Version: 0.12.1 (using KDE 3.5.2, Kubuntu Package 4:3.5.2-0ubuntu18.1 dapper) Compiler: Target: i486-linux-gnu OS: Linux (i686) release 2.6.15-26-386 The visible/invisible list for the ICQ protocol does not work. If you add/remove a user to/from the lists and click OK, he is still in the list! Same happens when you try it via right-click -> "Always visible for"/"Always invisible for"
Confirming the bug for Kopete 0.12.2 compiled from svn, KDE 3.5.4 on Gentoo. Though in my case it seems that the action works for some contacts and doesn't work for others. Also switching to another ICQ client (SIM in my case) and making changes in the lists there also correctly changes visible/invisible lists in Kopete.
Same problem on Gentoo, Qt: 3.3.6 KDE: 3.5.5 Kopete: 0.12.3
I can't reproduce it, can you provide more info? Does it work when you remove and add that contact to Kopete list again? Maybe you can send me one icq number that doesn't work so I can test it. Tobias: you are using Kopete 0.12.1 so you maybe suffering from bug 104243. Thanks
Doesn't work with ANY contact here. I can add the contact to my visible list using another IM (tried with SIM, in my case) and it will appear in visible list later in Kopete. I can remove that contact from the list in Kopete, but I can not add it back (and I can't add any other contact too). The same is true for the contacts initially added to my contacts list with Kopete - can't be added to the visible list.
After removing/adding contact it's start to work, and still working ..
Oleg: please run Kopete from console and tell me if you see there "No free id!" or "No free group id!" when you add somebody to in/visible list. Also console log of Kopete compiled with debug enabled would be helpful. Thanks.
Hm, seems that after some messing with the contact list (adding/removing contacts, setting visible/invisible statuses, etc) things start to work. Not sure what was the reason but I can't confirm initial bugreport right now. I'll check the log if the problem reappear.
Having same thing with Yahoo accounts.
I found this bug too, and it does seem to be related to how much space you have available to allocate users into one list or the other (visible or invisible). Right now, for example, I can have 1 contact in my visible list and 2 in my invisible list. If I try to add more, it doesn't work. If I remove one, then I can add another one, etc... If I log with Licq and add some contacts to both lists, then I log back with Kopete and I can remove them and add them back (the same or others, but not more than the number I added with Licq). I'm using KDE 3.5.6 and Kopete 12.3.
SVN commit 645234 by rjarosz: Update our local Server Side Info correctly. Fix authorization status in ICQ. Fix bug 133950: adding users to visible/invisible list does not work Please test it because I can't reproduce it. BUG: 133950 M +23 -1 liboscar/client.cpp M +0 -9 liboscar/ssiauthtask.cpp M +62 -27 liboscar/ssimanager.cpp M +3 -2 liboscar/ssimanager.h M +116 -12 liboscar/ssimodifytask.cpp M +12 -1 liboscar/ssimodifytask.h M +1 -1 oscarcontact.cpp --- branches/KDE/3.5/kdenetwork/kopete/protocols/oscar/liboscar/client.cpp #645233:645234 @@ -111,6 +111,7 @@ ICQUserInfoRequestTask* icqInfoTask; UserInfoTask* userInfoTask; TypingNotifyTask * typingNotifyTask; + SSIModifyTask* ssiModifyTask; //Managers SSIManager* ssiManager; ConnectionHandler connections; @@ -160,6 +161,7 @@ d->userInfoTask = 0L; d->stage = ClientPrivate::StageOne; d->typingNotifyTask = 0L; + d->ssiModifyTask = 0L; d->awayMsgRequestTimer = new QTimer(); d->codecProvider = &defaultCodecProvider; @@ -619,6 +621,7 @@ d->icqInfoTask = new ICQUserInfoRequestTask( c->rootTask() ); d->userInfoTask = new UserInfoTask( c->rootTask() ); d->typingNotifyTask = new TypingNotifyTask( c->rootTask() ); + d->ssiModifyTask = new SSIModifyTask( c->rootTask(), true ); connect( d->onlineNotifier, SIGNAL( userIsOnline( const QString&, const UserDetails& ) ), this, SIGNAL( receivedUserInfo( const QString&, const UserDetails& ) ) ); @@ -660,6 +663,8 @@ SSIModifyTask* ssimt = new SSIModifyTask( c->rootTask() ); if ( ssimt->removeGroup( groupName ) ) ssimt->go( true ); + else + delete ssimt; } void Client::addGroup( const QString& groupName ) @@ -672,6 +677,8 @@ SSIModifyTask* ssimt = new SSIModifyTask( c->rootTask() ); if ( ssimt->addGroup( groupName ) ) ssimt->go( true ); + else + delete ssimt; } void Client::addContact( const QString& contactName, const QString& groupName ) @@ -684,7 +691,8 @@ SSIModifyTask* ssimt = new SSIModifyTask( c->rootTask() ); if ( ssimt->addContact( contactName, groupName ) ) ssimt->go( true ); - + else + delete ssimt; } void Client::removeContact( const QString& contactName ) @@ -697,6 +705,8 @@ SSIModifyTask* ssimt = new SSIModifyTask( c->rootTask() ); if ( ssimt->removeContact( contactName ) ) ssimt->go( true ); + else + delete ssimt; } void Client::renameGroup( const QString & oldGroupName, const QString & newGroupName ) @@ -709,6 +719,8 @@ SSIModifyTask* ssimt = new SSIModifyTask( c->rootTask() ); if ( ssimt->renameGroup( oldGroupName, newGroupName ) ) ssimt->go( true ); + else + delete ssimt; } void Client::modifySSIItem( const Oscar::SSI& oldItem, const Oscar::SSI& newItem ) @@ -730,14 +742,20 @@ case 0: if ( ssimt->modifyItem( oldItem, newItem ) ) ssimt->go( true ); + else + delete ssimt; break; case 1: if ( ssimt->addItem( newItem ) ) ssimt->go( true ); + else + delete ssimt; break; case 2: if ( ssimt->removeItem( oldItem ) ) ssimt->go( true ); + else + delete ssimt; break; } } @@ -753,6 +771,8 @@ SSIModifyTask* ssimt = new SSIModifyTask( c->rootTask() ); if ( ssimt->changeGroup( contact, newGroupName ) ) ssimt->go( true ); + else + delete ssimt; } void Client::requestFullInfo( const QString& contactId ) @@ -1306,6 +1326,7 @@ delete d->icqInfoTask; delete d->userInfoTask; delete d->typingNotifyTask; + delete d->ssiModifyTask; d->errorTask = 0; d->onlineNotifier = 0; @@ -1315,6 +1336,7 @@ d->icqInfoTask = 0; d->userInfoTask = 0; d->typingNotifyTask = 0; + d->ssiModifyTask = 0; } bool Client::hasIconConnection( ) const --- branches/KDE/3.5/kdenetwork/kopete/protocols/oscar/liboscar/ssiauthtask.cpp #645233:645234 @@ -112,10 +112,6 @@ Transfer* t = createTransfer( f, s, buf ); send( t ); - - Oscar::SSI contact = m_manager->findContact( uin ); - if ( contact ) - contact.setWaitingAuth( true ); } void SSIAuthTask::sendAuthReply( const QString& uin, const QString& reason, bool auth ) @@ -175,11 +171,6 @@ kdDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Authorization request declined by " << uin << endl; kdDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Reason: " << reason << endl; - - Oscar::SSI sender = m_manager->findContact( uin ); - if ( sender ) - sender.setWaitingAuth( false ); - emit authReplied( uin, reason, accepted ); } --- branches/KDE/3.5/kdenetwork/kopete/protocols/oscar/liboscar/ssimanager.cpp #645233:645234 @@ -439,26 +439,27 @@ return false; } -bool SSIManager::updateGroup( const Oscar::SSI& oldGroup, const Oscar::SSI& newGroup ) +bool SSIManager::updateGroup( const Oscar::SSI& group ) { - removeID( oldGroup ); - if ( d->SSIList.remove( oldGroup ) == 0 ) + Oscar::SSI oldGroup = findGroup( group.name() ); + + if ( oldGroup.isValid() ) { - kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "No group were removed." << endl; - return false; + removeID( oldGroup ); + d->SSIList.remove( oldGroup ); } - - if ( d->SSIList.findIndex( newGroup ) != -1 ) + + if ( d->SSIList.findIndex( group ) != -1 ) { kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "New group is already in list." << endl; return false; } - - kdDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Updating group '" << newGroup.name() << "' in SSI list" << endl; - d->SSIList.append( newGroup ); - addID( newGroup ); - emit groupUpdated( newGroup ); - + + kdDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Updating group '" << group.name() << "' in SSI list" << endl; + d->SSIList.append( group ); + addID( group ); + emit groupUpdated( group ); + return true; } @@ -507,26 +508,27 @@ return true; } -bool SSIManager::updateContact( const Oscar::SSI& oldContact, const Oscar::SSI& newContact ) +bool SSIManager::updateContact( const Oscar::SSI& contact ) { - removeID( oldContact ); - if ( d->SSIList.remove( oldContact ) == 0 ) + Oscar::SSI oldContact = findContact( contact.name() ); + + if ( oldContact.isValid() ) { - kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "No contacts were removed." << endl; - return false; + removeID( oldContact ); + d->SSIList.remove( oldContact ); } - - if ( d->SSIList.findIndex( newContact ) != -1 ) + + if ( d->SSIList.findIndex( contact ) != -1 ) { kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "New contact is already in list." << endl; return false; } + + kdDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Updating contact '" << contact.name() << "' in SSI list" << endl; + addID( contact ); + d->SSIList.append( contact ); + emit contactUpdated( contact ); - kdDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Updating contact '" << newContact.name() << "' in SSI list" << endl; - addID( newContact ); - d->SSIList.append( newContact ); - emit contactUpdated( newContact ); - return true; } @@ -560,17 +562,50 @@ bool SSIManager::newItem( const Oscar::SSI& item ) { - //no error checking for now + if ( d->SSIList.findIndex( item ) != -1 ) + { + kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Item is already in list." << endl; + return false; + } + kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Adding item " << item.toString() << endl; d->SSIList.append( item ); addID( item ); return true; } +bool SSIManager::updateItem( const Oscar::SSI& item ) +{ + Oscar::SSI oldItem = findItem( item.name(), item.type() ); + + if ( oldItem.isValid() ) + { + removeID( oldItem ); + d->SSIList.remove( oldItem ); + } + + if ( d->SSIList.findIndex( item ) != -1 ) + { + kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "New item is already in list." << endl; + return false; + } + + kdDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Updating item in SSI list" << endl; + addID( item ); + d->SSIList.append( item ); + return true; +} + bool SSIManager::removeItem( const Oscar::SSI& item ) { - d->SSIList.remove( item ); + int remcount = d->SSIList.remove( item ); removeID( item ); + + if ( remcount == 0 ) + { + kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "No items were removed." << endl; + return false; + } return true; } --- branches/KDE/3.5/kdenetwork/kopete/protocols/oscar/liboscar/ssimanager.h #645233:645234 @@ -104,16 +104,17 @@ public slots: bool newGroup( const Oscar::SSI& group ); - bool updateGroup( const Oscar::SSI& oldGroup, const Oscar::SSI& newGroup ); + bool updateGroup( const Oscar::SSI& group ); bool removeGroup( const Oscar::SSI& group ); bool removeGroup( const QString& group ); bool newContact( const Oscar::SSI& contact ); - bool updateContact( const Oscar::SSI& oldContact, const Oscar::SSI& newContact ); + bool updateContact( const Oscar::SSI& contact ); bool removeContact( const Oscar::SSI& contact ); bool removeContact( const QString& contact ); bool newItem( const Oscar::SSI& item ); + bool updateItem( const Oscar::SSI& item ); bool removeItem( const Oscar::SSI& item ); void addID( const Oscar::SSI& item ); --- branches/KDE/3.5/kdenetwork/kopete/protocols/oscar/liboscar/ssimodifytask.cpp #645233:645234 @@ -28,9 +28,10 @@ #include "transfer.h" -SSIModifyTask::SSIModifyTask( Task* parent ) : Task( parent ) +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; @@ -50,9 +51,22 @@ { if ( forMe( transfer ) ) { - setTransfer( transfer ); - handleSSIAck(); - setTransfer( 0 ); + 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 @@ -201,11 +215,23 @@ 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; + } + } - if ( st->snacService() == 0x0013 && st->snacSubtype() == 0x000E && m_id == st->snac().id ) - return true; - else - return false; + return false; } void SSIModifyTask::handleSSIAck() @@ -429,9 +455,9 @@ else if ( m_opSubject == Group ) { if ( m_opType == Rename ) - m_ssiManager->updateGroup( m_oldItem, m_newItem ); + m_ssiManager->updateGroup( m_newItem ); else if ( m_opType == Change ) - m_ssiManager->updateContact( m_oldItem, m_newItem ); + m_ssiManager->updateContact( m_newItem ); } else if ( m_opSubject == NoSubject ) { @@ -443,7 +469,7 @@ setSuccess( 0, QString::null ); return; } - + if ( m_oldItem.isValid() && !m_newItem ) { kdDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Removing " << m_oldItem.name() << " from SSI manager" << endl; @@ -469,7 +495,7 @@ setSuccess( 0, QString::null ); return; } - + setSuccess( 0, QString::null ); } @@ -530,4 +556,82 @@ buffer->addTLV( ( *it ) ); } +Oscar::SSI SSIModifyTask::getItemFromBuffer( Buffer* buffer ) const +{ + QValueList<TLV> tlvList; + + WORD strlength = buffer->getWord(); + QString itemName = QString::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 ); + } +} + //kate: tab-width 4; indent-mode csands; --- branches/KDE/3.5/kdenetwork/kopete/protocols/oscar/liboscar/ssimodifytask.h #645233:645234 @@ -51,7 +51,7 @@ class SSIModifyTask : public Task { public: - SSIModifyTask(Task* parent); + SSIModifyTask( Task* parent, bool staticTask = false ); ~SSIModifyTask(); virtual void onGo(); @@ -128,7 +128,17 @@ void sendEditEnd(); void addItemToBuffer( Oscar::SSI item, Buffer* buffer ); + Oscar::SSI getItemFromBuffer( Buffer* buffer ) const; + //! Handle server request to add item + void handleSSIAdd(); + + //! Handle server request to update item + void handleSSIUpdate(); + + //! Handle server request to remove item + void handleSSIRemove(); + private: SSI m_oldItem; SSI m_newItem; @@ -137,6 +147,7 @@ OperationSubject m_opSubject; WORD m_id; SSIManager* m_ssiManager; + bool m_static; }; --- branches/KDE/3.5/kdenetwork/kopete/protocols/oscar/oscarcontact.cpp #645233:645234 @@ -142,7 +142,7 @@ if( !metaContact() || metaContact()->isTemporary() ) return; - if ( flags & Kopete::Contact::MovedBetweenGroup == Kopete::Contact::MovedBetweenGroup ) + if ( (flags & Kopete::Contact::MovedBetweenGroup) == Kopete::Contact::MovedBetweenGroup ) { kdDebug(OSCAR_GEN_DEBUG) << k_funcinfo << "Moving a contact between groups" << endl; SSIManager* ssiManager = mAccount->engine()->ssiManager();
SVN commit 645365 by rjarosz: Forwardport: Update our local Server Side Info correctly. Fix authorization status in ICQ. Fix bug 133950: adding users to visible/invisible list does not work Please test it because I can't reproduce it. CCBUG: 133950 M +23 -1 client.cpp M +62 -28 contactmanager.cpp M +3 -2 contactmanager.h M +0 -9 tasks/ssiauthtask.cpp M +113 -10 tasks/ssimodifytask.cpp M +14 -3 tasks/ssimodifytask.h --- trunk/KDE/kdenetwork/kopete/protocols/oscar/liboscar/client.cpp #645364:645365 @@ -117,6 +117,7 @@ ICQUserInfoRequestTask* icqInfoTask; UserInfoTask* userInfoTask; TypingNotifyTask * typingNotifyTask; + SSIModifyTask* ssiModifyTask; //Managers ContactManager* ssiManager; ConnectionHandler connections; @@ -174,6 +175,7 @@ d->userInfoTask = 0L; d->stage = ClientPrivate::StageOne; d->typingNotifyTask = 0L; + d->ssiModifyTask = 0L; d->awayMsgRequestTimer = new QTimer(); d->codecProvider = &defaultCodecProvider; @@ -711,6 +713,7 @@ d->icqInfoTask = new ICQUserInfoRequestTask( c->rootTask() ); d->userInfoTask = new UserInfoTask( c->rootTask() ); d->typingNotifyTask = new TypingNotifyTask( c->rootTask() ); + d->ssiModifyTask = new SSIModifyTask( c->rootTask(), true ); connect( d->onlineNotifier, SIGNAL( userIsOnline( const QString&, const UserDetails& ) ), this, SIGNAL( receivedUserInfo( const QString&, const UserDetails& ) ) ); @@ -754,6 +757,8 @@ SSIModifyTask* ssimt = new SSIModifyTask( c->rootTask() ); if ( ssimt->removeGroup( groupName ) ) ssimt->go( true ); + else + delete ssimt; } void Client::addGroup( const QString& groupName ) @@ -766,6 +771,8 @@ SSIModifyTask* ssimt = new SSIModifyTask( c->rootTask() ); if ( ssimt->addGroup( groupName ) ) ssimt->go( true ); + else + delete ssimt; } void Client::addContact( const QString& contactName, const QString& groupName ) @@ -778,7 +785,8 @@ SSIModifyTask* ssimt = new SSIModifyTask( c->rootTask() ); if ( ssimt->addContact( contactName, groupName ) ) ssimt->go( true ); - + else + delete ssimt; } void Client::removeContact( const QString& contactName ) @@ -791,6 +799,8 @@ SSIModifyTask* ssimt = new SSIModifyTask( c->rootTask() ); if ( ssimt->removeContact( contactName ) ) ssimt->go( true ); + else + delete ssimt; } void Client::renameGroup( const QString & oldGroupName, const QString & newGroupName ) @@ -803,6 +813,8 @@ SSIModifyTask* ssimt = new SSIModifyTask( c->rootTask() ); if ( ssimt->renameGroup( oldGroupName, newGroupName ) ) ssimt->go( true ); + else + delete ssimt; } void Client::modifyContactItem( const OContact& oldItem, const OContact& newItem ) @@ -824,14 +836,20 @@ case 0: if ( ssimt->modifyItem( oldItem, newItem ) ) ssimt->go( true ); + else + delete ssimt; break; case 1: if ( ssimt->addItem( newItem ) ) ssimt->go( true ); + else + delete ssimt; break; case 2: if ( ssimt->removeItem( oldItem ) ) ssimt->go( true ); + else + delete ssimt; break; } } @@ -847,6 +865,8 @@ SSIModifyTask* ssimt = new SSIModifyTask( c->rootTask() ); if ( ssimt->changeGroup( contact, newGroupName ) ) ssimt->go( true ); + else + delete ssimt; } void Client::requestFullInfo( const QString& contactId ) @@ -1453,6 +1473,7 @@ delete d->icqInfoTask; delete d->userInfoTask; delete d->typingNotifyTask; + delete d->ssiModifyTask; d->errorTask = 0; d->onlineNotifier = 0; @@ -1462,6 +1483,7 @@ d->icqInfoTask = 0; d->userInfoTask = 0; d->typingNotifyTask = 0; + d->ssiModifyTask = 0; } bool Client::hasIconConnection( ) const --- trunk/KDE/kdenetwork/kopete/protocols/oscar/liboscar/contactmanager.cpp #645364:645365 @@ -448,26 +448,26 @@ return false; } -bool ContactManager::updateGroup( const OContact& oldGroup, const OContact& newGroup ) +bool ContactManager::updateGroup( const OContact& group ) { - removeID( oldGroup ); - if ( d->contactList.removeAll( oldGroup ) == 0 ) + OContact oldGroup = findGroup( group.name() ); + + if ( oldGroup.isValid() ) { - kDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "No group were removed." << endl; - return false; + removeID( oldGroup ); + d->contactList.removeAll( oldGroup ); } - - if ( d->contactList.contains( newGroup ) ) + + if ( d->contactList.contains( group ) ) { kDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "New group is already in list." << endl; return false; } - - kDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Updating group '" << newGroup.name() << "' in SSI list" << endl; - addID( newGroup ); - d->contactList.append( newGroup ); - emit groupUpdated( newGroup ); - + + kDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Updating group '" << group.name() << "' in SSI list" << endl; + addID( group ); + d->contactList.append( group ); + emit groupUpdated( group ); return true; } @@ -516,26 +516,26 @@ return true; } -bool ContactManager::updateContact( const OContact& oldContact, const OContact& newContact ) +bool ContactManager::updateContact( const OContact& contact ) { - removeID( oldContact ); - if ( d->contactList.removeAll( oldContact ) == 0 ) + OContact oldContact = findContact( contact.name() ); + + if ( oldContact.isValid() ) { - kDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "No contacts were removed." << endl; - return false; + removeID( oldContact ); + d->contactList.removeAll( oldContact ); } - - if ( d->contactList.contains( newContact ) ) + + if ( d->contactList.contains( contact ) ) { kDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "New contact is already in list." << endl; return false; } - - kDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Updating contact '" << newContact.name() << "' in SSI list" << endl; - addID( newContact ); - d->contactList.append( newContact ); - emit contactUpdated( newContact ); - + + kDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Updating contact '" << contact.name() << "' in SSI list" << endl; + addID( contact ); + d->contactList.append( contact ); + emit contactUpdated( contact ); return true; } @@ -569,17 +569,51 @@ bool ContactManager::newItem( const OContact& item ) { - //no error checking for now + if ( d->contactList.contains( item ) ) + { + kDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Item is already in list." << endl; + return false; + } + kDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "Adding item " << item.toString() << endl; addID( item ); d->contactList.append( item ); return true; } +bool ContactManager::updateItem( const OContact& item ) +{ + OContact oldItem = findItem( item.name(), item.type() ); + + if ( oldItem.isValid() ) + { + removeID( oldItem ); + d->contactList.removeAll( oldItem ); + } + + if ( d->contactList.contains( item ) ) + { + kDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "New item is already in list." << endl; + return false; + } + + kDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Updating item in SSI list" << endl; + addID( item ); + d->contactList.append( item ); + return true; +} + bool ContactManager::removeItem( const OContact& item ) { removeID( item ); - d->contactList.removeAll( item ); + int remcount = d->contactList.removeAll( item ); + + if ( remcount == 0 ) + { + kDebug(OSCAR_RAW_DEBUG) << k_funcinfo << "No items were removed." << endl; + return false; + } + return true; } --- trunk/KDE/kdenetwork/kopete/protocols/oscar/liboscar/contactmanager.h #645364:645365 @@ -105,16 +105,17 @@ public slots: bool newGroup( const OContact& group ); - bool updateGroup( const OContact& oldGroup, const OContact& newGroup ); + bool updateGroup( const OContact& group ); bool removeGroup( const OContact& group ); bool removeGroup( const QString& group ); bool newContact( const OContact& contact ); - bool updateContact( const OContact& oldContact, const OContact& newContact ); + bool updateContact( const OContact& contact ); bool removeContact( const OContact& contact ); bool removeContact( const QString& contact ); bool newItem( const OContact& item ); + bool updateItem( const OContact& item ); bool removeItem( const OContact& item ); void addID( const OContact& item ); --- trunk/KDE/kdenetwork/kopete/protocols/oscar/liboscar/tasks/ssiauthtask.cpp #645364:645365 @@ -112,10 +112,6 @@ Transfer* t = createTransfer( f, s, buf ); send( t ); - - OContact contact = m_manager->findContact( uin ); - if ( contact ) - contact.setWaitingAuth( true ); } void SSIAuthTask::sendAuthReply( const QString& uin, const QString& reason, bool auth ) @@ -175,11 +171,6 @@ kDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Authorization request declined by " << uin << endl; kDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Reason: " << reason << endl; - - OContact sender = m_manager->findContact( uin ); - if ( sender ) - sender.setWaitingAuth( false ); - emit authReplied( uin, reason, accepted ); } --- trunk/KDE/kdenetwork/kopete/protocols/oscar/liboscar/tasks/ssimodifytask.cpp #645364:645365 @@ -28,9 +28,10 @@ #include "transfer.h" -SSIModifyTask::SSIModifyTask( Task* parent ) : Task( parent ) +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; @@ -50,9 +51,22 @@ { if ( forMe( transfer ) ) { - setTransfer( transfer ); - handleContactAck(); - setTransfer( 0 ); + SnacTransfer* st = dynamic_cast<SnacTransfer*>( transfer ); + if ( st ) + { + setTransfer( transfer ); + + if ( st->snacSubtype() == 0x0008 ) + handleContactAdd(); + else if ( st->snacSubtype() == 0x0009 ) + handleContactUpdate(); + else if ( st->snacSubtype() == 0x000A ) + handleContactRemove(); + else if ( st->snacSubtype() == 0x000E ) + handleContactAck(); + + setTransfer( 0 ); + } return true; } else @@ -202,10 +216,22 @@ if ( !st ) return false; - if ( st->snacService() == 0x0013 && st->snacSubtype() == 0x000E && m_id == st->snac().id ) - return true; - else - 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::handleContactAck() @@ -429,9 +455,9 @@ else if ( m_opSubject == Group ) { if ( m_opType == Rename ) - m_ssiManager->updateGroup( m_oldItem, m_newItem ); + m_ssiManager->updateGroup( m_newItem ); else if ( m_opType == Change ) - m_ssiManager->updateContact( m_oldItem, m_newItem ); + m_ssiManager->updateContact( m_newItem ); } else if ( m_opSubject == NoSubject ) { @@ -530,4 +556,81 @@ buffer->addTLV( ( *it ) ); } +OContact SSIModifyTask::getItemFromBuffer( Buffer* buffer ) const +{ + QList<TLV> tlvList; + + QString itemName = QString::fromUtf8( buffer->getBSTR() ); + Oscar::WORD groupId = buffer->getWord(); + Oscar::WORD itemId = buffer->getWord(); + Oscar::WORD itemType = buffer->getWord(); + Oscar::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 OContact( itemName, groupId, itemId, itemType, tlvList ); +} + +void SSIModifyTask::handleContactAdd() +{ + Buffer* b = transfer()->buffer(); + + while ( b->bytesAvailable() > 0 ) + { + OContact item = getItemFromBuffer( b ); + kDebug(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::handleContactUpdate() +{ + Buffer* b = transfer()->buffer(); + + while ( b->bytesAvailable() > 0 ) + { + OContact item = getItemFromBuffer( b ); + kDebug(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::handleContactRemove() +{ + Buffer* b = transfer()->buffer(); + + while ( b->bytesAvailable() > 0 ) + { + OContact item = getItemFromBuffer( b ); + kDebug(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 ); + } +} + //kate: tab-width 4; indent-mode csands; --- trunk/KDE/kdenetwork/kopete/protocols/oscar/liboscar/tasks/ssimodifytask.h #645364:645365 @@ -52,7 +52,7 @@ class SSIModifyTask : public Task { public: - SSIModifyTask(Task* parent); + SSIModifyTask( Task* parent, bool staticTask = false ); ~SSIModifyTask(); virtual void onGo(); @@ -129,7 +129,17 @@ void sendEditEnd(); void addItemToBuffer( OContact item, Buffer* buffer ); - + OContact getItemFromBuffer( Buffer* buffer ) const; + + //! Handle server request to add data + void handleContactAdd(); + + //! Handle server request to update data + void handleContactUpdate(); + + //! Handle server request to remove data + void handleContactRemove(); + private: OContact m_oldItem; OContact m_newItem; @@ -138,7 +148,8 @@ OperationSubject m_opSubject; Oscar::WORD m_id; ContactManager* m_ssiManager; - + bool m_static; + }; #endif
I've built kopete from svn today (version 651173) and the problem is not fixed. I still can't add users freely to visible/invisible lists. It is a strange bug not very consistent, you might be able to add one user and then you can't add more. Other times you can add more users... It's strange. In LICQ it does work correctly, in case anyone can look at how it does it.
Alberto: can you compile Kopete with debug enabled and post console log here? Thanks
Can you also tell me which clients did you use before Kopete? Thanks
Ok, I've built kpote from svn again (version 651357) with -enable-debug=full. When adding a user to the invisible list (which results in a failed addition) what I get is: kopete (oscar - raw protocol): [void Client::setInvisibleTo(const QString&, bool)] Adding XXXXXXXX to invisible list kopete (oscar - raw protocol): [void Client::modifySSIItem(const Oscar::SSI&, const Oscar::SSI&)] Add/Mod/Del item on server kopete (oscar - raw protocol): [void SSIModifyTask::sendSSIUpdate()] Adding an item to the SSI list kopete (oscar - raw protocol): [void CoreProtocol::addIncomingData(const QByteArray&)] Received 26 bytes. kopete (oscar - raw protocol): [virtual Transfer* SnacProtocol::parse(const QByteArray&, uint&)] family: 19 subtype: 14 flags: 32768 id: 52085 kopete (oscar - raw protocol): Acknowledgement code is 1 kopete (oscar - raw protocol): [void SSIModifyTask::handleSSIAck()] Unknown acknowledgement code Before kopete I used the original winicq client and Gaim.
Created attachment 20206 [details] Prints more debug info Alberto: I'm sorry but I cannot reproduce it and we don't know what acknowledgement code 1 is :( If you could apply attached patch (It adds more debug info to oscar), compile oscar, run Kopete from console and send me a log, it would be great. I swear I wont be providing your log to anybody else and I will delete it when I fix this bug or give up. My email is: kedgedev at centrum dot cz Steps to compile and run: cd kopete patch -p0 < /path/to/ssidebug.diff cd protocols/oscar/ make install and run kopete: kopete --nofork 2>debug.log the log will be in debug.log. Thanks
I tested it with KDE 4.0.85 (KDE 4.1 >= 20080703) openSUSE packages. What I did: 1. Add Contacts to Always Visible/Always Invisible list and save. 2. Restart Kopete, the lists had the same contacts that I added before. 3. Remove contacts and save. 4. Restart Kopete, now the list was empty again. => I cannot confirm the bug
I helped Roman Jarosz to debug this problem about a year ago. Apparently, the bug only happens with old accounts where many old contacts have been deleted over time and some kind of limit has been reached. IIRC, each time you delete an old contact it leaves some trace on the server, and once you reach a limit (like 200 or so, can't remember exactly) things act strangely. But with the official ICQ client (Windows) and with Licq (Linux), this problem doesn't happen, so Kopete must be doing something strange. However, in the end it is a low impact bug: Not only it affects a small number of users, it even has workarounds (like retrying to add/delete contacts to/from the invisible list a few times until they stick the way you want them).
I have a similar problem, but not sure if it's related to this bug... If I select user from the drop-down list, it perfectly adds. But if I type part of the name (kopete autoselects first match then), contact won't appear in the list. Qt: 4.4.3 KDE: 4.1.2 (KDE 4.1.2) Kopete: 0.60.2 Kubuntu: 8.10 x64
Dear Bug Submitter, This bug has been stagnant for a long time. Could you help us out and re-test if the bug is valid in the latest version? I am setting the status to NEEDSINFO pending your response, please change the Status back to REPORTED when you respond. Thank you for helping us make KDE software even better for everyone!
Dear Bug Submitter, This is a reminder that this bug has been stagnant for a long time. Could you help us out and re-test if the bug is valid in the latest version? This bug will be moved back to REPORTED Status for manual review later, which may take a while. If you are able to, please lend us a hand. Thank you for helping us make KDE software even better for everyone!
Thank you for reporting this issue in KDE software. As it has been a while since this issue was reported, can we please ask you to see if you can reproduce the issue with a recent software version? If you can reproduce the issue, please change the status to "REPORTED" when replying. Thank you!
Dear Bug Submitter, This bug has been in NEEDSINFO status with no change for at least 15 days. Please provide the requested information as soon as possible and set the bug status as REPORTED. Due to regular bug tracker maintenance, if the bug is still in NEEDSINFO status with no change in 30 days the bug will be closed as RESOLVED > WORKSFORME due to lack of needed information. For more information about our bug triaging procedures please read the wiki located here: https://community.kde.org/Guidelines_and_HOWTOs/Bug_triaging If you have already provided the requested information, please mark the bug as REPORTED so that the KDE team knows that the bug is ready to be confirmed. Thank you for helping us make KDE software even better for everyone!
This bug has been in NEEDSINFO status with no change for at least 30 days. The bug is now closed as RESOLVED > WORKSFORME due to lack of needed information. For more information about our bug triaging procedures please read the wiki located here: https://community.kde.org/Guidelines_and_HOWTOs/Bug_triaging Thank you for helping us make KDE software even better for everyone!