Version: (using KDE KDE 3.3.2) Installed from: Debian testing/unstable Packages OS: Linux I installed kopete for a friend of mine. She uses ICQ and Jabber. With Jabber, all works fine. But when she is away with ICQ, kopete often changes this to "Online". I think, this happens when reconnecting to the ICQ-Server. Activating Auto-Away is not a solution, because one can not set Auto-N/A or Auto-Busy. Expected behaviour: Kopete should restore the defined status after reconnecting.
Created attachment 11228 [details] an attempt at a general fix for this sort of problem...though it needs more work...am hoping filing it here will get it some attention please someone take a look at this and let me know what you think of it, this patch is the result of some hacking I've done on libkopete code...but unfortunately my incomplete understanding of how it all works has left me unable to completely finish it.
SVN commit 530493 by jritzerfeld: Restore online status and status message on reconnect. Thanks to Quinn Storm for the initial patch. CCMAIL: Quinn Storm <livinglatexkali@gmail.com> FEATURE: 101683 M +33 -1 libkopete/kopeteaccount.cpp M +10 -0 libkopete/kopeteaccount.h M +6 -7 protocols/oscar/icq/icqaccount.cpp M +1 -0 protocols/oscar/icq/icqaccount.h --- branches/kopete/0.12/kopete/libkopete/kopeteaccount.cpp #530492:530493 @@ -79,6 +79,8 @@ KConfigGroup *configGroup; uint connectionTry; QString customIcon; + Kopete::OnlineStatus restoreStatus; + QString restoreMessage; }; Account::Account( Protocol *parent, const QString &accountId, const char *name ) @@ -91,6 +93,9 @@ d->customIcon = d->configGroup->readEntry( "Icon", QString() ); d->priority = d->configGroup->readNumEntry( "Priority", 0 ); + d->restoreStatus = Kopete::OnlineStatus::Online; + d->restoreMessage = ""; + QObject::connect( &d->suppressStatusTimer, SIGNAL( timeout() ), this, SLOT( slotStopSuppression() ) ); } @@ -111,6 +116,12 @@ delete d; } +void Account::reconnect() +{ + kdDebug( 14010 ) << k_funcinfo << "account " << d->id << " restoreStatus " << d->restoreStatus.status() << " restoreMessage " << d->restoreMessage << endl; + setOnlineStatus( d->restoreStatus, d->restoreMessage ); +} + void Account::disconnected( DisconnectReason reason ) { //reconnect if needed @@ -121,7 +132,7 @@ d->connectionTry++; //use a timer to allow the plugins to clean up after return if(d->connectionTry < 3) - QTimer::singleShot( 0, this, SLOT(connect())); + QTimer::singleShot(10000, this, SLOT(reconnect())); // wait 10 seconds before reconnect } if(reason== OtherClient) { @@ -385,6 +396,8 @@ { QObject::disconnect( d->myself, SIGNAL( onlineStatusChanged( Kopete::Contact *, const Kopete::OnlineStatus &, const Kopete::OnlineStatus & ) ), this, SLOT( slotOnlineStatusChanged( Kopete::Contact *, const Kopete::OnlineStatus &, const Kopete::OnlineStatus & ) ) ); + QObject::disconnect( d->myself, SIGNAL( propertyChanged( Kopete::Contact *, const QString &, const QVariant &, const QVariant & ) ), + this, SLOT( slotContactPropertyChanged( Kopete::Contact *, const QString &, const QVariant &, const QVariant & ) ) ); } d->myself = myself; @@ -393,6 +406,8 @@ QObject::connect( d->myself, SIGNAL( onlineStatusChanged( Kopete::Contact *, const Kopete::OnlineStatus &, const Kopete::OnlineStatus & ) ), this, SLOT( slotOnlineStatusChanged( Kopete::Contact *, const Kopete::OnlineStatus &, const Kopete::OnlineStatus & ) ) ); + QObject::connect( d->myself, SIGNAL( propertyChanged( Kopete::Contact *, const QString &, const QVariant &, const QVariant & ) ), + this, SLOT( slotContactPropertyChanged( Kopete::Contact *, const QString &, const QVariant &, const QVariant & ) ) ); if ( isConnected() != wasConnected ) emit isConnectedChanged(); @@ -417,6 +432,13 @@ //the timer is also used to reset the d->connectionTry } + if ( !isOffline ) + { + d->restoreStatus = newStatus; + d->restoreMessage = myself()->property( Kopete::Global::Properties::self()->awayMessage() ).value().toString(); +// kdDebug( 14010 ) << k_funcinfo << "account " << d->id << " restoreStatus " << d->restoreStatus.status() << " restoreMessage " << d->restoreMessage << endl; + } + /* kdDebug(14010) << k_funcinfo << "account " << d->id << " changed status. was " << Kopete::OnlineStatus::statusTypeToString(oldStatus.status()) << ", is " << Kopete::OnlineStatus::statusTypeToString(newStatus.status()) << endl;*/ @@ -434,6 +456,16 @@ it.current()->setOnlineStatus( status ); } +void Account::slotContactPropertyChanged( Contact * /* contact */, + const QString &key, const QVariant &old, const QVariant &newVal ) +{ + if ( key == QString::fromLatin1("awayMessage") && old != newVal && isConnected() ) + { + d->restoreMessage = newVal.toString(); +// kdDebug( 14010 ) << k_funcinfo << "account " << d->id << " restoreMessage " << d->restoreMessage << endl; + } +} + void Account::slotStopSuppression() { d->suppressStatusNotification = false; --- branches/kopete/0.12/kopete/libkopete/kopeteaccount.h #530492:530493 @@ -503,6 +503,11 @@ private slots: /** + * Restore online status and status message on reconnect. + */ + virtual void reconnect(); + + /** * Track the deletion of a Contact and clean up */ void contactDestroyed( Kopete::Contact * ); @@ -513,6 +518,11 @@ void slotOnlineStatusChanged( Kopete::Contact *contact, const Kopete::OnlineStatus &newStatus, const Kopete::OnlineStatus &oldStatus ); /** + * The @ref myself() contact's property changed. + */ + void slotContactPropertyChanged( Kopete::Contact *, const QString &, const QVariant &, const QVariant & ); + + /** * Stop the suppression of status notification (connected to a timer) */ void slotStopSuppression(); --- branches/kopete/0.12/kopete/protocols/oscar/icq/icqaccount.cpp #530492:530493 @@ -56,6 +56,7 @@ kdDebug( OSCAR_ICQ_DEBUG ) << k_funcinfo << "extendedStatus is " << QString::number( extendedStatus, 16 ) << endl; ICQ::Presence presence = ICQ::Presence::fromOscarStatus( extendedStatus & 0xffff ); setOnlineStatus( presence.toOnlineStatus() ); + setProperty( Kopete::Global::Properties::self()->awayMessage(), static_cast<ICQAccount*>( account() )->engine()->statusMessage() ); } void ICQMyselfContact::receivedShortInfo( const QString& contact ) @@ -87,6 +88,7 @@ QString nickName = configGroup()->readEntry("NickName", QString::null); mWebAware = configGroup()->readBoolEntry( "WebAware", false ); mHideIP = configGroup()->readBoolEntry( "HideIP", true ); + mInitialStatusMessage = QString::null; QObject::connect( Kopete::ContactList::self(), SIGNAL( globalIdentityChanged( const QString&, const QVariant& ) ), this, SLOT( slotGlobalIdentityChanged( const QString&, const QVariant& ) ) ); @@ -183,10 +185,11 @@ status |= ICQ::StatusCode::WEBAWARE; engine()->setIsIcq( true ); - engine()->setStatus( status ); + engine()->setStatus( status, mInitialStatusMessage ); engine()->start( server, port, accountId(), password ); engine()->connectToServer( c, server, true /* doAuth */ ); + mInitialStatusMessage = QString::null; } } @@ -308,12 +311,10 @@ void ICQAccount::setPresenceType( ICQ::Presence::Type type, const QString &message ) { - Q_UNUSED( message ); ICQ::Presence pres = presence(); - kdDebug(14153) << k_funcinfo << "new type=" << (int)type << ", old type=" << (int)pres.type() << endl; + kdDebug(14153) << k_funcinfo << "new type=" << (int)type << ", old type=" << (int)pres.type() << ", new message=" << message << endl; //setAwayMessage(awayMessage); setPresenceTarget( ICQ::Presence( type, pres.visibility() ), message ); - myself()->setProperty( Kopete::Global::Properties::self()->awayMessage(), message ); } void ICQAccount::setPresenceTarget( const ICQ::Presence &newPres, const QString &message ) @@ -330,9 +331,7 @@ } else if ( accountIsOffline ) { - // set status message if given - if ( ! message.isEmpty() ) - engine()->setStatusMessage( message ); + mInitialStatusMessage = message; OscarAccount::connect( newPres.toOnlineStatus() ); } else --- branches/kopete/0.12/kopete/protocols/oscar/icq/icqaccount.h #530492:530493 @@ -101,6 +101,7 @@ private: bool mWebAware; bool mHideIP; + QString mInitialStatusMessage; OscarVisibilityDialog* m_visibilityDialog; };
*** Bug 128079 has been marked as a duplicate of this bug. ***
*** Bug 133262 has been marked as a duplicate of this bug. ***
Reopening because this is still the case. ICQ did restore my Away status after a reconnect yesterday (0.12.3). And I heard the same happens with MSN as well, but didn't experience that sofar.
I think you meant "ICQ did /not/ restore my Away status after reconnect yesterday." :) Generally, restoring of status does work. I am disconnected every 12h. However, in rare cases, the status is not correctly restored. The restore code is triggered (kdDebug in Account::reconnect()) but the saved status is simply wrong, that is online. For me, this is limited to ICQ and does not apply to jabber. The reason for this is that ICQ goes Online first when connecting, and gets its real status by the second(!) user info of the server. Thus, the code I added is triggered twice, first with Online and second with the saved value. That this is really the case, can be easily seen in my debug output. So, if there is an additional connection problem between these two phases, the status will be actually wrong, that is Online. IMHO, the generic code in Account cannot detect this situation. The ICQ protocol might be able to suppress the first, always Online user info only if it is possible with ICQ to go directly to a status other than Online.
> I think you meant "ICQ did /not/ restore my Away status after reconnect > yesterday." :) Just to clarify: yes, that's what I meant.
IIRC this should be fixed in KDE 4.1 and greater. If it isn't please reopen.