Bug 116614 - away messages are clobbered depending on the order they are received
Summary: away messages are clobbered depending on the order they are received
Status: RESOLVED FIXED
Alias: None
Product: kopete
Classification: Applications
Component: libkopete (show other bugs)
Version: unspecified
Platform: openSUSE Linux
: NOR normal
Target Milestone: ---
Assignee: Will Stephenson
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-11-18 12:14 UTC by S. Burmeister
Modified: 2006-05-03 12:10 UTC (History)
1 user (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description S. Burmeister 2005-11-18 12:14:48 UTC
Version:            (using KDE KDE 3.5.0)
Installed from:    SuSE RPMs
OS:                Linux

I have a meta-contact of the other person with ICQ and MSN in it. If the user is online, I do not see the "listening to"-text next to the nick. However it is shown in the MSN-tooltip, not in the ICQ one.
If the user is away for too long, kopete switches to away, the "listening to" is shown for a second next to the nick and then disappears again.

If the user sets its status to away manually, the "listening to" is shown perfectly in both tooltips and next to the nick.
Comment 1 Olivier Goffart 2005-12-24 12:45:25 UTC
Does the problem occursd only with ICQ,  or both with ICQ and MSN ?
Comment 2 S. Burmeister 2005-12-31 19:01:03 UTC
It happens for meta-contacts that have an MSN as well as an ICQ account. The music-text is shown in MSN's tooltip, not in ICQ's if the other person is online.

If those accounts are split, i.e. not part of one meta-contact, the MSN one shows the text, the ICQ one does not.

If one combines those two accounts into one meta-contact, the text is not shown next to the user's picture. I think this happens because the text provided by the MSN account is overwritten by the ICQ one, which is empty. This is the actual bug, yet there is some room for enhancements in the functionality as well.

If the other user is set to away, MSN's text is deleted until the next song begins. This should not happen when there is a song played.

If the other user sets its status to away, there is no possibility to do this keeping the text for the currently played song. Either bug 113966 is fixed in order to allow going away or online without changing/erasing/setting any away-message, or kopete ignores the away/online -> no message, if the "now listening" plug-in is used. The no-message is only respected till the next song begins by kopete anyway.
Comment 3 Will Stephenson 2006-03-11 21:14:25 UTC
Mea culpa
Comment 4 Jan Ritzerfeld 2006-04-14 17:06:58 UTC
SVN commit 529819 by jritzerfeld:

Use the following method to determine the status message to 
be displayed (the term "contact" should be read as 
"contact of the metacontact" and "online" as "not offline"):
* Display the new status message if
 - the new status message is not empty and
 - the contact who set it is online or there are no contacts online at all.
* Otherwise display the first non-empty status message among all contacts
  online---or offline if there are no contacts online at all.
* If no status message is displayed yet display no status message at all.

BUG: 116614


 M  +33 -3     kopete/contactlist/kopetemetacontactlvi.cpp  
 M  +5 -6      protocols/jabber/jabberbasecontact.cpp  


--- branches/kopete/0.12/kopete/kopete/contactlist/kopetemetacontactlvi.cpp #529818:529819
@@ -796,15 +796,45 @@
 		setTargetVisibility( true );
 }
 
-void KopeteMetaContactLVI::slotContactPropertyChanged( Kopete::Contact */*contact*/,
+void KopeteMetaContactLVI::slotContactPropertyChanged( Kopete::Contact *contact,
 	const QString &key, const QVariant &old, const QVariant &newVal )
 {
+//	if ( key == QString::fromLatin1("awayMessage") )
+//		kdDebug( 14000 ) << k_funcinfo << "contact=" << contact->contactId() << ", isonline=" << contact->isOnline() << ", alloffline=" << !m_metaContact->isOnline() << ", oldvalue=" << old.toString() << ", newvalue=" << newVal.toString() << endl;
 	if ( key == QString::fromLatin1("awayMessage") && d->extraText && old != newVal )
 	{
-		if ( newVal.toString().isEmpty() )
-			d->extraText->setText( QString::null );
+		bool allOffline = !m_metaContact->isOnline();
+		if ( newVal.toString().isEmpty() || ( !contact->isOnline() && !allOffline ) )
+		{
+			// try to find a more suitable away message to be displayed when: 
+			// -new away message is empty or
+			// -contact who set it is offline and there are contacts online in the metacontact
+			bool allAwayMessagesEmpty = true;
+			QPtrList<Kopete::Contact> contacts = m_metaContact->contacts();
+			for ( Kopete::Contact *c = contacts.first(); c; c = contacts.next() )
+			{
+//				kdDebug( 14000 ) << k_funcinfo << "ccontact=" << c->contactId() << ", isonline=" << c->isOnline() << ", awaymsg=" << c->property( key ).value().toString() << endl;
+				QString awayMessage( c->property( key ).value().toString() );
+				if ( ( allOffline || c->isOnline() ) && !awayMessage.isEmpty() )
+				{
+					// display this contact's away message when:
+					// -this contact's away message is not empty and
+					// -this contact is online or there are no contacts online at all
+					allAwayMessagesEmpty = false;
+					d->extraText->setText( awayMessage );
+					break;
+				}
+			}
+			if ( allAwayMessagesEmpty )
+				d->extraText->setText( QString::null );
+		}
 		else
+		{
+			// just use new away message when:
+			// -new away message is not empty and
+			// -contact who set it is online or there are no contacts online at all
 			d->extraText->setText( newVal.toString() );
+		}
 	} // wtf? KopeteMetaContact also connects this signals and emits photoChanged! why no connect photoChanged to slotPhotoChanged?
 	/*else if ( key == QString::fromLatin1("photo") && (m_metaContact->photoSourceContact() == contact) && (m_metaContact->photoSource() == Kopete::MetaContact::SourceContact))
 	{
--- branches/kopete/0.12/kopete/protocols/jabber/jabberbasecontact.cpp #529818:529819
@@ -308,6 +308,11 @@
 	}
 	
 
+	updateResourceList ();
+
+	kdDebug (JABBER_DEBUG_GLOBAL) << k_funcinfo << "New status for " << contactId () << " is " << status.description () << endl;
+	setOnlineStatus ( status );
+
 	/*
 	 * Set away message property.
 	 * We just need to read it from the current resource.
@@ -321,12 +326,6 @@
 		removeProperty ( protocol()->propAwayMessage );
 	}
 
-	updateResourceList ();
-
-
-	kdDebug (JABBER_DEBUG_GLOBAL) << k_funcinfo << "New status for " << contactId () << " is " << status.description () << endl;
-	setOnlineStatus ( status );
-
 }
 
 QString JabberBaseContact::fullAddress ()
Comment 5 Jan Ritzerfeld 2006-04-30 23:26:18 UTC
SVN commit 535976 by jritzerfeld:

Backport fix:
Use the following method to determine the status message to 
be displayed (the term "contact" should be read as 
"contact of the metacontact" and "online" as "not offline"):
* Display the new status message if
 - the new status message is not empty and
 - the contact who set it is online or there are no contacts online at all.
* Otherwise display the first non-empty status message among all contacts
  online---or offline if there are no contacts online at all.
* If no status message is displayed yet display no status message at all.

CCBUG: 116614


 M  +33 -3     kopete/contactlist/kopetemetacontactlvi.cpp  
 M  +5 -5      protocols/jabber/jabberbasecontact.cpp  


--- branches/KDE/3.5/kdenetwork/kopete/kopete/contactlist/kopetemetacontactlvi.cpp #535975:535976
@@ -796,15 +796,45 @@
 		setTargetVisibility( true );
 }
 
-void KopeteMetaContactLVI::slotContactPropertyChanged( Kopete::Contact */*contact*/,
+void KopeteMetaContactLVI::slotContactPropertyChanged( Kopete::Contact *contact,
 	const QString &key, const QVariant &old, const QVariant &newVal )
 {
+//	if ( key == QString::fromLatin1("awayMessage") )
+//		kdDebug( 14000 ) << k_funcinfo << "contact=" << contact->contactId() << ", isonline=" << contact->isOnline() << ", alloffline=" << !m_metaContact->isOnline() << ", oldvalue=" << old.toString() << ", newvalue=" << newVal.toString() << endl;
 	if ( key == QString::fromLatin1("awayMessage") && d->extraText && old != newVal )
 	{
-		if ( newVal.toString().isEmpty() )
-			d->extraText->setText( QString::null );
+		bool allOffline = !m_metaContact->isOnline();
+		if ( newVal.toString().isEmpty() || ( !contact->isOnline() && !allOffline ) )
+		{
+			// try to find a more suitable away message to be displayed when: 
+			// -new away message is empty or
+			// -contact who set it is offline and there are contacts online in the metacontact
+			bool allAwayMessagesEmpty = true;
+			QPtrList<Kopete::Contact> contacts = m_metaContact->contacts();
+			for ( Kopete::Contact *c = contacts.first(); c; c = contacts.next() )
+			{
+//				kdDebug( 14000 ) << k_funcinfo << "ccontact=" << c->contactId() << ", isonline=" << c->isOnline() << ", awaymsg=" << c->property( key ).value().toString() << endl;
+				QString awayMessage( c->property( key ).value().toString() );
+				if ( ( allOffline || c->isOnline() ) && !awayMessage.isEmpty() )
+				{
+					// display this contact's away message when:
+					// -this contact's away message is not empty and
+					// -this contact is online or there are no contacts online at all
+					allAwayMessagesEmpty = false;
+					d->extraText->setText( awayMessage );
+					break;
+				}
+			}
+			if ( allAwayMessagesEmpty )
+				d->extraText->setText( QString::null );
+		}
 		else
+		{
+			// just use new away message when:
+			// -new away message is not empty and
+			// -contact who set it is online or there are no contacts online at all
 			d->extraText->setText( newVal.toString() );
+		}
 	} // wtf? KopeteMetaContact also connects this signals and emits photoChanged! why no connect photoChanged to slotPhotoChanged?
 	/*else if ( key == QString::fromLatin1("photo") && (m_metaContact->photoSourceContact() == contact) && (m_metaContact->photoSource() == Kopete::MetaContact::SourceContact))
 	{
--- branches/KDE/3.5/kdenetwork/kopete/protocols/jabber/jabberbasecontact.cpp #535975:535976
@@ -267,6 +267,11 @@
 
 	status = protocol()->resourceToKOS ( resource );
 
+	updateResourceList ();
+
+	kdDebug (JABBER_DEBUG_GLOBAL) << k_funcinfo << "New status for " << contactId () << " is " << status.description () << endl;
+	setOnlineStatus ( status );
+
 	/*
 	 * Set away message property.
 	 * We just need to read it from the current resource.
@@ -280,11 +285,6 @@
 		removeProperty ( protocol()->propAwayMessage );
 	}
 
-	updateResourceList ();
-
-	kdDebug (JABBER_DEBUG_GLOBAL) << k_funcinfo << "New status for " << contactId () << " is " << status.description () << endl;
-	setOnlineStatus ( status );
-
 }
 
 QString JabberBaseContact::fullAddress ()
Comment 6 Jan Ritzerfeld 2006-05-03 12:10:55 UTC
SVN commit 536812 by jritzerfeld:

Remove the away message property of an icq contact when it goes 
online, i.e. it was offline and changes its status to something else than 
offline or unknown.

CCBUG: 116614


 M  +4 -0      icqcontact.cpp  


--- branches/kopete/0.12/kopete/protocols/oscar/icq/icqcontact.cpp #536811:536812
@@ -117,6 +117,10 @@
 	if ( Oscar::normalize( contact  ) != Oscar::normalize( contactId() ) )
 		return;
 
+	// invalidate old away message if user was offline
+	if ( !isOnline() )
+		removeProperty( mProtocol->awayMessage );
+
 	kdDebug( OSCAR_ICQ_DEBUG ) << k_funcinfo << "extendedStatus is " << details.extendedStatus() << endl;
 	ICQ::Presence presence = ICQ::Presence::fromOscarStatus( details.extendedStatus() & 0xffff );
 	setOnlineStatus( presence.toOnlineStatus() );