You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdenetwork/kopete/libkopete/kopetegroup.cpp

336 lines
8.3 KiB

/*
kopetegroup.cpp - Kopete (Meta)Contact Group
Copyright (c) 2002-2004 by Olivier Goffart <ogoffart@ tiscalinet.be>
Copyright (c) 2003 by Martijn Klingens <klingens@kde.org>
Kopete (c) 2002-2004 by the Kopete developers <kopete-devel@kde.org>
*************************************************************************
* *
* 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:
TQString 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 TQString &_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;
}
TQPtrList<MetaContact> Group::members() const
{
TQPtrList<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 TQDomElement Group::toXML()
{
TQDomDocument group;
group.appendChild( group.createElement( TQString::tqfromLatin1( "kopete-group" ) ) );
group.documentElement().setAttribute( TQString::tqfromLatin1( "groupId" ), TQString::number( groupId() ) );
TQString type;
switch ( d->type )
{
case Temporary:
type = TQString::tqfromLatin1( "temporary" );
break;
case TopLevel:
type = TQString::tqfromLatin1( "top-level" );
break;
default:
type = TQString::tqfromLatin1( "standard" ); // == Normal
break;
}
group.documentElement().setAttribute( TQString::tqfromLatin1( "type" ), type );
group.documentElement().setAttribute( TQString::tqfromLatin1( "view" ), TQString::tqfromLatin1( d->expanded ? "expanded" : "collapsed" ) );
TQDomElement displayName = group.createElement( TQString::tqfromLatin1( "display-name" ) );
displayName.appendChild( group.createTextNode( d->displayName ) );
group.documentElement().appendChild( displayName );
// Store other plugin data
TQValueList<TQDomElement> pluginData = ContactListElement::toXML();
for ( TQValueList<TQDomElement>::Iterator it = pluginData.begin(); it != pluginData.end(); ++it )
group.documentElement().appendChild( group.importNode( *it, true ) );
// Store custom notification data
TQDomElement notifyData = Kopete::NotifyDataObject::notifyDataToXML();
if ( notifyData.hasChildNodes() )
group.documentElement().appendChild( group.importNode( notifyData, true ) );
return group.documentElement();
}
bool Group::fromXML( const TQDomElement &data )
{
TQString strGroupId = data.attribute( TQString::tqfromLatin1( "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 )
{
TQString type = data.attribute( TQString::tqfromLatin1( "type" ), TQString::tqfromLatin1( "standard" ) );
if ( type == TQString::tqfromLatin1( "temporary" ) )
{
if ( d->type != Temporary )
{
s_temporary->fromXML( data );
return false;
}
}
else if ( type == TQString::tqfromLatin1( "top-level" ) )
{
if ( d->type != TopLevel )
{
s_topLevel->fromXML( data );
return false;
}
}
else
{
d->type = Normal;
}
}
TQString view = data.attribute( TQString::tqfromLatin1( "view" ), TQString::tqfromLatin1( "expanded" ) );
d->expanded = ( view != TQString::tqfromLatin1( "collapsed" ) );
TQDomNode groupData = data.firstChild();
while ( !groupData.isNull() )
{
TQDomElement groupElement = groupData.toElement();
if ( groupElement.tagName() == TQString::tqfromLatin1( "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() == TQString::tqfromLatin1( "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 = TQString::tqfromLatin1( "Temporary" );
break;
case TopLevel:
d->displayName = TQString::tqfromLatin1( "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 TQString &s )
{
if ( d->displayName != s )
{
TQString oldname = d->displayName;
d->displayName = s;
emit displayNameChanged( this, oldname );
}
}
TQString 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()
{
TQPtrList<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(), TQT_SIGNAL( messageSent( Kopete::Message&, Kopete::ChatSession* ) ), this, TQT_SLOT( sendMessage( Kopete::Message& ) ));
}
}
void Group::sendMessage( Message& msg )
{
TQPtrList<MetaContact> list = onlineMembers();
Kopete::MetaContact *mc = list.first();
ChatSession *cs=msg.manager();
if( cs )
{
disconnect( cs, TQT_SIGNAL( messageSent( Kopete::Message&, Kopete::ChatSession* ) ), this, TQT_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 );
}
}
}
}
TQPtrList<MetaContact> Group::onlineMembers() const
{
TQPtrList<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"