summaryrefslogtreecommitdiffstats
path: root/kopete/libkopete/kopetegroup.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kopete/libkopete/kopetegroup.cpp')
-rw-r--r--kopete/libkopete/kopetegroup.cpp335
1 files changed, 335 insertions, 0 deletions
diff --git a/kopete/libkopete/kopetegroup.cpp b/kopete/libkopete/kopetegroup.cpp
new file mode 100644
index 00000000..f50eb08b
--- /dev/null
+++ b/kopete/libkopete/kopetegroup.cpp
@@ -0,0 +1,335 @@
+/*
+ kopetegroup.cpp - Kopete (Meta)Contact Group
+
+ Copyright (c) 2002-2004 by Olivier Goffart <ogoffart@ tiscalinet.be>
+ Copyright (c) 2003 by Martijn Klingens <[email protected]>
+
+ Kopete (c) 2002-2004 by the Kopete developers <[email protected]>
+
+ *************************************************************************
+ * *
+ * This library is free software; you can redistribute it and/or *
+ * modify it under the terms of the GNU Lesser General Public *
+ * License as published by the Free Software Foundation; either *
+ * version 2 of the License, or (at your option) any later version. *
+ * *
+ *************************************************************************
+*/
+
+#include "kopetegroup.h"
+
+#include "kopetecontactlist.h"
+#include "kopetemetacontact.h"
+#include "kopetecontact.h"
+#include "kopetechatsession.h"
+
+#include <klocale.h>
+
+namespace Kopete {
+
+class Group::Private
+{
+public:
+ QString displayName;
+ Group::GroupType type;
+ bool expanded;
+ uint groupId;
+
+ //Unique contact id per metacontact
+ static uint uniqueGroupId;
+};
+
+Group *Group::s_topLevel = 0L;
+Group *Group::s_temporary = 0L;
+Group * Group::topLevel()
+{
+ if ( !s_topLevel )
+ s_topLevel = new Group( i18n( "Top Level" ), Group::TopLevel );
+
+ return s_topLevel;
+}
+
+Group * Group::temporary()
+{
+ if ( !s_temporary )
+ s_temporary = new Group( i18n( "Not in your contact list" ), Group::Temporary );
+
+ return s_temporary;
+}
+
+uint Group::Private::uniqueGroupId = 0;
+
+Group::Group( const QString &_name, GroupType _type )
+ : ContactListElement( ContactList::self() )
+{
+ d = new Private;
+ d->displayName = _name;
+ d->type = _type;
+ d->expanded = true;
+ d->groupId = 0;
+}
+
+Group::Group()
+ : ContactListElement( ContactList::self() )
+{
+ d = new Private;
+ d->expanded = true;
+ d->type = Normal;
+ d->groupId = 0;
+}
+
+Group::~Group()
+{
+ if(d->type == TopLevel)
+ s_topLevel=0L;
+ if(d->type == Temporary)
+ s_temporary=0L;
+ delete d;
+}
+
+QPtrList<MetaContact> Group::members() const
+{
+ QPtrList<MetaContact> members = ContactList::self()->metaContacts();
+ // members is a *copy* of the meta contacts, so using first(), next() and remove() is fine.
+ for( members.first(); members.current(); )
+ {
+ if ( members.current()->groups().contains( this ) )
+ members.next();
+ else
+ members.remove();
+ }
+ return members;
+}
+
+const QDomElement Group::toXML()
+{
+ QDomDocument group;
+ group.appendChild( group.createElement( QString::fromLatin1( "kopete-group" ) ) );
+ group.documentElement().setAttribute( QString::fromLatin1( "groupId" ), QString::number( groupId() ) );
+
+ QString type;
+ switch ( d->type )
+ {
+ case Temporary:
+ type = QString::fromLatin1( "temporary" );
+ break;
+ case TopLevel:
+ type = QString::fromLatin1( "top-level" );
+ break;
+ default:
+ type = QString::fromLatin1( "standard" ); // == Normal
+ break;
+ }
+
+ group.documentElement().setAttribute( QString::fromLatin1( "type" ), type );
+ group.documentElement().setAttribute( QString::fromLatin1( "view" ), QString::fromLatin1( d->expanded ? "expanded" : "collapsed" ) );
+
+ QDomElement displayName = group.createElement( QString::fromLatin1( "display-name" ) );
+ displayName.appendChild( group.createTextNode( d->displayName ) );
+ group.documentElement().appendChild( displayName );
+
+ // Store other plugin data
+ QValueList<QDomElement> pluginData = ContactListElement::toXML();
+ for ( QValueList<QDomElement>::Iterator it = pluginData.begin(); it != pluginData.end(); ++it )
+ group.documentElement().appendChild( group.importNode( *it, true ) );
+
+ // Store custom notification data
+ QDomElement notifyData = Kopete::NotifyDataObject::notifyDataToXML();
+ if ( notifyData.hasChildNodes() )
+ group.documentElement().appendChild( group.importNode( notifyData, true ) );
+
+ return group.documentElement();
+}
+
+bool Group::fromXML( const QDomElement &data )
+{
+ QString strGroupId = data.attribute( QString::fromLatin1( "groupId" ) );
+ if ( !strGroupId.isEmpty() )
+ {
+ d->groupId = strGroupId.toUInt();
+ if ( d->groupId > d->uniqueGroupId )
+ d->uniqueGroupId = d->groupId;
+ }
+
+ // Don't overwrite type for Temporary and TopLevel groups
+ if ( d->type != Temporary && d->type != TopLevel )
+ {
+ QString type = data.attribute( QString::fromLatin1( "type" ), QString::fromLatin1( "standard" ) );
+ if ( type == QString::fromLatin1( "temporary" ) )
+ {
+ if ( d->type != Temporary )
+ {
+ s_temporary->fromXML( data );
+ return false;
+ }
+ }
+ else if ( type == QString::fromLatin1( "top-level" ) )
+ {
+ if ( d->type != TopLevel )
+ {
+ s_topLevel->fromXML( data );
+ return false;
+ }
+ }
+ else
+ {
+ d->type = Normal;
+ }
+ }
+
+ QString view = data.attribute( QString::fromLatin1( "view" ), QString::fromLatin1( "expanded" ) );
+ d->expanded = ( view != QString::fromLatin1( "collapsed" ) );
+
+ QDomNode groupData = data.firstChild();
+ while ( !groupData.isNull() )
+ {
+ QDomElement groupElement = groupData.toElement();
+ if ( groupElement.tagName() == QString::fromLatin1( "display-name" ) )
+ {
+ // Don't set display name for temporary or top-level items
+ if ( d->type == Normal )
+ d->displayName = groupElement.text();
+ }
+ else if( groupElement.tagName() == QString::fromLatin1( "custom-notifications" ) )
+ {
+ Kopete::NotifyDataObject::notifyDataFromXML( groupElement );
+ }
+ else
+ {
+ Kopete::ContactListElement::fromXML( groupElement );
+ }
+
+ groupData = groupData.nextSibling();
+ }
+
+ // Sanity checks. We must not have groups without a displayname.
+ if ( d->displayName.isEmpty() )
+ {
+ switch ( d->type )
+ {
+ case Temporary:
+ d->displayName = QString::fromLatin1( "Temporary" );
+ break;
+ case TopLevel:
+ d->displayName = QString::fromLatin1( "Top-Level" );
+ break;
+ default:
+ d->displayName = i18n( "(Unnamed Group)" );
+ break;
+ }
+ }
+
+ //this allows to save data for the top-level group in the top-level group
+ return ( d->type == Normal );
+}
+
+void Group::setDisplayName( const QString &s )
+{
+ if ( d->displayName != s )
+ {
+ QString oldname = d->displayName;
+ d->displayName = s;
+ emit displayNameChanged( this, oldname );
+ }
+}
+
+QString Group::displayName() const
+{
+ return d->displayName;
+}
+
+Group::GroupType Group::type() const
+{
+ return d->type;
+}
+
+void Group::setType( GroupType t )
+{
+ d->type = t;
+}
+
+void Group::setExpanded( bool isExpanded )
+{
+ d->expanded = isExpanded;
+}
+
+bool Group::isExpanded() const
+{
+ return d->expanded;
+}
+
+uint Group::groupId() const
+{
+ if ( d->groupId == 0 )
+ d->groupId = ++d->uniqueGroupId;
+
+ return d->groupId;
+}
+
+
+void Group::sendMessage()
+{
+ QPtrList<Kopete::MetaContact> list = onlineMembers();
+ Kopete::MetaContact *mc = list.first();
+ Kopete::Contact *c;
+
+ if(!mc)
+ return;
+ c = mc->preferredContact();
+ c->sendMessage();
+ if( c->manager( Contact::CanCreate ) )
+ {
+ connect( c->manager(), SIGNAL( messageSent( Kopete::Message&, Kopete::ChatSession* ) ), this, SLOT( sendMessage( Kopete::Message& ) ));
+ }
+}
+
+void Group::sendMessage( Message& msg )
+{
+ QPtrList<MetaContact> list = onlineMembers();
+ Kopete::MetaContact *mc = list.first();
+ ChatSession *cs=msg.manager();
+ if( cs )
+ {
+ disconnect( cs, SIGNAL( messageSent( Kopete::Message&, Kopete::ChatSession* ) ), this, SLOT( sendMessage( Kopete::Message& ) ) );
+ }
+ else
+ return;
+
+ if(!mc)
+ return;
+ list.remove( msg.to().first()->metaContact() );
+ for( mc = list.first(); mc; mc = list.next() )
+ {
+ if(mc->isReachable())
+ {
+ Contact *kcontact=mc->preferredContact();
+ if( kcontact->manager( Contact::CanCreate ) )
+ {
+ //This is hack and stupid. send message to group should never exist anyway - Olivier 2005-09-11
+ // changing the "to" is require, because jabber use it to send the messgae. Cf BUG 111514
+ Message msg2(cs->myself() , kcontact , msg.plainBody() , msg.direction() , Message::PlainText , msg.requestedPlugin() );
+ kcontact->manager( Contact::CanCreate )->sendMessage( msg2 );
+ }
+ }
+ }
+}
+
+QPtrList<MetaContact> Group::onlineMembers() const
+{
+ QPtrList<MetaContact> list = members();
+
+ for( list.first(); list.current(); )
+ if( list.current()->isReachable() && list.current()->isOnline() )
+ list.next();
+ else
+ list.remove();
+ return list;
+}
+
+} //END namespace Kopete
+
+
+#include "kopetegroup.moc"
+
+
+