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

List:       kopete-devel
Subject:    [Kopete-devel] patch, and other stuff
From:       Andres Krapf <dae () chez ! com>
Date:       2002-05-04 10:47:59
[Download RAW message or body]

i've noticed some activity in the KMM cvs branch. while this is good, there 
still is no solution to address the sendMsg problem with KMMs. i liked 
Martijn solution of having a KopeteProtocol::sendMessage(KopeteMessage&). 
it's a method that has no real reason of being a slot (maybe there are, i 
just fail to see them...).

there was also the appendMessage that the plugins have to call after a 
successful send. i've implemented my KopeteMessage::done() scheme to solve 
this. the thing i don't like about it is that a signal can't be a const, so 
the method emitting a signal can't be a const, which means we have to pass 
KopeteMessage& instead of const KopeteMessage& to the plugin. too bad... but 
KopeteMessage has only private data and no mutators, so it's not a big 
problem.

the other solution would be for the protocol to emit a "sendSuccess" message 
of some sort, but then each KMM would receive it. that's not good, we want 
only the one KMM issuing the send to receive the ACK.

if nobody else has better ideas/code, the patch is attached... it'll imply 
that plugin writers will have to change 4 things:
 - reimplement the KopeteProtocol::sendMessage method (basically, they just 
copy whatever slot they used to receive the messageSent signal from KMM)
 - change the signature of it from slot(const KopeteMessage) to 
slot(KopeteMessage&).
 - replace the KMM::appendMessage by a call to message.done() on successful 
sending over the wire.
 - change the call to sessionFactory()->create, adding a KopeteProtocol 
pointer.

not too difficult... (i've also thrown in an overloaded KMMFactory::create 
method for conveniance, to use with one-to-one chat)

the patch also fixes a few issues with KMM QT event handling. (attaching to 
shown() is not a good way to handle canceling the event. example follows:
 - chatwindow is displayed
 - message arrives, creates a new event (which shows a balloon or whatever)
 - user changes to next desktop and back
 - shown() is called because the chatwindow is displayed once again, so the 
event gets cancelled
BUT, the user never saw the new message... it was never displayed)

i also had an occasional sigSEGV inside cancelUnreadMessageEvent, in the 
delete line. seems impossible, haven't figured that one out yet.... though, i 
have a gut feeling it's related to the issue above.

about the AIM plugin:
ok, i've got it KMMified... yes, it does it's contact bookkeeping, and i've 
changed a few other things, but i first want the libkopete issues solved 
before i send you the patch.

the attached patch is against latest KMM branch.

cheers,

-- 
Andres
["kmmbranch.patch" (text/x-diff)]

? ui/chatview.loT
Index: kopetemessage.cpp
===================================================================
RCS file: /home/kde/kdenonbeta/kopete/libkopete/kopetemessage.cpp,v
retrieving revision 1.4.2.3
diff -u -r1.4.2.3 kopetemessage.cpp
--- kopetemessage.cpp	1 May 2002 02:40:48 -0000	1.4.2.3
+++ kopetemessage.cpp	4 May 2002 10:40:03 -0000
@@ -15,6 +15,7 @@
 */
 
 #include "kopetemessage.h"
+#include "kopetemessage.moc"
 
 KopeteMessage::KopeteMessage()
 {
@@ -49,6 +50,17 @@
 	mBg = bg;
 	mFg = fg;
 	mFont = fnt;
+}
+
+KopeteMessage::KopeteMessage(const KopeteMessage& kopeteMessage) {
+	mTimestamp = kopeteMessage.mTimestamp;
+	mFrom = kopeteMessage.mFrom;
+	mTo = kopeteMessage.mTo;
+	mBody = kopeteMessage.mBody;
+	mDirection = kopeteMessage.mDirection;
+	mBg = kopeteMessage.mBg;
+	mFg = kopeteMessage.mFg;
+	mFont = kopeteMessage.mFont;
 }
 
 // vim: set noet ts=4 sts=4 sw=4:
Index: kopetemessage.h
===================================================================
RCS file: /home/kde/kdenonbeta/kopete/libkopete/kopetemessage.h,v
retrieving revision 1.6.2.3
diff -u -r1.6.2.3 kopetemessage.h
--- kopetemessage.h	1 May 2002 02:40:48 -0000	1.6.2.3
+++ kopetemessage.h	4 May 2002 10:40:04 -0000
@@ -17,6 +17,7 @@
 #ifndef _KOPETE_MESSAGE_H
 #define _KOPETE_MESSAGE_H
 
+#include <qobject.h>
 #include <qdatetime.h>
 #include <qstring.h>
 #include <qfont.h>
@@ -25,8 +26,9 @@
 
 typedef QPtrList<KopeteContact> KopeteContactList;
 
-class KopeteMessage
+class KopeteMessage : public QObject
 {
+Q_OBJECT
 public:
 	/**
 		Direction of a message. Inbound is from the chat partner, Outbound is
@@ -42,6 +44,7 @@
 	KopeteMessage();
 	KopeteMessage(const KopeteContact *, KopeteContactList, QString, MessageDirection, \
QColor = QColor(), QColor = QColor(), QFont = QFont() );  KopeteMessage(QDateTime, \
const KopeteContact *, KopeteContactList, QString, MessageDirection, QColor = \
QColor(), QColor = QColor(), QFont = QFont() ); +	KopeteMessage(const KopeteMessage& \
kopeteMessage);  
 	QDateTime timestamp() const { return mTimestamp; }
 
@@ -54,6 +57,11 @@
 
 	MessageDirection direction() const { return mDirection; }
 
+	void done() { emit done(*this); }; // call when a message is done
+
+signals:
+	void done(const KopeteMessage&);
+
 protected:
 	QDateTime mTimestamp;
 
@@ -64,6 +72,7 @@
 	QColor mFg, mBg;
 
 	MessageDirection mDirection;
+
 };
 
 #endif
Index: kopetemessagemanager.cpp
===================================================================
RCS file: /home/kde/kdenonbeta/kopete/libkopete/kopetemessagemanager.cpp,v
retrieving revision 1.18.2.5
diff -u -r1.18.2.5 kopetemessagemanager.cpp
--- kopetemessagemanager.cpp	3 May 2002 05:56:02 -0000	1.18.2.5
+++ kopetemessagemanager.cpp	4 May 2002 10:40:04 -0000
@@ -17,20 +17,23 @@
 */
 
 #include "kopetemessagemanager.h"
+
+#include "kopete.h"
 #include "kopetechatwindow.h"
 #include "kopeteevent.h"
-#include "kopete.h"
+#include "kopeteprotocol.h"
 
 #include "messagelog.h"
 #include <kdebug.h>
 #include <klocale.h>
 
 KopeteMessageManager::KopeteMessageManager( const KopeteContact *user, \
                KopeteContactList others,
-		QString logFile, QObject *parent, const char *name) : QObject( parent, name)
+		KopeteProtocol* protocol, QString logFile, QObject *parent, const char *name) : \
QObject( parent, name)  {
 
 	mContactList = others;
 	mUser = user;
+	mProtocol = protocol;
 	mChatWindow = 0L;
 	mUnreadMessageEvent = 0L;
 
@@ -89,14 +92,16 @@
 		connect ( mChatWindow, SIGNAL(sendMessage(const QString &)), this, \
SLOT(messageSentFromWindow(const QString &)) );  connect ( mChatWindow, \
SIGNAL(closeClicked()), this, SLOT(chatWindowClosing()) );  }
-	
+
 	for (KopeteMessageList::Iterator it = mMessageQueue.begin(); it != \
mMessageQueue.end(); it++)  {
 		kdDebug() << "[KopeteMessageManager] Inserting message from " << \
(*it).from()->name() << endl;  mChatWindow->messageReceived((*it));
 	}
 	mMessageQueue.clear();
-	mChatWindow->show();	// show message window again
+	mChatWindow->setActiveWindow();
+	mChatWindow->show();
+	cancelUnreadMessageEvent();
 }
 
 void KopeteMessageManager::slotReadMessages()
@@ -106,15 +111,26 @@
 
 void KopeteMessageManager::messageSentFromWindow(const QString &message)
 {
+	// Create the kopete message
 	QString body = message;
-	KopeteMessage tmpmessage(mUser, mContactList, body, KopeteMessage::Outbound);
-	emit messageSent ( tmpmessage );
+	KopeteMessage tmpMessage(mUser, mContactList, body, KopeteMessage::Outbound);
+
+	// Get to know when the message is sent so we can print it in the chatwindow
+	connect(&tmpMessage, SIGNAL(done(const KopeteMessage&)), this, \
SLOT(printMessage(const KopeteMessage&))); +
+	// Send the message
+	mProtocol->sendMessage(tmpMessage);
+
+	// This should go away soon... kept until all plugins migrate to \
"Protocol::sendMessage" +	emit messageSent ( tmpMessage );
+	
+	// What is this doing here ???? messages should be read when they arrive, not when \
they're sent  readMessages();
 }
 
 void KopeteMessageManager::chatWindowClosing()
 {
-	kdDebug() << "[KopeteMessageManager] Chat Window closed, now 0L" << endl;	
+	kdDebug() << "[KopeteMessageManager] Chat Window closed, now 0L" << endl;
 	mChatWindow = 0L;
 }
 
@@ -130,7 +146,7 @@
 		delete mUnreadMessageEvent;
 		mUnreadMessageEvent = 0L;
 		kdDebug() << "[KopeteMessageManager] cancelUnreadMessageEvent Event Deleted" << \
                endl;
-	}		
+	}
 }
 
 void KopeteMessageManager::slotEventDeleted(KopeteEvent *e)
@@ -196,4 +212,10 @@
 	{
                 mReadMode = Popup;
 	}
+}
+
+void KopeteMessageManager::printMessage( const KopeteMessage& message ) {
+
+	mChatWindow->messageReceived(message);
+
 }
Index: kopetemessagemanager.h
===================================================================
RCS file: /home/kde/kdenonbeta/kopete/libkopete/kopetemessagemanager.h,v
retrieving revision 1.11.2.5
diff -u -r1.11.2.5 kopetemessagemanager.h
--- kopetemessagemanager.h	3 May 2002 06:52:57 -0000	1.11.2.5
+++ kopetemessagemanager.h	4 May 2002 10:40:04 -0000
@@ -31,6 +31,7 @@
 class KopeteChatWindow;
 class KopeteEvent;
 class KopeteMessageLog;
+class KopeteProtocol;
 
 
 typedef QPtrList<KopeteContact>        KopeteContactList;
@@ -86,35 +87,38 @@
 	 * Get a list of all contacts in the session
 	 */
 	const KopeteContactList& members() const { return mContactList; }; /* Sorry, had to \
                change this to members(), it was conflicting with kxContact */
-    /**
+	/**
 	 * Get athe local user in the session
 	 */
 	const KopeteContact* user() const { return mUser; };
 
+
 signals:
 	/**
 	 * A message has been sent by the user or a plugin. The protocol should
 	 * connect to this signal to actually send the message over the wire.
 	 */
-	void messageSent( const KopeteMessage msg );
+	void messageSent( KopeteMessage& msg );
 	void dying( KopeteMessageManager *);
 
 public slots:
 	void readModeChanged();
-	
+
 protected slots:
 	void cancelUnreadMessageEvent();
 	void slotEventDeleted(KopeteEvent *);
-    void chatWindowClosing();
+	void chatWindowClosing();
 	void messageSentFromWindow( const QString &message);
+	void printMessage( const KopeteMessage& message );
 	void slotReadMessages();
+
 private:
 	/**
 	 * Create a message manager. This constructor is private, because the
 	 * static factory method createSession() creates the object. You may
 	 * not create instances yourself directly!
 	 */
-	KopeteMessageManager( const KopeteContact *user, KopeteContactList others,
+	KopeteMessageManager( const KopeteContact *user, KopeteContactList others, \
KopeteProtocol* protocol,  QString logFile = QString::null, QObject *parent = 0, \
const char *name = 0 );  
 	KopeteContactList mContactList;
@@ -123,6 +127,7 @@
 	KopeteEvent *mUnreadMessageEvent;
 	KopeteMessageList mMessageQueue;
 	KopeteMessageLog *mLogger;
+	KopeteProtocol* mProtocol;
 	int mReadMode;
 };
 
Index: kopetemessagemanagerfactory.cpp
===================================================================
RCS file: /home/kde/kdenonbeta/kopete/libkopete/kopetemessagemanagerfactory.cpp,v
retrieving revision 1.7.2.2
diff -u -r1.7.2.2 kopetemessagemanagerfactory.cpp
--- kopetemessagemanagerfactory.cpp	3 May 2002 06:52:57 -0000	1.7.2.2
+++ kopetemessagemanagerfactory.cpp	4 May 2002 10:40:04 -0000
@@ -29,9 +29,18 @@
 {
 }
 
+KopeteMessageManager* KopeteMessageManagerFactory::create(
+	const KopeteContact *user, KopeteContact* other, KopeteProtocol* protocol,
+	QString logFile)
+{
+	KopeteContactList tempKcl;
+	tempKcl.append(other);
+	return (create(user, tempKcl, protocol, logFile));
+}
+
 KopeteMessageManager *KopeteMessageManagerFactory::create(
 	const KopeteContact *user, KopeteContactList _contacts, /* Touch that underscore \
                and you die, along with ICQ not compiling */
-	QString logFile )
+	KopeteProtocol* protocol, QString logFile )
 {
 	bool createNewSession = false;
 	KopeteMessageManager *tmp;
@@ -39,14 +48,14 @@
 	{
     	if ( user == tmp->user() )
 		{
-			kdDebug() << "[KopeteMessageManagerFactory] User match, looking session members" \
<< endl;	 +			kdDebug() << "[KopeteMessageManagerFactory] User match, looking session \
members" << endl;  KopeteContact *tmp_contact;
 			KopeteContactList contactlist = tmp->members();
             for (  tmp_contact = contactlist.first(); tmp_contact ; tmp_contact = \
contactlist.next() )  {
 				if ( !_contacts.containsRef( tmp_contact ) )
 				{
-					kdDebug() << "[KopeteMessageManagerFactory] create() Oops, contact not found! \
new session needed!" << endl;	 +					kdDebug() << "[KopeteMessageManagerFactory] \
create() Oops, contact not found! new session needed!" << endl;  createNewSession = \
true;  break;
 				}
@@ -55,15 +64,15 @@
 			{
 				/* current session (tmp) is the same session the user is requesting */
 				return tmp;
-			}		
+			}
 		}
 		else
 		{
-			kdDebug() << "[KopeteMessageManagerFactory] User doesnt match, trying next \
session" << endl;	 +			kdDebug() << "[KopeteMessageManagerFactory] User doesnt match, \
trying next session" << endl;  }
 	}
-	
-	KopeteMessageManager *session = new KopeteMessageManager ( user, _contacts , \
logFile); +
+	KopeteMessageManager *session = new KopeteMessageManager ( user, _contacts, \
protocol, logFile);  connect( session, SIGNAL(dying(KopeteMessageManager*)), this, \
SLOT(slotRemoveSession(KopeteMessageManager*)));  (mSessionList).append(session);
 	return (session);
@@ -77,4 +86,3 @@
 }
 
 // vim: set noet ts=4 sts=4 sw=4:
-
Index: kopetemessagemanagerfactory.h
===================================================================
RCS file: /home/kde/kdenonbeta/kopete/libkopete/kopetemessagemanagerfactory.h,v
retrieving revision 1.7.2.1
diff -u -r1.7.2.1 kopetemessagemanagerfactory.h
--- kopetemessagemanagerfactory.h	3 May 2002 06:52:57 -0000	1.7.2.1
+++ kopetemessagemanagerfactory.h	4 May 2002 10:40:04 -0000
@@ -27,6 +27,7 @@
 class KopeteMessageManager;
 class KopeteMessage;
 class KopeteContact;
+class KopeteProtocol;
 
 typedef QPtrList<KopeteContact>        KopeteContactList;
 typedef QValueList<KopeteMessage>        KopeteMessageList;
@@ -46,8 +47,14 @@
 	 * it will be reused. Otherwise a new session is created.
 	 */
 	KopeteMessageManager* create( const KopeteContact *user,
-		KopeteContactList _contacts , QString logFile = QString::null );
-	
+		KopeteContactList _contacts, KopeteProtocol* protocol, QString logFile = \
QString::null ); +
+	/**
+	 * Overloaded function for convenience. Use for one-to-one KMM creation
+	 */
+	KopeteMessageManager* create( const KopeteContact *user,
+		KopeteContact* other, KopeteProtocol* protocol, QString logFile = QString::null );
+
 	/**
 	 * Get a list of all open sessions
 	 */
Index: kopeteprotocol.h
===================================================================
RCS file: /home/kde/kdenonbeta/kopete/libkopete/kopeteprotocol.h,v
retrieving revision 1.2
diff -u -r1.2 kopeteprotocol.h
--- kopeteprotocol.h	13 Apr 2002 03:45:41 -0000	1.2
+++ kopeteprotocol.h	4 May 2002 10:40:04 -0000
@@ -24,6 +24,7 @@
 
 class AddContactPage;
 class QString;
+class KopeteMessage;
 
 /**
  * @author duncan
@@ -52,7 +53,9 @@
 	// plugins should also return TRUE for modes like occupied not-vailable etc.
 	virtual bool isAway(void) const = 0;
 
-	virtual AddContactPage *createAddContactWidget(QWidget *parent)=0;
+	virtual AddContactPage *createAddContactWidget(QWidget *parent) = 0;
+
+	virtual void sendMessage(KopeteMessage&) {};
 
 	/**
 	 * The icon of the plugin as shown in the status bar


_______________________________________________
Kopete-devel mailing list
Kopete-devel@mail.kde.org
http://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