Bug 130895

Summary: Extra Status for ICQ protocol in kopete (aka Xtra/X-Status/xStatus)
Product: [Unmaintained] kopete Reporter: Ildar Nurislamov <absorbb>
Component: ICQ and AIM PluginsAssignee: Roman Jarosz <kedgedev>
Status: RESOLVED FIXED    
Severity: wishlist CC: kopete-bugs-null, petr.odut, rcc.fry
Priority: NOR    
Version: unspecified   
Target Milestone: ---   
Platform: FreeBSD Ports   
OS: FreeBSD   
Latest Commit: Version Fixed In:
Sentry Crash Report:

Description Ildar Nurislamov 2006-07-16 10:24:29 UTC
Version:            (using KDE KDE 3.5.3)
Installed from:    FreeBSD Ports
OS:                FreeBSD

When in kopete will be added Extra Statuses? It's works much time in many clients for Windows. But still there is no unix clients that supports this feature. Extra Status is pretty and useful thing.
Comment 1 Conrad Hoffmann 2006-07-31 15:35:31 UTC
*** Bug 131589 has been marked as a duplicate of this bug. ***
Comment 2 Rezeda 2006-10-21 20:13:34 UTC
*** This bug has been confirmed by popular vote. ***
Comment 3 Fry 2006-10-22 09:45:19 UTC
Many win-users use X-status, but in kopete no X-status.
Comment 4 Roman Jarosz 2007-01-06 18:03:41 UTC
SVN commit 620581 by rjarosz:

Add general Xtraz notification support.
Add Xtraz status support.
 - we can send and receive Xtraz status.
 - Kopete automatically retrieves Xtraz status.
 - for now we only show Xtraz status description in contact list.

TODO:
 - add GUI interface for own Xtraz status.
 - create OnlineStatus for buddy with Xtraz status icon and title.

FEATURE: 130895



 M  +14 -4     icq/icqcontact.cpp  
 M  +10 -9     icqcontactbase.cpp  
 M  +2 -1      icqcontactbase.h  
 M  +2 -1      liboscar/CMakeLists.txt  
 M  +57 -1     liboscar/client.cpp  
 M  +2 -2      liboscar/client.h  
 M  +1 -1      liboscar/profiletask.cpp  
 A             liboscar/xtrazxawayservice.cpp   [License: LGPL (v2+)]
 A             liboscar/xtrazxawayservice.h   [License: LGPL (v2+)]
 A             liboscar/xtrazxrandomizerservice.cpp   [License: LGPL (v2+)]
 A             liboscar/xtrazxrandomizerservice.h   [License: LGPL (v2+)]
 A             liboscar/xtrazxservice.cpp   [License: LGPL (v2+)]
 A             liboscar/xtrazxservice.h   [License: LGPL (v2+)]
 A             liboscar/xtrazxtraznotify.cpp   [License: LGPL (v2+)]
 A             liboscar/xtrazxtraznotify.h   [License: LGPL (v2+)]


--- trunk/KDE/kdenetwork/kopete/protocols/oscar/icq/icqcontact.cpp #620580:620581
@@ -96,15 +96,25 @@
 	ICQ::Presence presence = ICQ::Presence::fromOscarStatus( details.extendedStatus() & 0xffff );
 	setOnlineStatus( presence.toOnlineStatus() );
 
-	// ICQ does not support status messages for state Online
+	bool selfVisible = ( ICQ::Presence::fromOnlineStatus( account()->myself()->onlineStatus() ).visibility() == ICQ::Presence::Visible );
 	if ( presence.type() == ICQ::Presence::Online )
 	{
-		mAccount->engine()->removeICQAwayMessageRequest( contactId() );
-		removeProperty( mProtocol->awayMessage );
+		if ( details.xtrazStatusSpecified() )
+		{
+			if ( selfVisible )
+				mAccount->engine()->addICQAwayMessageRequest( contactId(), Client::ICQXStatus );
+			else
+				mAccount->engine()->removeICQAwayMessageRequest( contactId() );
+		}
+		else
+		{
+			mAccount->engine()->removeICQAwayMessageRequest( contactId() );
+			removeProperty( mProtocol->awayMessage );
+		}
 	}
 	else
 	{
-		if ( ICQ::Presence::fromOnlineStatus( account()->myself()->onlineStatus() ).visibility() == ICQ::Presence::Visible )
+		if ( selfVisible )
 		{
 			switch ( presence.type() )
 			{
--- trunk/KDE/kdenetwork/kopete/protocols/oscar/icqcontactbase.cpp #620580:620581
@@ -30,10 +30,10 @@
 {
 	m_requestingNickname = false;
 
-	QObject::connect( mAccount->engine(), SIGNAL( receivedIcqShortInfo( const QString& ) ),
-	                  this, SLOT( receivedShortInfo( const QString& ) ) );
-	QObject::connect( mAccount->engine(), SIGNAL( receivedAwayMessage( const Oscar::Message& ) ),
-	                  this, SLOT( receivedStatusMessage( const Oscar::Message& ) ) );
+	QObject::connect( mAccount->engine(), SIGNAL(receivedIcqShortInfo(const QString&)),
+	                  this, SLOT(receivedShortInfo(const QString&)) );
+	QObject::connect( mAccount->engine(), SIGNAL(receivedXStatusMessage(const QString&, int, const QString&, const QString&)),
+	                  this, SLOT(receivedXStatusMessage(const QString&, int, const QString&, const QString&)) );
 }
 
 ICQContactBase::~ICQContactBase()
@@ -79,14 +79,15 @@
 	}
 }
 
-void ICQContactBase::receivedStatusMessage( const Oscar::Message &message )
+void ICQContactBase::receivedXStatusMessage( const QString& contact, int icon, const QString& title, const QString& desc )
 {
-	if ( Oscar::normalize( message.sender() ) != Oscar::normalize( contactId() ) )
+	if ( Oscar::normalize( contact ) != Oscar::normalize( contactId() ) )
 		return;
+
+	// TODOL create OnlineStatus with icon and title
+	setAwayMessage( desc );
 	
-	//decode message
-	QTextCodec* codec = contactCodec();
-	setAwayMessage( message.text(codec) );
+	m_haveAwayMessage = true;
 }
 
 void ICQContactBase::slotSendMsg( Kopete::Message& msg, Kopete::ChatSession* session )
--- trunk/KDE/kdenetwork/kopete/protocols/oscar/icqcontactbase.h #620580:620581
@@ -29,6 +29,7 @@
  * @author Richard Smith
  * @author Matt Rogers
  */
+
 class KOPETE_EXPORT ICQContactBase : public OscarContact
 {
 Q_OBJECT
@@ -53,7 +54,7 @@
 
 private slots:
 	void receivedShortInfo( const QString& contact );
-	void receivedStatusMessage( const Oscar::Message &message );
+	void receivedXStatusMessage( const QString& contact, int icon, const QString& title, const QString& desc );
 
 };
 
--- trunk/KDE/kdenetwork/kopete/protocols/oscar/liboscar/CMakeLists.txt #620580:620581
@@ -25,13 +25,14 @@
 buddyicontask.cpp serverredirecttask.cpp oscarsettings.cpp filetransfertask.cpp
 localcontactlisttask.cpp chatnavservicetask.cpp connectionhandler.cpp chatservicetask.cpp oscarguid.cpp 
 icquserinfoupdatetask.cpp icqchangepasswordtask.cpp oscarmessageplugin.cpp oftmetatransfer.cpp
+xtrazxawayservice.cpp xtrazxservice.cpp xtrazxtraznotify.cpp xtrazxrandomizerservice.cpp
 )
 
 kde4_automoc(${liboscar_SRCS} )
 
 kde4_add_library( oscar SHARED ${liboscar_SRCS} )
 
-target_link_libraries( oscar ${KDE4_KDECORE_LIBS} ${QT_QTNETWORK_LIBRARY} )
+target_link_libraries( oscar ${KDE4_KDECORE_LIBS} ${QT_QTNETWORK_LIBRARY} ${QT_QTXML_LIBRARY} )
 
 install(TARGETS oscar  DESTINATION ${LIB_INSTALL_DIR})
 
--- trunk/KDE/kdenetwork/kopete/protocols/oscar/liboscar/client.cpp #620580:620581
@@ -65,6 +65,8 @@
 #include "icquserinfoupdatetask.h"
 #include "icqchangepasswordtask.h"
 #include "oscarmessageplugin.h"
+#include "xtrazxtraznotify.h"
+#include "xtrazxawayservice.h"
 
 
 namespace
@@ -545,6 +547,31 @@
 			response.setText( Oscar::Message::UserDefined, statusMessage(), codec );
 			emit userReadsStatusMessage( msg.sender() );
 		}
+		else if ( msg.messageType() == Oscar::MessageType::Plugin )
+		{
+			Oscar::MessagePlugin::Types type = msg.plugin()->type();
+			Oscar::WORD subType = msg.plugin()->subTypeId();
+			if ( type == Oscar::MessagePlugin::XtrazScript )
+			{
+				if ( subType == Oscar::MessagePlugin::SubScriptNotify )
+				{
+					using namespace Xtraz;
+					XtrazNotify xNotify;
+					xNotify.handle( msg.plugin() );
+					if ( xNotify.type() == XtrazNotify::Request && xNotify.pluginId() == "srvMng" )
+					{
+						if ( xNotify.findService( "cAwaySrv" ) )
+						{
+							//TODO: Send own Xtraz status
+							/* XtrazNotify xNotifyResponse;
+							xNotifyResponse.setSenderUni( userId() );
+							response.setPlugin( xNotifyResponse.statusResponse( 1, "title", "desc" ) );
+							emit userReadsStatusMessage( msg.sender() );*/
+						}
+					}
+				}
+			}
+		}
 		else
 		{
 			response.setEncoding( Oscar::Message::UserDefined );
@@ -568,7 +595,26 @@
 		}
 		else if ( msg.messageType() == Oscar::MessageType::Plugin )
 		{
-			kDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Received a plugin message response." << endl;
+			kDebug( OSCAR_RAW_DEBUG ) << k_funcinfo << "Received an plugin message response." << endl;
+
+			Oscar::MessagePlugin::Types type = msg.plugin()->type();
+			Oscar::WORD subType = msg.plugin()->subTypeId();
+			if ( type == Oscar::MessagePlugin::XtrazScript )
+			{
+				if ( subType == Oscar::MessagePlugin::SubScriptNotify )
+				{
+					using namespace Xtraz;
+					XtrazNotify xNotify;
+					xNotify.handle( msg.plugin() );
+					if ( xNotify.type() == XtrazNotify::Response )
+					{
+						const Xtraz::XAwayService* service = dynamic_cast<const XAwayService*>(xNotify.findService( "cAwaySrv" ));
+						if ( service )
+							emit receivedXStatusMessage( service->senderId(), service->iconIndex(),
+							                             service->title(), service->description() );
+					}
+				}
+			}
 		}
 	}
 	else
@@ -922,6 +968,16 @@
 	case ICQFreeForChat:
 		msg.setMessageType( Oscar::MessageType::AutoFFC ); // free for chat
 		break;
+	case ICQXStatus:
+		{
+			msg.setMessageType( Oscar::MessageType::Plugin ); // plugin message
+			msg.addProperty( ~ Oscar::Message::StatusMessageRequest );
+
+			Xtraz::XtrazNotify xNotify;
+			xNotify.setSenderUni( userId() );
+			msg.setPlugin( xNotify.statusRequest() );
+			break;
+		}
 	default:
 		// may be a good way to deal with possible error and lack of online status message?
 		emit receivedAwayMessage( contact, "Sorry, this protocol does not support this type of status message" );
--- trunk/KDE/kdenetwork/kopete/protocols/oscar/liboscar/client.h #620580:620581
@@ -75,7 +75,7 @@
 		FatalProtocolError = 3
 	};
 
-	enum ICQStatus { ICQOnline = 0, ICQAway, ICQNotAvailable, ICQOccupied, ICQDoNotDisturb, ICQFreeForChat };
+	enum ICQStatus { ICQOnline = 0, ICQAway, ICQNotAvailable, ICQOccupied, ICQDoNotDisturb, ICQFreeForChat, ICQXStatus };
 
 	/*************
 	  EXTERNAL API
@@ -439,7 +439,7 @@
 
 	void receivedProfile( const QString& contact, const QString& profile );
 	void receivedAwayMessage( const QString& contact, const QString& message );
-	void receivedAwayMessage( const Oscar::Message& message );
+	void receivedXStatusMessage( const QString& contact, int icon, const QString& title, const QString& desc );
 	void receivedUserInfo( const QString& contact, const UserDetails& details );
 	void userReadsStatusMessage( const QString& contact );
 
--- trunk/KDE/kdenetwork/kopete/protocols/oscar/liboscar/profiletask.cpp #620580:620581
@@ -104,7 +104,7 @@
 			capBuf.addGuid( oscar_caps[CAP_DIRECT_ICQ_COMMUNICATION] ); // we support direct communication
 			//capBuf.addGuid( oscar_caps[CAP_RTFMSGS] ); // we do incoming RTF messages
 			capBuf.addGuid( oscar_caps[CAP_NEWCAPS] ); // we understand the new format of caps (xtra status)
-			//capBuf.addGuid( oscar_caps[CAP_XTRAZ] ); // we support xtraz
+			capBuf.addGuid( oscar_caps[CAP_XTRAZ] ); // we support xtraz
 		}
 		else
 		{
Comment 5 alexey novgorodov 2007-10-20 08:46:23 UTC
there are no usefull xtraz support yet
Comment 6 Roman Jarosz 2007-10-20 10:33:36 UTC
It's in trunk and will be in KDE 4.0