|
|
|
/*
|
|
|
|
Kopete Oscar Protocol
|
|
|
|
ssimodifytask.cpp - Handles all the ssi modification stuff
|
|
|
|
|
|
|
|
Copyright (c) 2004 by Kopete Developers <kopete-devel@kde.org>
|
|
|
|
|
|
|
|
Based on code Copyright (c) 2004 SuSE Linux AG <http://www.suse.com>
|
|
|
|
Based on Iris, Copyright (C) 2003 Justin Karneges
|
|
|
|
|
|
|
|
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 "ssimodifytask.h"
|
|
|
|
|
|
|
|
#include <kdebug.h>
|
|
|
|
#include <tdelocale.h>
|
|
|
|
#include <tqstring.h>
|
|
|
|
#include "connection.h"
|
|
|
|
#include "oscarutils.h"
|
|
|
|
#include "transfer.h"
|
|
|
|
|
|
|
|
|
|
|
|
SSIModifyTask::SSIModifyTask( Task* parent, bool staticTask ) : Task( parent )
|
|
|
|
{
|
|
|
|
m_ssiManager = parent->client()->ssiManager();
|
|
|
|
m_static = staticTask;
|
|
|
|
m_opType = NoType;
|
|
|
|
m_opSubject = NoSubject;
|
|
|
|
m_id = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
SSIModifyTask::~SSIModifyTask()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void SSIModifyTask::onGo()
|
|
|
|
{
|
|
|
|
sendSSIUpdate();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SSIModifyTask::take( Transfer* transfer )
|
|
|
|
{
|
|
|
|
if ( forMe( transfer ) )
|
|
|
|
{
|
|
|
|
SnacTransfer* st = dynamic_cast<SnacTransfer*>( transfer );
|
|
|
|
if ( st )
|
|
|
|
{
|
|
|
|
setTransfer( transfer );
|
|
|
|
|
|
|
|
if ( st->snacSubtype() == 0x0008 )
|
|
|
|
handleSSIAdd();
|
|
|
|
else if ( st->snacSubtype() == 0x0009 )
|
|
|
|
handleSSIUpdate();
|
|
|
|
else if ( st->snacSubtype() == 0x000A )
|
|
|
|
handleSSIRemove();
|
|
|
|
else if ( st->snacSubtype() == 0x000E )
|
|
|
|
handleSSIAck();
|
|
|
|
|
|
|
|
setTransfer( 0 );
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SSIModifyTask::addContact( const TQString& contact, const TQString& group, bool requiresAuth )
|
|
|
|
{
|
|
|
|
m_opType = Add;
|
|
|
|
m_opSubject = Contact;
|
|
|
|
|
|
|
|
TQString newContact = Oscar::normalize( contact );
|
|
|
|
|
|
|
|
Oscar::SSI oldItem = m_ssiManager->findContact( newContact );
|
|
|
|
Oscar::SSI groupItem = m_ssiManager->findGroup( group );
|
|
|
|
|
|
|
|
if ( !groupItem )
|
|
|
|
{
|
|
|
|
kdDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "group " << group << " does not exist on SSI. Aborting" << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//create new SSI item and populate the TLV list
|
|
|
|
TQValueList<TLV> tlvList;
|
|
|
|
if ( requiresAuth )
|
|
|
|
{
|
|
|
|
kdDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "This contact requires auth. adding appropriate tlv" << endl;
|
|
|
|
TLV t( 0x0066, 0, 0 );
|
|
|
|
tlvList.append( t );
|
|
|
|
}
|
|
|
|
|
|
|
|
kdDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "creating new SSI item for " << contact << " in group " << group << endl;
|
|
|
|
Oscar::SSI newItem( newContact, groupItem.gid(), m_ssiManager->nextContactId(), ROSTER_CONTACT, tlvList );
|
|
|
|
m_newItem = newItem;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SSIModifyTask::removeContact( const TQString& contact )
|
|
|
|
{
|
|
|
|
m_opType = Remove;
|
|
|
|
m_opSubject = Contact;
|
|
|
|
m_oldItem = m_ssiManager->findContact( Oscar::normalize( contact ) );
|
|
|
|
kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Scheduling" << m_oldItem.name() << " for removal" << endl;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SSIModifyTask::changeGroup( const TQString& contact, const TQString& newGroup )
|
|
|
|
{
|
|
|
|
m_opType = Change;
|
|
|
|
m_opSubject = Group;
|
|
|
|
m_oldItem = m_ssiManager->findContact( Oscar::normalize( contact ) );
|
|
|
|
Oscar::SSI oldGroupItem;
|
|
|
|
if ( m_oldItem.isValid() )
|
|
|
|
oldGroupItem = m_ssiManager->findGroup( newGroup );
|
|
|
|
else
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if ( m_oldItem.gid() == oldGroupItem.gid() )
|
|
|
|
{ //buddy already exists in this group
|
|
|
|
kdDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "contact " << contact << " already exists in group " << oldGroupItem.name() << ". Aborting." << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_groupItem = m_ssiManager->findGroup( newGroup );
|
|
|
|
if ( !m_groupItem )
|
|
|
|
{ //couldn't find group
|
|
|
|
kdDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "new group " << newGroup << " not found in SSI. Aborting" << endl;
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
//create a new SSI item for the buddy in the new group
|
|
|
|
Oscar::SSI newItem( m_oldItem.name(), m_groupItem.gid(), m_oldItem.bid(), ROSTER_CONTACT, m_oldItem.tlvList() );
|
|
|
|
m_newItem = newItem;
|
|
|
|
kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Moving '" << m_oldItem.name() << "' to group " << m_groupItem.name() << endl;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SSIModifyTask::addGroup( const TQString& groupName )
|
|
|
|
{
|
|
|
|
m_opType = Add;
|
|
|
|
m_opSubject = Group;
|
|
|
|
m_newItem = m_ssiManager->findGroup( groupName );
|
|
|
|
TQValueList<TLV> dummy;
|
|
|
|
Oscar::SSI newItem( groupName, m_ssiManager->nextGroupId(), 0, ROSTER_GROUP, dummy );
|
|
|
|
m_newItem = newItem;
|
|
|
|
kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Adding group '" << m_newItem.name() << "' to SSI" << endl;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SSIModifyTask::removeGroup( const TQString& groupName )
|
|
|
|
{
|
|
|
|
m_opType = Remove;
|
|
|
|
m_opSubject = Group;
|
|
|
|
m_oldItem = m_ssiManager->findGroup( groupName );
|
|
|
|
kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Scheduling group '" << m_oldItem.name() << "' for removal. " << endl;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SSIModifyTask::renameGroup( const TQString& oldName, const TQString & newName )
|
|
|
|
{
|
|
|
|
m_opType = Rename;
|
|
|
|
m_opSubject = Group;
|
|
|
|
if ( oldName == newName )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
m_oldItem = m_ssiManager->findGroup( oldName );
|
|
|
|
Oscar::SSI newItem( newName, m_oldItem.gid(), m_oldItem.bid(), ROSTER_GROUP, m_oldItem.tlvList() );
|
|
|
|
m_newItem = newItem;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SSIModifyTask::addItem( const Oscar::SSI& item )
|
|
|
|
{
|
|
|
|
m_opType = Add;
|
|
|
|
m_opSubject = NoSubject;
|
|
|
|
m_newItem = item;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SSIModifyTask::removeItem( const Oscar::SSI& item )
|
|
|
|
{
|
|
|
|
m_opType = Remove;
|
|
|
|
m_opSubject = NoSubject;
|
|
|
|
m_oldItem = item;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SSIModifyTask::modifyItem( const Oscar::SSI& oldItem, const Oscar::SSI& newItem )
|
|
|
|
{
|
|
|
|
if ( !m_ssiManager->hasItem( oldItem ) )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
//make sure there are some common things between the two items
|
|
|
|
if ( oldItem.type() != newItem.type() )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
m_oldItem = oldItem;
|
|
|
|
m_newItem = newItem;
|
|
|
|
m_opType = Change;
|
|
|
|
m_opSubject = NoSubject;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool SSIModifyTask::forMe( const Transfer * transfer ) const
|
|
|
|
{
|
|
|
|
const SnacTransfer* st = dynamic_cast<const SnacTransfer*>( transfer );
|
|
|
|
if ( !st )
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if ( st->snacService() == 0x0013 )
|
|
|
|
{
|
|
|
|
WORD subtype = st->snacSubtype();
|
|
|
|
if ( m_static )
|
|
|
|
{
|
|
|
|
if ( subtype == 0x0008 || subtype == 0x0009 || subtype == 0x000A )
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ( subtype == 0x000E && m_id == st->snac().id )
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void SSIModifyTask::handleSSIAck()
|
|
|
|
{
|
|
|
|
Buffer* b = transfer()->buffer();
|
|
|
|
int numItems = b->length() / 2;
|
|
|
|
for( int i = 0; i < numItems; ++i )
|
|
|
|
{
|
|
|
|
WORD ackCode = b->getWord();
|
|
|
|
kdDebug(OSCAR_RAW_DEBUG) << "Acknowledgement code is " << ackCode << endl;
|
|
|
|
|
|
|
|
if ( ackCode != 0x0000 )
|
|
|
|
freeIdOnError();
|
|
|
|
|
|
|
|
switch( ackCode )
|
|
|
|
{
|
|
|
|
case 0x0000:
|
|
|
|
kdDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "SSI Update successful" << endl;
|
|
|
|
updateSSIManager();
|
|
|
|
break;
|
|
|
|
case 0x0002:
|
|
|
|
kdDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Item to modify not found in list" << endl;
|
|
|
|
setSuccess( 0, TQString() );
|
|
|
|
break;
|
|
|
|
case 0x0003:
|
|
|
|
kdDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Item already exists in SSI" << endl;
|
|
|
|
setSuccess( 0, TQString() );
|
|
|
|
break;
|
|
|
|
case 0x000A:
|
|
|
|
kdDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Error adding item ( invalid id, already in list, invalid data )" << endl;
|
|
|
|
setSuccess( 0, TQString() );
|
|
|
|
break;
|
|
|
|
case 0x000C:
|
|
|
|
kdDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Can't add item. Limit exceeded." << endl;
|
|
|
|
setSuccess( 0, TQString() );
|
|
|
|
break;
|
|
|
|
case 0x000D:
|
|
|
|
kdDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Can't add ICQ item to AIM list ( and vice versa )" << endl;
|
|
|
|
setSuccess( 0, TQString() );
|
|
|
|
break;
|
|
|
|
case 0x000E:
|
|
|
|
{
|
|
|
|
kdDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Can't add item because contact requires authorization" << endl;
|
|
|
|
Oscar::SSI groupItem = m_ssiManager->findGroup( m_newItem.gid() );
|
|
|
|
TQString groupName = groupItem.name();
|
|
|
|
addContact( m_newItem.name(), groupName, true );
|
|
|
|
go();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
kdDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Unknown acknowledgement code" << endl;
|
|
|
|
setSuccess( 0, TQString() );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void SSIModifyTask::sendSSIUpdate()
|
|
|
|
{
|
|
|
|
//what type of update are we sending?
|
|
|
|
if ( m_opSubject == Group && m_opType == Change )
|
|
|
|
changeGroupOnServer();
|
|
|
|
|
|
|
|
//add an item to the ssi list
|
|
|
|
if ( m_opType == Add )
|
|
|
|
{
|
|
|
|
kdDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Adding an item to the SSI list" << endl;
|
|
|
|
sendEditStart();
|
|
|
|
|
|
|
|
//add the item
|
|
|
|
FLAP f1 = { 0x02, 0, 0 };
|
|
|
|
m_id = client()->snacSequence();
|
|
|
|
SNAC s1 = { 0x0013, 0x0008, 0x0000, m_id };
|
|
|
|
Buffer* ssiBuffer = new Buffer;
|
|
|
|
ssiBuffer->addString( m_newItem );
|
|
|
|
Transfer* t2 = createTransfer( f1, s1, ssiBuffer );
|
|
|
|
send( t2 );
|
|
|
|
|
|
|
|
sendEditEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
//remove an item
|
|
|
|
if ( m_opType == Remove )
|
|
|
|
{
|
|
|
|
kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Removing " << m_oldItem.name() << " from SSI" << endl;
|
|
|
|
sendEditStart();
|
|
|
|
|
|
|
|
//remove the item
|
|
|
|
FLAP f1 = { 0x02, 0, 0 };
|
|
|
|
m_id = client()->snacSequence();
|
|
|
|
SNAC s1 = { 0x0013, 0x000A, 0x0000, m_id };
|
|
|
|
Buffer* ssiBuffer = new Buffer;
|
|
|
|
ssiBuffer->addString( m_oldItem );
|
|
|
|
Transfer* t2 = createTransfer( f1, s1, ssiBuffer );
|
|
|
|
send( t2 );
|
|
|
|
|
|
|
|
sendEditEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
//modify an item
|
|
|
|
//we use rename for group and change for other items
|
|
|
|
if ( m_opType == Rename || ( m_opType == Change && m_opSubject != Group ) )
|
|
|
|
{
|
|
|
|
kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Modifying the item: " << m_oldItem.toString() << endl;
|
|
|
|
kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "changing it to: " << m_newItem.toString() << endl;
|
|
|
|
sendEditStart();
|
|
|
|
|
|
|
|
//change the group name
|
|
|
|
FLAP f1 = { 0x02, 0, 0 };
|
|
|
|
m_id = client()->snacSequence();
|
|
|
|
SNAC s1 = { 0x0013, 0x0009, 0x0000, m_id };
|
|
|
|
Buffer* ssiBuffer = new Buffer;
|
|
|
|
ssiBuffer->addString( m_newItem );
|
|
|
|
Transfer* t2 = createTransfer( f1, s1, ssiBuffer );
|
|
|
|
send( t2 );
|
|
|
|
|
|
|
|
sendEditEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void SSIModifyTask::changeGroupOnServer()
|
|
|
|
{
|
|
|
|
kdDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Moving a contact from one group to another" << endl;
|
|
|
|
|
|
|
|
sendEditStart();
|
|
|
|
|
|
|
|
//remove the old buddy from the list
|
|
|
|
FLAP f1 = { 0x02, 0, 0 };
|
|
|
|
SNAC s1 = { 0x0013, 0x000A, 0x0000, client()->snacSequence() };
|
|
|
|
Buffer* b1 = new Buffer;
|
|
|
|
b1->addBSTR( m_oldItem.name().latin1() );
|
|
|
|
b1->addWord( m_oldItem.gid() );
|
|
|
|
b1->addWord( m_oldItem.bid() );
|
|
|
|
b1->addWord( m_oldItem.type() );
|
|
|
|
b1->addWord( 0 );
|
|
|
|
Transfer* t2 = createTransfer( f1, s1, b1 );
|
|
|
|
send( t2 );
|
|
|
|
|
|
|
|
//add the buddy to the list with a different group
|
|
|
|
FLAP f2 = { 0x02, 0, 0 };
|
|
|
|
m_id = client()->snacSequence(); //we don't care about the first ack
|
|
|
|
SNAC s2 = { 0x0013, 0x0008, 0x0000, m_id };
|
|
|
|
Buffer* b2 = new Buffer;
|
|
|
|
addItemToBuffer( m_newItem, b2 );
|
|
|
|
|
|
|
|
Transfer* t3 = createTransfer( f2, s2, b2 );
|
|
|
|
send( t3 );
|
|
|
|
|
|
|
|
//find the old group so we can change it's list of buddy ids
|
|
|
|
//what a kludge
|
|
|
|
Oscar::SSI oldGroupItem = m_ssiManager->findGroup( m_oldItem.gid() );
|
|
|
|
/* not checking the existance of oldGroupItem because if we got here
|
|
|
|
it has to exist */
|
|
|
|
|
|
|
|
//Change the 0x00C8 TLV in the old group item to remove the bid we're
|
|
|
|
//moving to a different group
|
|
|
|
TQValueList<TLV> list = oldGroupItem.tlvList();
|
|
|
|
TLV oldIds = Oscar::findTLV( list, 0x00C8 );
|
|
|
|
if ( oldIds.type == 0x00C8 )
|
|
|
|
{
|
|
|
|
Buffer newTLVData;
|
|
|
|
Buffer tlvBuffer( oldIds.data, oldIds.length );
|
|
|
|
while ( tlvBuffer.length() != 0 )
|
|
|
|
{
|
|
|
|
WORD id = tlvBuffer.getWord();
|
|
|
|
if ( id != m_oldItem.bid() )
|
|
|
|
newTLVData.addWord( id );
|
|
|
|
}
|
|
|
|
|
|
|
|
TLV newGroupTLV( 0x00C8, newTLVData.length(), newTLVData.buffer() );
|
|
|
|
|
|
|
|
list.remove( oldIds );
|
|
|
|
list.append( newGroupTLV );
|
|
|
|
oldGroupItem.setTLVList( list );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//Change the 0x00C8 TLV in the new group item to add the bid we're
|
|
|
|
//adding to this group
|
|
|
|
TQValueList<TLV> list2 = m_groupItem.tlvList();
|
|
|
|
TLV oldIds2 = Oscar::findTLV( list2, 0x00C8 );
|
|
|
|
TLV newGroupTLV;
|
|
|
|
if ( oldIds2.type == 0x00C8 )
|
|
|
|
{
|
|
|
|
Buffer tlvBuffer( oldIds2.data, oldIds2.length );
|
|
|
|
tlvBuffer.addWord( m_newItem.bid() );
|
|
|
|
|
|
|
|
TLV newGroupTLV( 0x00C8, tlvBuffer.length(), tlvBuffer.buffer() );
|
|
|
|
list2.remove( oldIds );
|
|
|
|
list2.append( newGroupTLV );
|
|
|
|
m_groupItem.setTLVList( list2 );
|
|
|
|
}
|
|
|
|
|
|
|
|
//change the group properties
|
|
|
|
FLAP f3 = { 0x02, 0, 0 };
|
|
|
|
SNAC s3 = { 0x0013, 0x0009, 0x0000, client()->snacSequence() };
|
|
|
|
Buffer* b3 = new Buffer;
|
|
|
|
addItemToBuffer( oldGroupItem, b3 );
|
|
|
|
addItemToBuffer( m_groupItem, b3 );
|
|
|
|
|
|
|
|
Transfer* t4 = createTransfer( f3, s3, b3 ); //we get no ack from this packet
|
|
|
|
send( t4 );
|
|
|
|
|
|
|
|
sendEditEnd();
|
|
|
|
}
|
|
|
|
|
|
|
|
void SSIModifyTask::updateSSIManager()
|
|
|
|
{
|
|
|
|
if ( m_oldItem.isValid() && m_newItem.isValid() )
|
|
|
|
{
|
|
|
|
if ( m_opSubject == Contact )
|
|
|
|
{
|
|
|
|
kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Removing " << m_oldItem.name() << endl;
|
|
|
|
m_ssiManager->removeContact( m_oldItem.name() );
|
|
|
|
kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "and adding " << m_newItem.name() << " to SSI manager" << endl;
|
|
|
|
m_ssiManager->newContact( m_newItem );
|
|
|
|
}
|
|
|
|
else if ( m_opSubject == Group )
|
|
|
|
{
|
|
|
|
if ( m_opType == Rename )
|
|
|
|
m_ssiManager->updateGroup( m_newItem );
|
|
|
|
else if ( m_opType == Change )
|
|
|
|
m_ssiManager->updateContact( m_newItem );
|
|
|
|
}
|
|
|
|
else if ( m_opSubject == NoSubject )
|
|
|
|
{
|
|
|
|
kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Removing " << m_oldItem.name() << endl;
|
|
|
|
m_ssiManager->removeItem( m_oldItem );
|
|
|
|
kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "and adding " << m_newItem.name() << " to SSI manager" << endl;
|
|
|
|
m_ssiManager->newItem( m_newItem );
|
|
|
|
}
|
|
|
|
setSuccess( 0, TQString() );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( m_oldItem.isValid() && !m_newItem )
|
|
|
|
{
|
|
|
|
kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Removing " << m_oldItem.name() << " from SSI manager" << endl;
|
|
|
|
if ( m_opSubject == Group )
|
|
|
|
m_ssiManager->removeGroup( m_oldItem.name() );
|
|
|
|
else if ( m_opSubject == Contact )
|
|
|
|
m_ssiManager->removeContact( m_oldItem.name() );
|
|
|
|
else if ( m_opSubject == NoSubject )
|
|
|
|
m_ssiManager->removeItem( m_oldItem );
|
|
|
|
setSuccess( 0, TQString() );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( m_newItem.isValid() && !m_oldItem )
|
|
|
|
{
|
|
|
|
kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Adding " << m_newItem.name() << " to SSI manager" << endl;
|
|
|
|
if ( m_opSubject == Group )
|
|
|
|
m_ssiManager->newGroup( m_newItem );
|
|
|
|
else if ( m_opSubject == Contact )
|
|
|
|
m_ssiManager->newContact( m_newItem );
|
|
|
|
else if ( m_opSubject == NoSubject )
|
|
|
|
m_ssiManager->newItem( m_newItem );
|
|
|
|
setSuccess( 0, TQString() );
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
setSuccess( 0, TQString() );
|
|
|
|
}
|
|
|
|
|
|
|
|
void SSIModifyTask::freeIdOnError()
|
|
|
|
{
|
|
|
|
if ( m_oldItem.isValid() && m_newItem.isValid() )
|
|
|
|
{
|
|
|
|
if ( m_opSubject == Contact || m_opSubject == NoSubject )
|
|
|
|
{
|
|
|
|
if ( m_oldItem.bid() != m_newItem.bid() )
|
|
|
|
m_ssiManager->removeID( m_newItem );
|
|
|
|
}
|
|
|
|
else if ( m_opSubject == Group )
|
|
|
|
{
|
|
|
|
if ( m_oldItem.gid() != m_newItem.gid() )
|
|
|
|
m_ssiManager->removeID( m_newItem );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( m_newItem.isValid() && !m_oldItem )
|
|
|
|
{
|
|
|
|
if ( m_opSubject == Group || m_opSubject == Contact ||
|
|
|
|
m_opSubject == NoSubject )
|
|
|
|
{
|
|
|
|
m_ssiManager->removeID( m_newItem );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SSIModifyTask::sendEditStart()
|
|
|
|
{
|
|
|
|
SNAC editStartSnac = { 0x0013, 0x0011, 0x0000, client()->snacSequence() };
|
|
|
|
FLAP editStart = { 0x02, 0, 10 };
|
|
|
|
Buffer* emptyBuffer = new Buffer;
|
|
|
|
Transfer* t1 = createTransfer( editStart, editStartSnac, emptyBuffer );
|
|
|
|
send( t1 );
|
|
|
|
}
|
|
|
|
|
|
|
|
void SSIModifyTask::sendEditEnd()
|
|
|
|
{
|
|
|
|
SNAC editEndSnac = { 0x0013, 0x0012, 0x0000, client()->snacSequence() };
|
|
|
|
FLAP editEnd = { 0x02, 0, 10 } ;
|
|
|
|
Buffer* emptyBuffer = new Buffer;
|
|
|
|
Transfer *t5 = createTransfer( editEnd, editEndSnac, emptyBuffer );
|
|
|
|
send( t5 );
|
|
|
|
}
|
|
|
|
|
|
|
|
void SSIModifyTask::addItemToBuffer( Oscar::SSI item, Buffer* buffer )
|
|
|
|
{
|
|
|
|
buffer->addBSTR( item.name().latin1() );
|
|
|
|
buffer->addWord( item.gid() );
|
|
|
|
buffer->addWord( item.bid() );
|
|
|
|
buffer->addWord( item.type() );
|
|
|
|
buffer->addWord( item.tlvListLength() );
|
|
|
|
|
|
|
|
TQValueList<TLV>::const_iterator it = item.tlvList().begin();
|
|
|
|
TQValueList<TLV>::const_iterator listEnd = item.tlvList().end();
|
|
|
|
for( ; it != listEnd; ++it )
|
|
|
|
buffer->addTLV( ( *it ) );
|
|
|
|
}
|
|
|
|
|
|
|
|
Oscar::SSI SSIModifyTask::getItemFromBuffer( Buffer* buffer ) const
|
|
|
|
{
|
|
|
|
TQValueList<TLV> tlvList;
|
|
|
|
|
|
|
|
WORD strlength = buffer->getWord();
|
|
|
|
TQString itemName = TQString::fromUtf8( buffer->getBlock( strlength ), strlength );
|
|
|
|
WORD groupId = buffer->getWord();
|
|
|
|
WORD itemId = buffer->getWord();
|
|
|
|
WORD itemType = buffer->getWord();
|
|
|
|
WORD tlvLength = buffer->getWord();
|
|
|
|
for ( int i = 0; i < tlvLength; )
|
|
|
|
{
|
|
|
|
TLV t = buffer->getTLV();
|
|
|
|
i += 4;
|
|
|
|
i += t.length;
|
|
|
|
tlvList.append( t );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( itemType == ROSTER_CONTACT )
|
|
|
|
itemName = Oscar::normalize( itemName );
|
|
|
|
|
|
|
|
return Oscar::SSI( itemName, groupId, itemId, itemType, tlvList );
|
|
|
|
}
|
|
|
|
|
|
|
|
void SSIModifyTask::handleSSIAdd()
|
|
|
|
{
|
|
|
|
Buffer* b = transfer()->buffer();
|
|
|
|
|
|
|
|
while ( b->length() > 0 )
|
|
|
|
{
|
|
|
|
Oscar::SSI item = getItemFromBuffer( b );
|
|
|
|
kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Adding " << item.name() << " to SSI manager" << endl;
|
|
|
|
|
|
|
|
if ( item.type() == ROSTER_GROUP )
|
|
|
|
m_ssiManager->newGroup( item );
|
|
|
|
else if ( item.type() == ROSTER_CONTACT )
|
|
|
|
m_ssiManager->newContact( item );
|
|
|
|
else
|
|
|
|
m_ssiManager->newItem( item );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SSIModifyTask::handleSSIUpdate()
|
|
|
|
{
|
|
|
|
Buffer* b = transfer()->buffer();
|
|
|
|
|
|
|
|
while ( b->length() > 0 )
|
|
|
|
{
|
|
|
|
Oscar::SSI item = getItemFromBuffer( b );
|
|
|
|
kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Updating " << item.name() << " in SSI manager" << endl;
|
|
|
|
|
|
|
|
if ( item.type() == ROSTER_GROUP )
|
|
|
|
m_ssiManager->updateGroup( item );
|
|
|
|
else if ( item.type() == ROSTER_CONTACT )
|
|
|
|
m_ssiManager->updateContact( item );
|
|
|
|
else
|
|
|
|
m_ssiManager->updateItem( item );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void SSIModifyTask::handleSSIRemove()
|
|
|
|
{
|
|
|
|
Buffer* b = transfer()->buffer();
|
|
|
|
|
|
|
|
while ( b->length() > 0 )
|
|
|
|
{
|
|
|
|
Oscar::SSI item = getItemFromBuffer( b );
|
|
|
|
kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Removing " << item.name() << " from SSI manager" << endl;
|
|
|
|
|
|
|
|
if ( item.type() == ROSTER_GROUP )
|
|
|
|
m_ssiManager->removeGroup( item );
|
|
|
|
else if ( item.type() == ROSTER_CONTACT )
|
|
|
|
m_ssiManager->removeContact( item );
|
|
|
|
else
|
|
|
|
m_ssiManager->removeItem( item );
|
|
|
|
}
|
|
|
|
}
|