[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kopete-devel
Subject:    [kopete-devel] [PATCH] Non-intrusive notifications v3
From:       "Roman Jarosz" <kedgedev () centrum ! cz>
Date:       2008-03-16 19:05:38
Message-ID: op.t74hzoh3yuholc () localhost
[Download RAW message or body]

Hi

Here is the final version of non-intrusive notifications.

Since last version I have added KNotification for new info events
(the KNotification name is "Service Message") and made some slight
adjustment to the API. I've also fixed couple bug and polished the gui.

All protocols are now converted to the new API, I didn't test the Yahoo, MSN
and Telepaty but it should be ok. If anybody can test these protocols please do.

If nobody objects I'll probably commit it tomorrow.

Thanks,
Roman

["kopetenotifications3.diff" (kopetenotifications3.diff)]

Index: protocols/yahoo/yahooaccount.h
===================================================================
--- protocols/yahoo/yahooaccount.h	(revision 786234)
+++ protocols/yahoo/yahooaccount.h	(working copy)
@@ -183,7 +183,7 @@
 	void slotAuthorizationAccepted( const QString &who );
 	void slotAuthorizationRejected( const QString &who, const QString &msg );
 	void slotgotAuthorizationRequest( const QString &, const QString &, const QString & \
                );
-	void slotContactAddedNotifyDialogClosed( const QString & );
+	void slotAddedInfoEventActionActivated( uint actionId );
 	void slotGotIgnore(const QStringList &);
 	void slotGotIdentities(const QStringList &);
 	void slotStatusChanged(const QString &who, int stat, const QString &msg, int away, \
                int idle, int pictureChecksum);
Index: protocols/yahoo/yahooaccount.cpp
===================================================================
--- protocols/yahoo/yahooaccount.cpp	(revision 786234)
+++ protocols/yahoo/yahooaccount.cpp	(working copy)
@@ -54,7 +54,7 @@
 #include <kopetecontactlist.h>
 #include <kopetetransfermanager.h>
 #include <kopeteview.h>
-#include <contactaddednotifydialog.h>
+#include <events/kopeteaddedinfoevent.h>
 
 // Yahoo
 #include "yahooaccount.h"
@@ -837,29 +837,36 @@
 	if(kc)
 		metaContact=kc->metaContact();
 
-	Kopete::UI::ContactAddedNotifyDialog::HideWidgetOptions \
                hideFlags=Kopete::UI::ContactAddedNotifyDialog::InfoButton;
-	if( metaContact && !metaContact->isTemporary() )
-		hideFlags |= Kopete::UI::ContactAddedNotifyDialog::AddCheckBox | \
Kopete::UI::ContactAddedNotifyDialog::AddGroupBox ; \
+	Kopete::AddedInfoEvent::ShowActionOptions actions = \
Kopete::AddedInfoEvent::AuthorizeAction; +	actions |= \
Kopete::AddedInfoEvent::BlockAction; +	if( !metaContact || metaContact->isTemporary() \
) +		actions |= Kopete::AddedInfoEvent::AddAction;
 
-	Kopete::UI::ContactAddedNotifyDialog *dialog=
-		new Kopete::UI::ContactAddedNotifyDialog( user,QString(),this, hideFlags );
-	QObject::connect(dialog,SIGNAL(applyClicked(const QString&)),
-	                 this,SLOT(slotContactAddedNotifyDialogClosed(const QString& )));
-	dialog->show();
+	Kopete::AddedInfoEvent* event = new Kopete::AddedInfoEvent( user, this );
+	QObject::connect( event, SIGNAL(actionActivated(uint)),
+	                  this, SLOT(slotAddedInfoEventActionActivated(uint)) );
+	
+	event->showActions( actions );
+	event->sendEvent();
 }
 
-void YahooAccount::slotContactAddedNotifyDialogClosed( const QString &user )
+void YahooAccount::slotAddedInfoEventActionActivated( uint actionId )
 {
-	const Kopete::UI::ContactAddedNotifyDialog *dialog =
-		dynamic_cast<const Kopete::UI::ContactAddedNotifyDialog *>(sender());
-	if(!dialog || !isConnected())
+	const Kopete::AddedInfoEvent *event = dynamic_cast<const Kopete::AddedInfoEvent \
*>(sender()); +	if( !event || !isConnected() )
 		return;
 
-	m_session->sendAuthReply( user, dialog->authorized(), QString() );
-
-	if(dialog->added())
+	switch ( actionId )
 	{
-		dialog->addContact();
+	case Kopete::AddedInfoEvent::AuthorizeAction:
+		m_session->sendAuthReply( event->contactId(), true, QString() );
+		break;
+	case Kopete::AddedInfoEvent::BlockAction:
+		m_session->sendAuthReply( event->contactId(), false, QString() );
+		break;
+	case Kopete::AddedInfoEvent::AddContactAction:
+		event->addContact();
+		break;
 	}
 }
 
Index: protocols/jabber/jabberaccount.h
===================================================================
--- protocols/jabber/jabberaccount.h	(revision 786234)
+++ protocols/jabber/jabberaccount.h	(working copy)
@@ -277,7 +277,7 @@
 	void slotSubscription ( const XMPP::Jid &jid, const QString &type );
 
 	/* the dialog that asked to add the contact was closed   (that dialog is shown in \
                slotSubscription) */
-	void slotContactAddedNotifyDialogClosed(const QString& contactid);
+	void slotAddedInfoEventActionActivated ( uint actionId );
 
 	/**
 	 * A new item appeared in our roster, synch it with the
Index: protocols/jabber/jabberaccount.cpp
===================================================================
--- protocols/jabber/jabberaccount.cpp	(revision 786234)
+++ protocols/jabber/jabberaccount.cpp	(working copy)
@@ -59,7 +59,7 @@
 #include "kopetegroup.h"
 #include "kopetecontactlist.h"
 #include "kopeteaccountmanager.h"
-#include "contactaddednotifydialog.h"
+#include "events/kopeteaddedinfoevent.h"
 
 #include "jabberconnector.h"
 #include "jabberclient.h"
@@ -1184,16 +1184,19 @@
 		Kopete::MetaContact *metaContact=0L;
 		if(contact)
 			metaContact=contact->metaContact();
-		
-		Kopete::UI::ContactAddedNotifyDialog::HideWidgetOptions \
                hideFlags=Kopete::UI::ContactAddedNotifyDialog::InfoButton;
-		if( metaContact && !metaContact->isTemporary() )
-			hideFlags |= Kopete::UI::ContactAddedNotifyDialog::AddCheckBox | \
                Kopete::UI::ContactAddedNotifyDialog::AddGroupBox ;
-		
-		Kopete::UI::ContactAddedNotifyDialog *dialog=
-				new Kopete::UI::ContactAddedNotifyDialog( jid.full() ,QString(),this, hideFlags \
                );
-		QObject::connect(dialog,SIGNAL(applyClicked(const QString&)),
-						this,SLOT(slotContactAddedNotifyDialogClosed(const QString& )));
-		dialog->show();
+
+		Kopete::AddedInfoEvent::ShowActionOptions actions = \
Kopete::AddedInfoEvent::AuthorizeAction; +		actions |= \
Kopete::AddedInfoEvent::BlockAction; +
+		if( !metaContact || metaContact->isTemporary() )
+			actions |= Kopete::AddedInfoEvent::AddAction;
+
+		Kopete::AddedInfoEvent* event = new Kopete::AddedInfoEvent( jid.full(), this );
+		QObject::connect( event, SIGNAL(actionActivated(uint)),
+		                  this, SLOT(slotAddedInfoEventActionActivated(uint)) );
+
+		event->showActions( actions );
+		event->sendEvent();
 	}
 	else if (type == "unsubscribed")
 	{
@@ -1237,41 +1240,36 @@
 	}
 }
 
-void JabberAccount::slotContactAddedNotifyDialogClosed( const QString & contactid )
-{	// the dialog that asked the authorisation is closed. (it was shown in \
                slotSubscrition)
-	
-	XMPP::JT_Presence *task;
-	XMPP::Jid jid(contactid);
+void JabberAccount::slotAddedInfoEventActionActivated ( uint actionId )
+{
+	const Kopete::AddedInfoEvent *event =
+		dynamic_cast<const Kopete::AddedInfoEvent *>(sender());
 
-	const Kopete::UI::ContactAddedNotifyDialog *dialog =
-			dynamic_cast<const Kopete::UI::ContactAddedNotifyDialog *>(sender());
-	if(!dialog || !isConnected())
+	if ( !event || !isConnected() )
 		return;
 
-	if ( dialog->authorized() )
+	XMPP::Jid jid(event->contactId());
+	if ( actionId == Kopete::AddedInfoEvent::AuthorizeAction )
 	{
 		/*
 		* Authorize user.
 		*/
-
-		task = new XMPP::JT_Presence ( client()->rootTask () );
+		XMPP::JT_Presence *task = new XMPP::JT_Presence ( client()->rootTask () );
 		task->sub ( jid, "subscribed" );
 		task->go ( true );
 	}
-	else
+	else if ( actionId == Kopete::AddedInfoEvent::BlockAction )
 	{
 		/*
 		* Reject subscription.
 		*/
-		task = new XMPP::JT_Presence ( client()->rootTask () );
+		XMPP::JT_Presence *task = new XMPP::JT_Presence ( client()->rootTask () );
 		task->sub ( jid, "unsubscribed" );
 		task->go ( true );
 	}
-
-
-	if(dialog->added())
+	else if( actionId == Kopete::AddedInfoEvent::AddContactAction )
 	{
-		Kopete::MetaContact *parentContact=dialog->addContact();
+		Kopete::MetaContact *parentContact=event->addContact();
 		if(parentContact)
 		{
 			QStringList groupNames;
@@ -1280,7 +1278,6 @@
 				groupNames += group->displayName();
 
 			XMPP::RosterItem item;
-//			XMPP::Jid jid ( contactId );
 
 			item.setJid ( jid );
 			item.setName ( parentContact->displayName() );
Index: protocols/msn/msnaccount.cpp
===================================================================
--- protocols/msn/msnaccount.cpp	(revision 786234)
+++ protocols/msn/msnaccount.cpp	(working copy)
@@ -51,7 +51,7 @@
 #include "kopeteuiglobal.h"
 #include "kopeteglobal.h"
 #include "kopetechatsessionmanager.h"
-#include "contactaddednotifydialog.h"
+#include "events/kopeteaddedinfoevent.h"
 
 #if !defined NDEBUG
 #include "msndebugrawcmddlg.h"
@@ -1002,12 +1002,17 @@
 				QString nick;			//in most case, the public name is not know
 				if(publicName!=handle)  // so we don't whos it if it is not know
 					nick=publicName;
-				Kopete::UI::ContactAddedNotifyDialog *dialog=
-						new Kopete::UI::ContactAddedNotifyDialog(  handle,nick,this,
-								Kopete::UI::ContactAddedNotifyDialog::InfoButton );
-				QObject::connect(dialog,SIGNAL(applyClicked(const QString&)),
-								 this,SLOT(slotContactAddedNotifyDialogClosed(const QString& )));
-				dialog->show();
+
+				Kopete::AddedInfoEvent::ShowActionOptions actions = \
Kopete::AddedInfoEvent::AuthorizeAction; +				actions |= \
Kopete::AddedInfoEvent::BlockAction | Kopete::AddedInfoEvent::AddAction; +
+				Kopete::AddedInfoEvent* event = new Kopete::AddedInfoEvent( handle, this );
+				QObject::connect( event, SIGNAL(actionActivated(uint)),
+				                  this, SLOT(slotAddedInfoEventActionActivated(uint)) );
+
+				event->showActions( actions );
+				event->setContactNickname( nick );
+				event->sendEvent();
 			}
 		}
 		else
@@ -1220,17 +1225,17 @@
 	}
 }
 
-void MSNAccount::slotContactAddedNotifyDialogClosed(const QString& handle)
+void MSNAccount::slotAddedInfoEventActionActivated( uint actionId )
 {
-	const Kopete::UI::ContactAddedNotifyDialog *dialog =
-			dynamic_cast<const Kopete::UI::ContactAddedNotifyDialog *>(sender());
-	if(!dialog || !m_notifySocket)
+	const Kopete::AddedInfoEvent *event = dynamic_cast<const Kopete::AddedInfoEvent \
*>(sender()); +	if( !event || !m_notifySocket )
 		return;
 
-	if(dialog->added())
+	QString handle = event->contactId();
+	if ( actionId == Kopete::AddedInfoEvent::AddContactAction )
 	{
-		Kopete::MetaContact *mc=dialog->addContact();
-		if(mc)
+		Kopete::MetaContact *mc = event->addContact();
+		if ( mc )
 		{ //if the contact has been added this way, it's because the other user added us.
 		  // don't forgot to set the reversed flag  (Bug 114400)
 			if ( !mc->contacts().isEmpty() )
@@ -1243,15 +1248,14 @@
 			}
 		}
 	}
-
-	if ( !dialog->authorized() )
+	else if ( actionId == Kopete::AddedInfoEvent::BlockAction )
 	{
 		if ( m_allowList.contains( handle ) )
 			m_notifySocket->removeContact( handle, MSNProtocol::AL, QString(), QString() );
 		else if ( !m_blockList.contains( handle ) )
 			m_notifySocket->addContact( handle, MSNProtocol::BL, QString(), QString(), \
QString() );  }
-	else
+	else if ( actionId == Kopete::AddedInfoEvent::AuthorizeAction )
 	{
 		if ( m_blockList.contains( handle ) )
 			m_notifySocket->removeContact( handle, MSNProtocol::BL, QString(), QString() );
@@ -1259,7 +1263,6 @@
 			m_notifySocket->addContact( handle, MSNProtocol::AL, QString(), QString(), \
QString() );  }
 
-
 }
 
 void MSNAccount::slotErrorMessageReceived( int type, const QString &msg )
Index: protocols/msn/msnaccount.h
===================================================================
--- protocols/msn/msnaccount.h	(revision 786234)
+++ protocols/msn/msnaccount.h	(working copy)
@@ -191,9 +191,9 @@
 	void slotKopeteGroupRemoved( Kopete::Group* );
 
 	/**
-	 * add contact ui
+	 * added info event
 	 */
-	void slotContactAddedNotifyDialogClosed( const QString &handle);
+	void slotAddedInfoEventActionActivated( uint actionId );
 
 	/**
 	 * When the dispatch server sends us the notification server to use.
Index: protocols/telepathy/telepathyaddpendingcontactjob.cpp
===================================================================
--- protocols/telepathy/telepathyaddpendingcontactjob.cpp	(revision 786234)
+++ protocols/telepathy/telepathyaddpendingcontactjob.cpp	(working copy)
@@ -23,7 +23,7 @@
 #include <kdebug.h>
 
 // Kopete includes
-#include <contactaddednotifydialog.h>
+#include <events/kopeteaddedinfoevent.h?
 #include <kopetemetacontact.h>
 #include <kopetecontactlist.h>
 
@@ -76,60 +76,64 @@
 
 	Q_ASSERT( !d->pendingContact.isNull() );
 
-	ContactAddedNotifyDialog::HideWidgetOptions hideOptions = \
                ContactAddedNotifyDialog::InfoButton;
-	if( d->authorizationOnly )
+	Kopete::AddedInfoEvent::ShowActionOptions actions = \
Kopete::AddedInfoEvent::AuthorizeAction; +	if( !d->authorizationOnly )
 	{
-		hideOptions |= ContactAddedNotifyDialog::AddGroupBox | \
ContactAddedNotifyDialog::AddCheckBox; +		actions |= \
Kopete::AddedInfoEvent::AddAction;  }
 
-	Kopete::UI::ContactAddedNotifyDialog *dialog = new \
Kopete::UI::ContactAddedNotifyDialog(d->pendingContact->uri(), \
                d->pendingContact->alias(), d->account, hideOptions);
-	connect(dialog, SIGNAL(applyClicked(QString)), this, SLOT(contactDialogDone()));
+	Kopete::AddedInfoEvent* event = new Kopete::AddedInfoEvent( \
d->pendingContact->uri(), d->account ); +	QObject::connect( event, \
SIGNAL(actionActivated(uint)), +	                  this, \
SLOT(slotAddedInfoEventActionActivated(uint)) ); +	QObject::connect( event, \
SIGNAL(eventClosed(Kopete::InfoEvent*)), +	                  this, \
SLOT(slotAddedInfoEventClosed()) );  
-	dialog->show();
+	event->showActions( actions );
+	event->setContactNickname( d->pendingContact->alias() );
+	event->sendEvent();
 }
 
-void TelepathyAddPendingContactJob::contactDialogDone()
+void TelepathyAddPendingContactJob::slotAddedInfoEventActionActivated( uint actionId \
)  {
-	// NOTE: sender() is evil. It kill kittens.
-	Kopete::UI::ContactAddedNotifyDialog *dialog = \
dynamic_cast<Kopete::UI::ContactAddedNotifyDialog *>( sender() ); +	const \
Kopete::AddedInfoEvent *event = dynamic_cast<const Kopete::AddedInfoEvent \
*>(sender()); +	if( !event )
+	{
+		setError( KJob::UserDefinedError );
+		return;
+	}
 
-	if( dialog )
+	if ( actionId == Kopete::AddedInfoEvent::AddContactAction )
 	{
-		if( dialog->added() )
+		// Get the new metacontact
+		Kopete::MetaContact *newMetaContact = event->addContact();
+
+		// Set internal contact pointer to new contact
+		QString contactUri = d->pendingContact->uri();
+		TelepathyContact *newContact = static_cast<TelepathyContact*>( \
d->account->contacts()[contactUri] ); +		if( newContact )
 		{
-			// Get the new metacontact
-			Kopete::MetaContact *newMetaContact = dialog->addContact();
-	
-			// Set internal contact pointer to new contact
-			QString contactUri = d->pendingContact->uri();
-			TelepathyContact *newContact = static_cast<TelepathyContact*>( \
                d->account->contacts()[contactUri] );
-			if( newContact )
-			{
-				newContact->setInternalContact( d->pendingContact );
-				// Subscribe to contact presence.
-				d->pendingContact->subscribe(true);
+			newContact->setInternalContact( d->pendingContact );
+			// Subscribe to contact presence.
+			d->pendingContact->subscribe(true);
 
-				// Add to contact list
-				Kopete::ContactList::self()->addMetaContact( newMetaContact );
-			}
-			else
-			{
-				kDebug(TELEPATHY_DEBUG_AREA) << "Could not find new Telepathy contact " << \
                contactUri;
-				setError( KJob::UserDefinedError );
-			}
+			// Add to contact list
+			Kopete::ContactList::self()->addMetaContact( newMetaContact );
 		}
-
-		if( dialog->authorized() )
+		else
 		{
-			// Authorize new contact
-			d->pendingContact->authorize(true);
+			kDebug(TELEPATHY_DEBUG_AREA) << "Could not find new Telepathy contact " << \
contactUri; +			setError( KJob::UserDefinedError );
 		}
 	}
-	else
+	else if ( actionId == Kopete::AddedInfoEvent::AuthorizeAction )
 	{
-		setError( KJob::UserDefinedError );
+		// Authorize new contact
+		d->pendingContact->authorize(true);
 	}
+}
 
+void TelepathyAddPendingContactJob::slotAddedInfoEventClosed()
+{
 	emitResult();
 }
 
Index: protocols/telepathy/telepathyaddpendingcontactjob.h
===================================================================
--- protocols/telepathy/telepathyaddpendingcontactjob.h	(revision 786234)
+++ protocols/telepathy/telepathyaddpendingcontactjob.h	(working copy)
@@ -55,7 +55,8 @@
 	virtual void start();
 
 private slots:
-	void contactDialogDone();
+	void slotAddedInfoEventActionActivated( uint actionId );
+	void slotAddedInfoEventClosed();
 
 private:
 	class Private;
Index: protocols/oscar/icq/icqaccount.h
===================================================================
--- protocols/oscar/icq/icqaccount.h	(revision 786234)
+++ protocols/oscar/icq/icqaccount.h	(working copy)
@@ -3,7 +3,7 @@
 
   Copyright (c) 2002 by Chris TenHarmsel            <tenharmsel@staticmethod.net>
   Copyright (c) 2004 by Richard Smith               <kde@metafoo.co.uk>
-  Kopete    (c) 2002-2007 by the Kopete developers  <kopete-devel@kde.org>
+  Kopete    (c) 2002-2008 by the Kopete developers  <kopete-devel@kde.org>
 
   *************************************************************************
   *                                                                       *
@@ -101,9 +101,9 @@
 
 	/** We have received an auth request */
 	void slotGotAuthRequest( const QString& contact, const QString& reason );
-	
-	void slotAuthReplyDialogOkClicked();
 
+	void addedInfoEventActionActivated( uint actionId );
+
 private:
 	bool mWebAware;
 	bool mHideIP;
Index: protocols/oscar/icq/icqaccount.cpp
===================================================================
--- protocols/oscar/icq/icqaccount.cpp	(revision 786234)
+++ protocols/oscar/icq/icqaccount.cpp	(working copy)
@@ -3,7 +3,7 @@
 
   Copyright (c) 2002 by Chris TenHarmsel            <tenharmsel@staticmethod.net>
   Copyright (c) 2004 by Richard Smith               <kde@metafoo.co.uk>
-  Kopete    (c) 2002-2007 by the Kopete developers  <kopete-devel@kde.org>
+  Kopete    (c) 2002-2008 by the Kopete developers  <kopete-devel@kde.org>
 
   *************************************************************************
   *                                                                       *
@@ -30,6 +30,8 @@
 #include "kopetemessage.h"
 #include "kopetecontactlist.h"
 #include "kopeteuiglobal.h"
+#include "kopetemetacontact.h"
+#include "events/kopeteaddedinfoevent.h"
 
 #include "client.h"
 #include "icquserinfo.h"
@@ -48,7 +50,6 @@
 #include "xtrazicqstatuseditor.h"
 #include "xtrazstatusaction.h"
 #include "icqstatusmanager.h"
-#include "icqauthreplydialog.h"
 
 ICQMyselfContact::ICQMyselfContact( ICQAccount *acct ) : OscarMyselfContact( acct )
 {
@@ -476,24 +477,62 @@
 
 void ICQAccount::slotGotAuthRequest( const QString& contact, const QString& reason )
 {
-	ICQAuthReplyDialog *replyDialog = new ICQAuthReplyDialog();
-	QObject::connect( this, SIGNAL(destroyed()), replyDialog, SLOT(deleteLater()) );
-	QObject::connect( replyDialog, SIGNAL(okClicked()), this, \
SLOT(slotAuthReplyDialogOkClicked()) ); +	QString contactId = Oscar::normalize( \
contact );  
-	Kopete::Contact * ct = contacts()[ Oscar::normalize( contact ) ];	
-	replyDialog->setUser( ( ct ) ? ct->nickName() : contact );
-	replyDialog->setContact( contact );
-	replyDialog->setRequestReason( reason );
-	replyDialog->show();
+	Kopete::AddedInfoEvent* event = new Kopete::AddedInfoEvent( contactId, this );
+	QObject::connect( event, SIGNAL(actionActivated(uint)), this, \
SLOT(addedInfoEventActionActivated(uint)) ); +
+	Kopete::AddedInfoEvent::ShowActionOptions actions = \
Kopete::AddedInfoEvent::AuthorizeAction; +	actions |= \
Kopete::AddedInfoEvent::BlockAction; +	actions |= Kopete::AddedInfoEvent::InfoAction;
+
+	Kopete::Contact * ct = contacts()[contactId];
+	if( !ct || !ct->metaContact() || ct->metaContact()->isTemporary() )
+		actions |= Kopete::AddedInfoEvent::AddAction;
+
+	if( ct )
+		event->setContactNickname( ct->nickName() );
+
+	event->showActions( actions );
+	event->setAdditionalText( reason );
+	event->sendEvent();
 }
 
-void ICQAccount::slotAuthReplyDialogOkClicked()
+void ICQAccount::addedInfoEventActionActivated( uint actionId )
 {
-    // Do not need to delete will delete itself automatically
-	ICQAuthReplyDialog *replyDialog = (ICQAuthReplyDialog*)sender();
+	Kopete::AddedInfoEvent *event = dynamic_cast<Kopete::AddedInfoEvent *>(sender());
+	if ( !event || !isConnected() )
+		return;
 	
-	if ( replyDialog )
-		engine()->sendAuth( replyDialog->contact(), replyDialog->reason(), \
replyDialog->grantAuth() ); +	kDebug() << "actionId: " << actionId;
+	switch ( actionId )
+	{
+	case Kopete::AddedInfoEvent::AddContactAction:
+		event->addContact();
+		break;
+	case Kopete::AddedInfoEvent::AuthorizeAction:
+		engine()->sendAuth( event->contactId(), QString(), true );
+		break;
+	case Kopete::AddedInfoEvent::BlockAction:
+		engine()->sendAuth( event->contactId(), QString(), false );
+		engine()->setIgnore( event->contactId(), true );
+		break;
+	case Kopete::AddedInfoEvent::InfoAction:
+		{
+			ICQContact* c = new ICQContact( this, event->contactId(), NULL );
+			ICQUserInfoWidget* info = new ICQUserInfoWidget( Kopete::UI::Global::mainWidget() \
); +			QObject::connect( info, SIGNAL(finished()), c, SLOT(deleteLater()) );
+			QObject::connect( info, SIGNAL(finished()), info, SLOT(delayedDestruct()) );
+			QObject::connect( event, SIGNAL(eventClosed(Kopete::InfoEvent*)), info, \
SLOT(delayedDestruct()) ); +
+			info->setContact( c );
+			engine()->requestFullInfo( c->contactId() );
+
+			info->setModal( false );
+			info->show();
+		}
+		break;
+	}
 }
 
 #include "icqaccount.moc"
Index: kopete/kopete.notifyrc
===================================================================
--- kopete/kopete.notifyrc	(revision 786234)
+++ kopete/kopete.notifyrc	(working copy)
@@ -975,7 +975,7 @@
 Comment[zh_CN]=您的 Yahoo 收件箱中有新邮件到达
 Comment[zh_HK]=您的 Yahoo 收件匣有新郵件
 Comment[zh_TW]=您的 Yahoo 收件匣中有新郵件
-Action=MessageBox
+Action=Popup
 
 
 [Event/msn_mail]
@@ -1900,3 +1900,10 @@
 Comment[zh_CN]=一位 ICQ 用户正在查阅您的状态信息
 Comment[zh_TW]=有 ICQ 使用者正讀取您的狀態訊息
 Action=Popup
+
+[Event/kopete_info_event]
+Name=Service Message
+Comment=An service message has been received (e.g. authorization request)
+Action=Popup
+Sound=
+
Index: kopete/infoeventwidget.h
===================================================================
--- kopete/infoeventwidget.h	(revision 0)
+++ kopete/infoeventwidget.h	(revision 0)
@@ -0,0 +1,83 @@
+/*
+    infoeventwidget.h - Info Event Widget
+
+    Copyright (c) 2008      by Roman Jarosz          <kedgedev@centrum.cz>
+    Kopete    (c) 2008      by the Kopete developers <kopete-devel@kde.org>
+
+    *************************************************************************
+    *                                                                       *
+    * This library is free software; you can redistribute it and/or         *
+    * modify it under the terms of the GNU Lesser General Public            *
+    * License as published by the Free Software Foundation; either          *
+    * version 2 of the License, or (at your option) any later version.      *
+    *                                                                       *
+    *************************************************************************
+*/
+#ifndef INFOEVENTWIDGET_H
+#define INFOEVENTWIDGET_H
+
+#include <QWidget>
+
+namespace Kopete { class InfoEvent; }
+/**
+ * @author Roman Jarosz <kedgedev@centrum.cz>
+ *
+ * This dialog is used to view info events.
+ */
+class InfoEventWidget : public QWidget
+{
+Q_OBJECT
+public:
+	/**
+	 * Info event widget constructor
+	 */
+	InfoEventWidget( QWidget *parent = 0 );
+
+	~InfoEventWidget();
+
+	virtual void setVisible( bool visible );
+
+Q_SIGNALS:
+	void showRequest();
+
+public Q_SLOTS:
+	/**
+	 * Show previous info event from info event list
+	 */
+	void prevInfoEvent();
+
+	/**
+	 * Show next info event from info event list
+	 */
+	void nextInfoEvent();
+
+	/**
+	 * Close current info event from info event list
+	 * @note Info Event object will be destroyed.
+	 */
+	void closeInfoEvent();
+
+private Q_SLOTS:
+	void slotAnimate( qreal amount );
+
+	void linkClicked( const QString& link );
+
+	/**
+	 * Update widget's buttons and text.
+	 */
+	void updateInfo();
+
+	void eventAdded( Kopete::InfoEvent* event );
+
+	void notificationActivated();
+
+	void notificationClosed();
+
+private:
+	int sizeHintHeight() const;
+
+	class Private;
+	Private *d;
+};
+
+#endif
Index: kopete/kopetewindow.h
===================================================================
--- kopete/kopetewindow.h	(revision 786234)
+++ kopete/kopetewindow.h	(working copy)
@@ -5,7 +5,7 @@
     Copyright (c) 2001-2002 by Stefan Gehn            <metz AT gehn.net>
     Copyright (c) 2002-2003 by Martijn Klingens       <klingens@kde.org>
 
-    Kopete    (c) 2002-2003 by the Kopete developers  <kopete-devel@kde.org>
+    Kopete    (c) 2002-2008 by the Kopete developers  <kopete-devel@kde.org>
 
     *************************************************************************
     *                                                                       *
@@ -176,6 +176,16 @@
 	void slotGlobalStatusMessageIconClicked( const QPoint &position );
 
 	/**
+	 * Show Info Event widget and if necessary raise the Kopete window.
+	 */
+	void slotShowInfoEventWidget();
+
+	/**
+	 * Show/hide Info Event widget.
+	 */
+	void slotInfoIconClicked();
+
+	/**
 	 * Extracts protocolId and accountId from the single QString argument signalled by \
                a QSignalMapper,
 	 * get the account, and call showAddContactDialog.
 	 * @param accountIdentifer QString of protocolId and accountId, concatenated with \
QChar( 0xE000 ) @@ -218,5 +228,22 @@
 
 };
 
+class InfoEventIconLabel : public QLabel
+{
+	Q_OBJECT
+public:
+	InfoEventIconLabel( QWidget *parent = 0 );
+
+protected:
+	void mouseReleaseEvent( QMouseEvent *event );
+
+signals:
+	void clicked();
+
+private slots:
+	void updateIcon();
+
+};
+
 #endif
 // vim: set noet ts=4 sts=4 sw=4:
Index: kopete/CMakeLists.txt
===================================================================
--- kopete/CMakeLists.txt	(revision 786234)
+++ kopete/CMakeLists.txt	(working copy)
@@ -58,11 +58,12 @@
    kopetewindow.cpp 
    kopeteidentitystatusbaricon.cpp 
    kopetedbusinterface.cpp
+   infoeventwidget.cpp
    )
 
 QT4_ADD_DBUS_ADAPTOR(kopete_SRCS org.kde.Kopete.xml kopetedbusinterface.h \
KopeteDBusInterface)  
-kde4_add_ui_files(kopete_SRCS groupkabcselectorwidget.ui )
+kde4_add_ui_files(kopete_SRCS groupkabcselectorwidget.ui infoeventbase.ui )
 
 
 kde4_add_executable(kopete_bin ${kopete_SRCS})
Index: kopete/infoeventwidget.cpp
===================================================================
--- kopete/infoeventwidget.cpp	(revision 0)
+++ kopete/infoeventwidget.cpp	(revision 0)
@@ -0,0 +1,237 @@
+/*
+    infoeventwidget.cpp - Info Event Widget
+
+    Copyright (c) 2008      by Roman Jarosz          <kedgedev@centrum.cz>
+    Kopete    (c) 2008      by the Kopete developers <kopete-devel@kde.org>
+
+    *************************************************************************
+    *                                                                       *
+    * This library is free software; you can redistribute it and/or         *
+    * modify it under the terms of the GNU Lesser General Public            *
+    * License as published by the Free Software Foundation; either          *
+    * version 2 of the License, or (at your option) any later version.      *
+    *                                                                       *
+    *************************************************************************
+*/
+#include "infoeventwidget.h"
+#include "ui_infoeventbase.h"
+
+#include <QPointer>
+#include <QHash>
+#include <QTimeLine>
+#include <QLayout>
+#include <QTextDocument>
+
+#include <knotification.h>
+
+#include <kopeteinfoeventmanager.h>
+#include <kopeteinfoevent.h>
+
+class InfoEventWidget::Private
+{
+public:
+	int currentEvent;
+	QTimeLine *timeline;
+	Ui::InfoEventBase ui;
+	bool enableUpdates;
+	QHash<KNotification*, QPointer<Kopete::InfoEvent> > notifyEventHash;
+};
+
+InfoEventWidget::InfoEventWidget(QWidget *parent)
+: QWidget(parent), d( new Private() )
+{
+	d->timeline = new QTimeLine( 150, this );
+	d->timeline->setCurveShape( QTimeLine::EaseInOutCurve );
+	connect( d->timeline, SIGNAL(valueChanged(qreal)),
+	         this, SLOT(slotAnimate(qreal)) );
+
+	d->ui.setupUi(this);
+	static_cast<KSqueezedTextLabel*>(d->ui.lblTitle)->setTextElideMode( Qt::ElideRight \
); +	d->ui.buttonPrev->setIcon( KIcon( "arrow-left" ) );
+	d->ui.buttonNext->setIcon( KIcon( "arrow-right" ) );
+	d->ui.buttonClose->setIcon( KIcon( "window-close" ) );
+	QWidget::setVisible( false );
+
+	d->currentEvent = 0;
+	d->enableUpdates = false;
+	connect( Kopete::InfoEventManager::self(), SIGNAL(changed()), this, \
SLOT(updateInfo()) ); +	connect( Kopete::InfoEventManager::self(), \
SIGNAL(eventAdded(Kopete::InfoEvent*)), this, SLOT(eventAdded(Kopete::InfoEvent*)) ); \
+	connect( d->ui.lblActions, SIGNAL(linkActivated(const QString&)), this, \
SLOT(linkClicked(const QString&)) ); +	connect( d->ui.buttonPrev, \
SIGNAL(clicked(bool)), this, SLOT(prevInfoEvent()) ); +	connect( d->ui.buttonNext, \
SIGNAL(clicked(bool)), this, SLOT(nextInfoEvent()) ); +	connect( d->ui.buttonClose, \
SIGNAL(clicked(bool)), this, SLOT(closeInfoEvent()) ); +}
+
+
+InfoEventWidget::~InfoEventWidget()
+{
+	delete d;
+}
+
+void InfoEventWidget::setVisible( bool visible )
+{
+	d->enableUpdates = visible;
+	if ( visible )
+		updateInfo();
+
+	// animate the widget disappearing
+	d->timeline->setDirection( visible ?  QTimeLine::Forward
+	                           : QTimeLine::Backward );
+	d->timeline->start();
+}
+
+void InfoEventWidget::prevInfoEvent()
+{
+	if ( d->currentEvent > 0 )
+	{
+		d->currentEvent--;
+		updateInfo();
+	}
+}
+
+void InfoEventWidget::nextInfoEvent()
+{
+	if ( d->currentEvent + 1 < Kopete::InfoEventManager::self()->eventCount() )
+	{
+		d->currentEvent++;
+		updateInfo();
+	}
+}
+
+void InfoEventWidget::closeInfoEvent()
+{
+	Kopete::InfoEvent* event = Kopete::InfoEventManager::self()->event( d->currentEvent \
); +
+	Q_ASSERT( event );
+	event->close();
+}
+
+void InfoEventWidget::slotAnimate( qreal amount )
+{
+	if ( amount == 0 )
+	{
+		QWidget::setVisible( false );
+		return;
+	}
+	
+	if ( amount == 1.0 )
+	{
+		layout()->setSizeConstraint( QLayout::SetDefaultConstraint );
+		setFixedHeight( sizeHintHeight() );
+		return;
+	}
+	
+	setFixedHeight( sizeHintHeight() * amount );
+	
+	if ( !isVisible() )
+		QWidget::setVisible( true );
+}
+
+void InfoEventWidget::linkClicked( const QString& link )
+{
+	Kopete::InfoEvent* event = Kopete::InfoEventManager::self()->event( d->currentEvent \
); +	Q_ASSERT( event );
+
+	event->activate( link.toInt() );
+}
+
+void InfoEventWidget::updateInfo()
+{
+	if ( !d->enableUpdates )
+		return;
+
+	Kopete::InfoEventManager* ie = Kopete::InfoEventManager::self();
+
+	if ( ie->eventCount() == 0 )
+	{
+		d->currentEvent = 0;
+		d->ui.lblInfo->clear();
+		d->ui.lblActions->clear();
+		d->ui.lblTitle->clear();
+		d->ui.lblEvent->setText( "0/0" );
+		d->ui.buttonPrev->setEnabled( false );
+		d->ui.buttonNext->setEnabled( false );
+		d->ui.buttonClose->setEnabled( false );
+		return;
+	}
+
+	if ( d->currentEvent >= ie->eventCount() )
+		d->currentEvent = ie->eventCount() - 1;
+
+	d->ui.buttonClose->setEnabled( true );
+	d->ui.buttonPrev->setEnabled( (d->currentEvent > 0) );
+	d->ui.buttonNext->setEnabled( (d->currentEvent + 1 < ie->eventCount()) );
+
+	const Kopete::InfoEvent* event = ie->event( d->currentEvent );
+	Q_ASSERT( event );
+
+	static_cast<KSqueezedTextLabel*>(d->ui.lblTitle)->setText( Qt::escape( \
event->title() ) ); +	d->ui.lblEvent->setText( QString("%1/%2").arg( d->currentEvent \
+ 1 ).arg( ie->eventCount() ) ); +
+	QString text = QString( "<p>%1</p>" ).arg( event->text() );
+	if ( !event->additionalText().isEmpty() )
+		text += QString( "<p>%1</p>" ).arg( event->additionalText() );
+
+	d->ui.lblInfo->setText( text );
+
+	QString linkCode = QString::fromLatin1( "<p align=\"right\">" );
+
+	QMap<uint, QString> actions = event->actions();
+	QMapIterator<uint, QString> it(actions);
+	while ( it.hasNext() )
+	{
+		it.next();
+		linkCode += QString::fromLatin1( "<a href=\"%1\">%2</a> " ).arg( it.key() ).arg( \
Qt::escape(it.value()) ); +	}
+
+	d->ui.lblActions->setText( linkCode );
+
+	// Redo the layout otherwise sizeHint() won't be correct.
+	layout()->activate();
+	if ( sizeHintHeight() > height() )
+		setFixedHeight( sizeHintHeight() );
+}
+
+void InfoEventWidget::eventAdded( Kopete::InfoEvent* event )
+{
+	KNotification *notify = new KNotification( QString("kopete_info_event") , 0l );
+	notify->setActions( QStringList( i18n( "View" ) ) );
+	notify->setText( event->text() );
+
+	d->notifyEventHash.insert( notify, event );
+
+	connect( notify, SIGNAL(activated(unsigned int)), this, \
SLOT(notificationActivated()) ); +	connect( notify, SIGNAL(closed()), this, \
SLOT(notificationClosed()) ); +
+	notify->sendEvent();
+}
+
+void InfoEventWidget::notificationActivated()
+{
+	KNotification *notify = dynamic_cast<KNotification *>(sender());
+
+	Kopete::InfoEvent* event = d->notifyEventHash.value( notify, 0 );
+	if ( !event )
+		return;
+
+	int index = Kopete::InfoEventManager::self()->events().indexOf( event );
+	if ( index != -1 )
+	{
+		d->currentEvent = index;
+		updateInfo();
+	}
+	emit showRequest();
+}
+
+void InfoEventWidget::notificationClosed()
+{
+	KNotification *notify = dynamic_cast<KNotification *>(sender());
+	d->notifyEventHash.remove( notify );
+}
+
+int InfoEventWidget::sizeHintHeight() const
+{
+	return qMin( sizeHint().height(), 250 );
+}
+
+#include "infoeventwidget.moc"
Index: kopete/kopetewindow.cpp
===================================================================
--- kopete/kopetewindow.cpp	(revision 786234)
+++ kopete/kopetewindow.cpp	(working copy)
@@ -98,6 +98,8 @@
 #include "kopetestatusrootaction.h"
 #include "kopetestatuseditaction.h"
 #include "kopeteemoticons.h"
+#include "kopeteinfoeventmanager.h"
+#include "infoeventwidget.h"
 
 
 //BEGIN GlobalStatusMessageIconLabel
@@ -116,11 +118,41 @@
 }
 //END GlobalStatusMessageIconLabel
 
+//BEGIN InfoEventIconLabel
+InfoEventIconLabel::InfoEventIconLabel( QWidget *parent )
+: QLabel( parent )
+{
+	setCursor( QCursor( Qt::PointingHandCursor ) );
+	setFixedSize( 16, 16 );
+	setPixmap( SmallIcon( "flag-black" ) );
+	setToolTip( i18n( "Service messages" ) );
+	
+	connect( Kopete::InfoEventManager::self(), SIGNAL(changed()), this, \
SLOT(updateIcon()) ); +}
+
+void InfoEventIconLabel::mouseReleaseEvent( QMouseEvent *event )
+{
+	if ( event->button() == Qt::LeftButton || event->button() == Qt::RightButton )
+	{
+		emit clicked();
+		event->accept();
+	}
+}
+
+void InfoEventIconLabel::updateIcon()
+{
+	if ( Kopete::InfoEventManager::self()->eventCount() > 0 )
+		setPixmap( SmallIcon( "flag-green" ) );
+	else
+		setPixmap( SmallIcon( "flag-black" ) );
+}
+//END InfoEventIconLabel
+
 class KopeteWindow::Private
 {
 	public:
 		Private()
-				: contactlist ( 0 ), identitywidget ( 0 ), actionAddContact ( 0 ), \
actionDisconnect ( 0 ), +				: contactlist ( 0 ), identitywidget ( 0 ), \
                infoEventWidget ( 0 ), actionAddContact ( 0 ), actionDisconnect ( 0 \
                ),
 				actionExportContacts ( 0 ), actionStatusMenu ( 0 ), actionDockMenu ( 0 ), \
                actionSetAway ( 0 ),
 				actionSetBusy ( 0 ), actionSetAvailable ( 0 ), actionSetInvisible ( 0 ), \
                actionPrefs ( 0 ),
 				actionQuit ( 0 ), actionSave ( 0 ), menubarAction ( 0 ), statusbarAction ( 0 ),
@@ -136,6 +168,7 @@
 		KopeteContactListView *contactlist;
 
 		IdentityStatusWidget *identitywidget;
+		InfoEventWidget *infoEventWidget;
 
 		// Some Actions
 		KActionMenu *actionAddContact;
@@ -230,6 +263,12 @@
 	label->setToolTip ( i18n ( "Global status message" ) );
 	statusBarMessageLayout->addWidget ( label );
 	statusBarMessageLayout->addSpacing ( 1 );
+
+	InfoEventIconLabel *infoLabel = new InfoEventIconLabel ( statusBarMessage );
+	connect ( infoLabel, SIGNAL(clicked()), this, SLOT(slotInfoIconClicked()) );
+	statusBarMessageLayout->addWidget ( infoLabel );
+	statusBarMessageLayout->addSpacing ( 1 );
+
 	d->globalStatusMessage = new KSqueezedTextLabel ( statusBarMessage );
 	connect ( Kopete::StatusManager::self(), SIGNAL ( globalStatusChanged() ),
 	          this, SLOT ( globalStatusChanged() ) );
@@ -309,7 +348,12 @@
 	d->identitywidget->setSizePolicy ( QSizePolicy ( QSizePolicy::Preferred, \
QSizePolicy::Minimum ) );  d->identitywidget->setVisible ( false );
 	l->addWidget ( d->identitywidget );
-
+	d->infoEventWidget = new InfoEventWidget ( w );
+	d->infoEventWidget->setSizePolicy ( QSizePolicy ( QSizePolicy::Preferred, \
QSizePolicy::Minimum ) ); +	d->infoEventWidget->setVisible ( false );
+	connect ( d->infoEventWidget, SIGNAL(showRequest()), this, \
SLOT(slotShowInfoEventWidget()) ); +	l->addWidget ( d->infoEventWidget );
+	
 	setCentralWidget ( w );
 	d->contactlist->setFocus();
 }
@@ -874,11 +918,45 @@
 		return;
 	}
 
+	if ( d->infoEventWidget->isVisible() )
+		d->infoEventWidget->setVisible ( false );
+
 	d->identitywidget->setIdentity ( identity );
 	d->identitywidget->setVisible ( true );
 }
 
+void KopeteWindow::slotShowInfoEventWidget()
+{
+	if ( d->identitywidget->isVisible() )
+	{
+		d->identitywidget->setIdentity( 0 );
+		d->identitywidget->setVisible( false );
+	}
 
+	if ( !d->infoEventWidget->isVisible() )
+		d->infoEventWidget->setVisible( true );
+
+	if ( !isActiveWindow() )
+		slotShowHide();
+}
+
+void KopeteWindow::slotInfoIconClicked()
+{
+	if ( d->infoEventWidget->isVisible() )
+	{
+		d->infoEventWidget->setVisible( false );
+	}
+	else
+	{
+		if ( d->identitywidget->isVisible() )
+		{
+			d->identitywidget->setIdentity( 0 );
+			d->identitywidget->setVisible( false );
+		}
+		d->infoEventWidget->setVisible( true );
+	}
+}
+
 void KopeteWindow::slotAccountRegistered ( Kopete::Account *account )
 {
 
Index: kopete/infoeventbase.ui
===================================================================
--- kopete/infoeventbase.ui	(revision 0)
+++ kopete/infoeventbase.ui	(revision 0)
@@ -0,0 +1,90 @@
+<ui version="4.0" >
+ <class>InfoEventBase</class>
+ <widget class="QWidget" name="InfoEventBase" >
+  <property name="geometry" >
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>273</width>
+    <height>122</height>
+   </rect>
+  </property>
+  <layout class="QVBoxLayout" >
+   <item>
+    <layout class="QHBoxLayout" >
+     <item>
+      <layout class="QHBoxLayout" >
+       <property name="spacing" >
+        <number>2</number>
+       </property>
+       <item>
+        <widget class="QToolButton" name="buttonPrev" />
+       </item>
+       <item>
+        <widget class="QLabel" name="lblEvent" >
+         <property name="text" >
+          <string/>
+         </property>
+        </widget>
+       </item>
+       <item>
+        <widget class="QToolButton" name="buttonNext" />
+       </item>
+      </layout>
+     </item>
+     <item>
+      <widget class="KSqueezedTextLabel" name="lblTitle" >
+       <property name="sizePolicy" >
+        <sizepolicy vsizetype="Preferred" hsizetype="Expanding" >
+         <horstretch>0</horstretch>
+         <verstretch>0</verstretch>
+        </sizepolicy>
+       </property>
+       <property name="alignment" >
+        <set>Qt::AlignCenter</set>
+       </property>
+      </widget>
+     </item>
+     <item>
+      <widget class="QToolButton" name="buttonClose" />
+     </item>
+    </layout>
+   </item>
+   <item>
+    <widget class="QLabel" name="lblInfo" >
+     <property name="sizePolicy" >
+      <sizepolicy vsizetype="Preferred" hsizetype="Ignored" >
+       <horstretch>0</horstretch>
+       <verstretch>1</verstretch>
+      </sizepolicy>
+     </property>
+     <property name="text" >
+      <string/>
+     </property>
+     <property name="alignment" >
+      <set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
+     </property>
+     <property name="wordWrap" >
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+   <item>
+    <widget class="QLabel" name="lblActions" >
+     <property name="wordWrap" >
+      <bool>true</bool>
+     </property>
+    </widget>
+   </item>
+  </layout>
+ </widget>
+ <customwidgets>
+  <customwidget>
+   <class>KSqueezedTextLabel</class>
+   <extends>QLabel</extends>
+   <header location="global" >ksqueezedtextlabel.h</header>
+  </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
Index: libkopete/kopeteinfoeventmanager.cpp
===================================================================
--- libkopete/kopeteinfoeventmanager.cpp	(revision 0)
+++ libkopete/kopeteinfoeventmanager.cpp	(revision 0)
@@ -0,0 +1,83 @@
+/*
+    kopeteinfoeventmanager.cpp - Kopete Info Event Manager
+
+    Copyright (c) 2008      by Roman Jarosz          <kedgedev@centrum.cz>
+    Kopete    (c) 2008      by the Kopete developers <kopete-devel@kde.org>
+
+    *************************************************************************
+    *                                                                       *
+    * This library is free software; you can redistribute it and/or         *
+    * modify it under the terms of the GNU Lesser General Public            *
+    * License as published by the Free Software Foundation; either          *
+    * version 2 of the License, or (at your option) any later version.      *
+    *                                                                       *
+    *************************************************************************
+*/
+#include "kopeteinfoeventmanager.h"
+#include "kopeteinfoevent.h"
+
+#include <QStringList>
+
+namespace Kopete {
+
+class InfoEventManager::Private
+{
+public:
+	QList<InfoEvent*> eventList;
+};
+
+InfoEventManager *InfoEventManager::instance = 0L;
+
+InfoEventManager::InfoEventManager()
+ : QObject(), d( new Private )
+{
+}
+
+
+InfoEventManager::~InfoEventManager()
+{
+	delete d;
+}
+
+InfoEventManager *InfoEventManager::self()
+{
+	if ( !instance )
+		instance = new InfoEventManager;
+	
+	return instance;
+}
+
+void InfoEventManager::addEvent( Kopete::InfoEvent* event )
+{
+	connect( event, SIGNAL(eventClosed(Kopete::InfoEvent*)),
+	         this, SLOT(eventClosed(Kopete::InfoEvent*)) );
+
+	d->eventList.append( event );
+	emit eventAdded( event );
+	emit changed();
+}
+
+QList<InfoEvent*> InfoEventManager::events() const
+{
+	return d->eventList;
+}
+
+int InfoEventManager::eventCount() const
+{
+	return d->eventList.count();
+}
+
+Kopete::InfoEvent* InfoEventManager::event( int i ) const
+{
+	return d->eventList.at( i );
+}
+
+void InfoEventManager::eventClosed( Kopete::InfoEvent* event )
+{
+	d->eventList.removeAll( event );
+	emit changed();
+}
+
+}
+
+#include "kopeteinfoeventmanager.moc"
Index: libkopete/events/kopeteaddedinfoevent.cpp
===================================================================
--- libkopete/events/kopeteaddedinfoevent.cpp	(revision 0)
+++ libkopete/events/kopeteaddedinfoevent.cpp	(revision 0)
@@ -0,0 +1,173 @@
+/*
+    kopeteaddedinfoevent.cpp - Kopete Added Info Event
+
+    Copyright (c) 2008      by Roman Jarosz          <kedgedev@centrum.cz>
+    Kopete    (c) 2008      by the Kopete developers <kopete-devel@kde.org>
+
+    *************************************************************************
+    *                                                                       *
+    * This library is free software; you can redistribute it and/or         *
+    * modify it under the terms of the GNU Lesser General Public            *
+    * License as published by the Free Software Foundation; either          *
+    * version 2 of the License, or (at your option) any later version.      *
+    *                                                                       *
+    *************************************************************************
+*/
+#include "kopeteaddedinfoevent.h"
+
+#include <klocale.h>
+#include <kdebug.h>
+
+#include "kopeteaccount.h"
+#include "kopeteprotocol.h"
+#include "ui/contactaddednotifydialog.h"
+
+namespace Kopete {
+
+class AddedInfoEvent::Private
+{
+public:
+	QString contactId;
+	Kopete::Account *account;
+	ShowActionOptions actions;
+
+	QString contactNickname;
+
+	bool suppressClose;
+	UI::ContactAddedNotifyDialog* addDialog;
+};
+
+AddedInfoEvent::AddedInfoEvent( const QString& contactId, Kopete::Account *account )
+	: InfoEvent(account), d( new Private() )
+{
+	d->suppressClose = false;
+	d->addDialog = 0;
+	d->contactId = contactId;
+	d->account = account;
+	d->actions = AllActions;
+}
+
+AddedInfoEvent::~AddedInfoEvent()
+{
+	if( d->addDialog )
+		d->addDialog->deleteLater();
+
+	delete d;
+}
+
+QString AddedInfoEvent::contactId() const
+{
+	return d->contactId;
+}
+
+Kopete::Account* AddedInfoEvent::account() const
+{
+	return d->account;
+}
+
+void AddedInfoEvent::showActions( ShowActionOptions actions )
+{
+	d->actions = actions;
+}
+
+void AddedInfoEvent::setContactNickname( const QString& nickname )
+{
+	d->contactNickname = nickname;
+}
+
+void AddedInfoEvent::activate( uint actionId )
+{
+	if ( actionId == AddAction )
+	{
+		if ( d->addDialog )
+		{
+			d->addDialog->raise();
+		}
+		else
+		{
+			UI::ContactAddedNotifyDialog::HideWidgetOptions hideFlags = \
UI::ContactAddedNotifyDialog::DefaultHide; +			if ( !(d->actions & AuthorizeAction) )
+				hideFlags |= UI::ContactAddedNotifyDialog::AuthorizeCheckBox;
+			if ( !(d->actions & InfoAction) )
+				hideFlags |= UI::ContactAddedNotifyDialog::InfoButton;
+
+			d->addDialog = new UI::ContactAddedNotifyDialog( d->contactId, \
d->contactNickname, d->account, hideFlags ); +			d->addDialog->setAttribute( \
Qt::WA_DeleteOnClose, false ); +
+			connect( d->addDialog, SIGNAL(finished()), this, SLOT(addDialogFinished()) );
+			connect( d->addDialog, SIGNAL(applyClicked(const QString&)), this, \
SLOT(addDialogOk()) ); +			d->addDialog->show();
+		}
+	}
+	else
+	{
+		InfoEvent::activate( actionId );
+
+		if ( !d->suppressClose && actionId != InfoAction && d->account->isConnected() )
+			close();
+	}
+}
+
+MetaContact* AddedInfoEvent::addContact() const
+{
+	if( !d->addDialog )
+		return 0L;
+
+	return d->addDialog->addContact();
+}
+
+void AddedInfoEvent::sendEvent()
+{
+	setTitle( i18n( "You have been added" ) );
+
+	if ( d->actions & AddAction )
+		addAction( AddAction, i18n("Add...") );
+	if ( d->actions & AuthorizeAction )
+		addAction( AuthorizeAction, i18n("Authorize") );
+	if ( d->actions & BlockAction )
+		addAction( BlockAction, i18n("Block") );
+	if ( d->actions & InfoAction )
+		addAction( InfoAction, i18n("Info...") );
+
+	setText( i18n( "The contact <b>%1</b> has added you to his/her contact list.",
+	               ( d->contactNickname.isEmpty() ) ? d->contactId : d->contactNickname \
) ); +
+	InfoEvent::sendEvent();
+}
+
+void AddedInfoEvent::addDialogOk()
+{
+	kDebug();
+	if( !d->addDialog )
+		return;
+
+	d->suppressClose = true;
+	if ( d->addDialog->authorized() )
+		activate( AuthorizeAction );
+
+
+	if ( d->addDialog->added() )
+		activate( AddContactAction );
+
+	if ( d->account->isConnected() )
+		close();
+}
+
+void AddedInfoEvent::addDialogInfo()
+{
+	activate( InfoAction );
+}
+
+void AddedInfoEvent::addDialogFinished()
+{
+	kDebug();
+	if( d->addDialog )
+	{
+		d->addDialog->deleteLater();
+		d->addDialog = 0;
+	}
+}
+
+}
+
+#include "kopeteaddedinfoevent.moc"
Index: libkopete/events/kopeteaddedinfoevent.h
===================================================================
--- libkopete/events/kopeteaddedinfoevent.h	(revision 0)
+++ libkopete/events/kopeteaddedinfoevent.h	(revision 0)
@@ -0,0 +1,156 @@
+/*
+    kopeteaddedinfoevent.h - Kopete Added Info Event
+
+    Copyright (c) 2008      by Roman Jarosz          <kedgedev@centrum.cz>
+    Kopete    (c) 2008      by the Kopete developers <kopete-devel@kde.org>
+
+    *************************************************************************
+    *                                                                       *
+    * This library is free software; you can redistribute it and/or         *
+    * modify it under the terms of the GNU Lesser General Public            *
+    * License as published by the Free Software Foundation; either          *
+    * version 2 of the License, or (at your option) any later version.      *
+    *                                                                       *
+    *************************************************************************
+*/
+#ifndef KOPETEADDEDINFOEVENT_H
+#define KOPETEADDEDINFOEVENT_H
+
+#include "kopeteinfoevent.h"
+
+namespace Kopete {
+
+class MetaContact;
+class Account;
+/**
+ * @brief Event which is shown when a contact added you into the contact list or \
requested authorization. + *
+ * This event allows the user to give authorization for the addition to the
+ * person who added the user and also allows the user to add the person into
+ * the user's contact list.
+ *
+ * The @p title() and @p text() will be filled with predefined text.
+ * If you want to add additional information use @p setAdditionalText()
+ *
+ * example of usage
+ * @code
+	Kopete::AddedInfoEvent* event = new Kopete::AddedInfoEvent( contactId, account );
+	QObject::connect( event, SIGNAL(actionActivated(uint)), this, \
SLOT(addedInfoEventActionActivated(uint)) ); +	event->sendEvent();
+ * @endcode
+ *
+ * and in your addedInfoEventActionActivated slot
+ * @code
+	Kopete::AddedInfoEvent *event = dynamic_cast<Kopete::AddedInfoEvent *>(sender());
+	if ( !event )
+		return;
+	
+	switch ( actionId )
+	{
+	case Kopete::AddedInfoEvent::AddContactAction:
+		event->addContact();
+		break;
+	case Kopete::AddedInfoEvent::AuthorizeAction:
+		socket->authorize( event->contactId() );
+		break;
+	case Kopete::AddedInfoEvent::InfoAction:
+		showInfo();
+		break;
+	}
+ * @endcode
+ *
+ * @author Roman Jarosz <kedgedev@centrum.cz>
+ */
+class KOPETE_EXPORT AddedInfoEvent : public InfoEvent
+{
+	Q_OBJECT
+public:
+	/**
+	 * All actions that may be shown and emitted.
+	 */
+	enum ShowAction
+	{
+		AddAction = 0x001, /** Add action was activated. The default implementation shows
+		                       ContactAddedNotifyDialog if activate(uint) isn't replaced \
*/ +		AuthorizeAction = 0x002, /** You should authorize the contact */
+		BlockAction = 0x004, /** You should block this and future requests */
+		InfoAction = 0x008, /** You should show info about contact */
+
+		AddContactAction = 0x100, /** You should add contact to Kopete contact list with \
@p addContact() +		                              this is only emitted if \
activate(uint) isn't replaced */ +		AllActions = 0x00F
+	};
+	Q_DECLARE_FLAGS(ShowActionOptions, ShowAction)
+
+	/**
+	 * @brief Constructor
+	 *
+	 * @param contactId the contactId of the contact which has added you
+	 * @param account the account which has generated this event
+	 */
+	AddedInfoEvent( const QString& contactId, Kopete::Account *account );
+
+	~AddedInfoEvent();
+
+	/**
+	 * Return the contactId of a contact which has added you.
+	 */
+	QString contactId() const;
+
+	/**
+	 * Return the account that has generated this event.
+	 */
+	Kopete::Account* account() const;
+
+	/**
+	 * Set which actions should be shown.
+	 *
+	 * @param actions a bitmask of ShowAction used to show specific actions.
+	 * @note by default everything is shown.
+	 */
+	void showActions( ShowActionOptions actions );
+
+	/**
+	 * Set contact nickname
+	 *
+	 * @param nickname the nickname of the contact.
+	 */
+	void setContactNickname( const QString& nickname );
+
+	/**
+	 * @brief create a metacontact.
+	 *
+	 * This function only works if the AddContactAction action was activated, otherwise
+	 * it will return 0L.
+	 *
+	 * it uses the Account::addContact function to add the contact
+	 *
+	 * @return the new metacontact created, or 0L if the operation failed.
+	 */
+	MetaContact* addContact() const;
+
+public Q_SLOTS:
+	/**
+	 * Activate the action specified action
+	 */
+	virtual void activate( uint actionId );
+
+	/**
+	 * Emit the event.
+	 */
+	virtual void sendEvent();
+
+private Q_SLOTS:
+	void addDialogOk();
+	void addDialogInfo();
+	void addDialogFinished();
+
+private:
+	class Private;
+	Private *d;
+};
+Q_DECLARE_OPERATORS_FOR_FLAGS( AddedInfoEvent::ShowActionOptions )
+
+}
+
+#endif
Index: libkopete/kopeteinfoeventmanager.h
===================================================================
--- libkopete/kopeteinfoeventmanager.h	(revision 0)
+++ libkopete/kopeteinfoeventmanager.h	(revision 0)
@@ -0,0 +1,98 @@
+/*
+    kopeteinfoeventmanager.h - Kopete Info Event Manager
+
+    Copyright (c) 2008      by Roman Jarosz          <kedgedev@centrum.cz>
+    Kopete    (c) 2008      by the Kopete developers <kopete-devel@kde.org>
+
+    *************************************************************************
+    *                                                                       *
+    * This library is free software; you can redistribute it and/or         *
+    * modify it under the terms of the GNU Lesser General Public            *
+    * License as published by the Free Software Foundation; either          *
+    * version 2 of the License, or (at your option) any later version.      *
+    *                                                                       *
+    *************************************************************************
+*/
+#ifndef KOPETEINFOEVENTMANAGER_H
+#define KOPETEINFOEVENTMANAGER_H
+
+#include <QObject>
+#include "kopete_export.h"
+
+namespace Kopete {
+
+class InfoEvent;
+
+/**
+ * The Info Event Manager that contains all info event items
+ *
+ * All info event items that are in Info Event Manager will be shown in
+ * non-intrusive way to a user in Kopete Main Window.
+ *
+ * @author Roman Jarosz <kedgedev@centrum.cz>
+ */
+class KOPETE_EXPORT InfoEventManager : public QObject
+{
+Q_OBJECT
+public:
+	/**
+	 * The Info Event Manager is a singleton class of which only a single
+	 * instance will exist. If no manager exists yet this function will
+	 * create one for you.
+	 *
+	 * @return the instance of the InfoEventManager
+	 */
+	static InfoEventManager *self();
+
+	~InfoEventManager();
+
+	/**
+	 * Return all info events that are in the InfoEventManager.
+	 */
+	QList<InfoEvent*> events() const;
+
+	/**
+	 * Return number of info event items in the InfoEventManager.
+	 */
+	int eventCount() const;
+
+	/**
+	 * Return the info event at index position @p i in the InfoEventManager.
+	 */
+	Kopete::InfoEvent* event( int i ) const;
+
+Q_SIGNALS:
+	/**
+	 * Emitted when the info event items in InfoEventManager has been changed.
+	 */
+	void changed();
+
+	/**
+	 * Emitted when new info event item is added into the InfoEventManager.
+	 */
+	void eventAdded( Kopete::InfoEvent* event );
+
+protected:
+	friend class InfoEvent;
+	/**
+	 * Add info event
+	 *
+	 * @param event the Info Event that will be added into InfoEventManager
+	 */
+	void addEvent( Kopete::InfoEvent* event );
+
+private Q_SLOTS:
+	void eventClosed( Kopete::InfoEvent* event );
+
+private:
+	InfoEventManager();
+
+	static InfoEventManager *instance;
+
+	class Private;
+	Private *d;
+};
+
+}
+
+#endif
Index: libkopete/kopeteinfoevent.h
===================================================================
--- libkopete/kopeteinfoevent.h	(revision 0)
+++ libkopete/kopeteinfoevent.h	(revision 0)
@@ -0,0 +1,138 @@
+/*
+    kopeteinfoevent.h - Kopete Info Event
+
+    Copyright (c) 2008      by Roman Jarosz          <kedgedev@centrum.cz>
+    Kopete    (c) 2008      by the Kopete developers <kopete-devel@kde.org>
+
+    *************************************************************************
+    *                                                                       *
+    * This library is free software; you can redistribute it and/or         *
+    * modify it under the terms of the GNU Lesser General Public            *
+    * License as published by the Free Software Foundation; either          *
+    * version 2 of the License, or (at your option) any later version.      *
+    *                                                                       *
+    *************************************************************************
+*/
+#ifndef KOPETEINFOEVENT_H
+#define KOPETEINFOEVENT_H
+
+#include <QObject>
+#include <QMap>
+
+#include "kopete_export.h"
+
+namespace Kopete {
+
+/**
+ * Base class for all Info Events
+ *
+ * The info event will be shown in non-intrusive way
+ * to user in Kopete Main Window.
+ *
+ * You have to use sendEvent to show the event.
+ *
+ * The pointer is automatically deleted when the event is closed.
+ *
+ *	@author Roman Jarosz <kedgedev@centrum.cz>
+ */
+class KOPETE_EXPORT InfoEvent : public QObject
+{
+Q_OBJECT
+public:
+	InfoEvent( QObject *parent = 0 );
+
+	~InfoEvent();
+
+	/**
+	 * @return the Info Event title
+	 */
+	QString title() const;
+
+	/**
+	 * Set the Info Event title.
+	 * @param title the title
+	 */
+	void setTitle( const QString& title );
+
+	/**
+	 * @return the Info Event text
+	 */
+	QString text() const;
+
+	/**
+	 * Set the Info Event text.
+	 *
+	 * The text is shown in a QLabel, you should make sure to escape any html that is \
needed. +	 * You can use some of the qt basic html tags.
+	 *
+	 * This text will also be shown in KNotification popup
+	 *
+	 * @param text the text
+	 */
+	void setText( const QString& text );
+
+	/**
+	 * @return the additional text
+	 */
+	QString additionalText() const;
+
+	/**
+	 * Set the additional text.
+	 *
+	 * This is only shown in InfoEditWidget
+	 *
+	 * @param text the additional text
+	 */
+	void setAdditionalText( const QString& text );
+
+	/**
+	 * @return the list of actions
+	 */
+	QMap<uint, QString> actions() const;
+
+	/**
+	 * Set the list of actions link.
+	 * @param actions the list of actions
+	 */
+	void addAction( uint actionId, const QString& actionText );
+
+public Q_SLOTS:
+	/**
+	 * Emit the event.
+	 */
+	virtual void sendEvent();
+
+	/**
+	 * Activate the action specified action
+	 */
+	virtual void activate( uint actionId );
+
+	/**
+	 * Close the info event.
+	 *
+	 * This will delete the info event.
+	 */
+	void close();
+
+Q_SIGNALS:
+	/**
+	 * A action has been activated. This signal is only emitted if
+	 * activate( uint ) is not replaced.
+	 * @param actionId is the id of the activated action.
+	 */
+	void actionActivated( uint actionId );
+	
+	/**
+	 * Emitted when the info event is closed.
+	 */
+	void eventClosed( Kopete::InfoEvent* event );
+
+private:
+	class Private;
+	Private *d;
+
+};
+
+}
+
+#endif
Index: libkopete/kopeteinfoevent.cpp
===================================================================
--- libkopete/kopeteinfoevent.cpp	(revision 0)
+++ libkopete/kopeteinfoevent.cpp	(revision 0)
@@ -0,0 +1,115 @@
+/*
+    kopeteinfoevent.cpp - Kopete Info Event
+
+    Copyright (c) 2008      by Roman Jarosz          <kedgedev@centrum.cz>
+    Kopete    (c) 2008      by the Kopete developers <kopete-devel@kde.org>
+
+    *************************************************************************
+    *                                                                       *
+    * This library is free software; you can redistribute it and/or         *
+    * modify it under the terms of the GNU Lesser General Public            *
+    * License as published by the Free Software Foundation; either          *
+    * version 2 of the License, or (at your option) any later version.      *
+    *                                                                       *
+    *************************************************************************
+*/
+#include "kopeteinfoevent.h"
+#include "kopeteinfoeventmanager.h"
+
+#include <QStringList>
+
+#include <kdebug.h>
+
+namespace Kopete {
+
+class InfoEvent::Private
+{
+public:
+	QMap<uint, QString> actions;
+	QString title;
+	QString text;
+	QString additionalText;
+	bool closed;
+};
+
+InfoEvent::InfoEvent( QObject *parent )
+ : QObject( parent ), d( new Private )
+{
+	d->closed = false;
+}
+
+InfoEvent::~InfoEvent()
+{
+	if ( !d->closed )
+		emit eventClosed( this );
+
+	delete d;
+}
+
+void InfoEvent::sendEvent()
+{
+	InfoEventManager::self()->addEvent( this );
+}
+
+QString InfoEvent::title() const
+{
+	return d->title;
+}
+
+void InfoEvent::setTitle( const QString& title )
+{
+	d->title = title;
+}
+
+QString InfoEvent::text() const
+{
+	return d->text;
+}
+
+void InfoEvent::setText( const QString& text )
+{
+	d->text = text;
+}
+
+QString InfoEvent::additionalText() const
+{
+	return d->additionalText;
+}
+
+void InfoEvent::setAdditionalText( const QString& text )
+{
+	d->additionalText = text;
+}
+
+QMap<uint, QString> InfoEvent::actions() const
+{
+	return d->actions;
+}
+
+void InfoEvent::addAction( uint actionId, const QString& actionText )
+{
+	d->actions[actionId] = actionText;
+}
+
+void InfoEvent::activate( uint actionId )
+{
+	emit actionActivated( actionId );
+}
+
+void InfoEvent::close()
+{
+	kDebug();
+	if ( d->closed )
+	{
+		kDebug() << "Closing more the once!!!";
+		return;
+	}
+
+	d->closed = true;
+	emit eventClosed( this );
+	deleteLater();
+}
+
+}
+
+#include "kopeteinfoevent.moc"
Index: libkopete/CMakeLists.txt
===================================================================
--- libkopete/CMakeLists.txt	(revision 786234)
+++ libkopete/CMakeLists.txt	(working copy)
@@ -53,11 +53,16 @@
   tasks/kopetedeletecontacttask.cpp
 )
 
+set(kopete_events_SRCS
+  events/kopeteaddedinfoevent.cpp
+)
+
 set(kopete_LIB_SRCS
    ${kopete_private_SRCS}
    ${kopete_ui_SRCS}
    ${kopete_contactlist_SRCS}
    ${kopete_tasks_SRCS}
+   ${kopete_events_SRCS}
    kabcpersistence.cpp
    kopeteaccount.cpp
    kopeteaccountmanager.cpp
@@ -103,6 +108,8 @@
    kopetestatusmanager.cpp
    kopetestatusitems.cpp
    kopeteidletimer.cpp
+   kopeteinfoeventmanager.cpp
+   kopeteinfoevent.cpp
 # REMOVED FOR NOW
 #   connectionmanager.cpp
 #   managedconnectionaccount.cpp



_______________________________________________
kopete-devel mailing list
kopete-devel@kde.org
https://mail.kde.org/mailman/listinfo/kopete-devel


[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic