Bug 101683 - Wrong status after reconnect
Summary: Wrong status after reconnect
Status: RESOLVED FIXED
Alias: None
Product: kopete
Classification: Unmaintained
Component: ICQ and AIM Plugins (other bugs)
Version First Reported In: unspecified
Platform: Debian testing Linux
: NOR wishlist
Target Milestone: ---
Assignee: Kopete Developers
URL:
Keywords:
: 128079 133262 (view as bug list)
Depends on:
Blocks:
 
Reported: 2005-03-17 12:16 UTC by Stephan Windmüller
Modified: 2008-12-28 14:02 UTC (History)
3 users (show)

See Also:
Latest Commit:
Version Fixed In:
Sentry Crash Report:


Attachments
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 (2.19 KB, patch)
2005-05-28 05:41 UTC, Quinn Storm
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Stephan Windmüller 2005-03-17 12:16:27 UTC
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.
Comment 1 Quinn Storm 2005-05-28 05:41:22 UTC
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.
Comment 2 Jan Ritzerfeld 2006-04-16 23:38:06 UTC
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;
 };
 
Comment 3 Jan Ritzerfeld 2006-05-26 16:03:27 UTC
*** Bug 128079 has been marked as a duplicate of this bug. ***
Comment 4 Jan Ritzerfeld 2006-08-30 11:11:23 UTC
*** Bug 133262 has been marked as a duplicate of this bug. ***
Comment 5 Bram Schoenmakers 2007-02-04 12:39:44 UTC
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.
Comment 6 Jan Ritzerfeld 2007-03-24 13:06:37 UTC
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.
Comment 7 Bram Schoenmakers 2007-03-24 13:18:20 UTC
> I think you meant "ICQ did /not/ restore my Away status after reconnect 
> yesterday." :) 

Just to clarify: yes, that's what I meant.
Comment 8 Roman Jarosz 2008-12-28 14:02:42 UTC
IIRC this should be fixed in KDE 4.1 and greater. If it isn't please reopen.