Commits

Lukas Linhart committed c5b2e40

Comments (0)

Files changed (15)

net-im/psi-otr/Manifest

+DIST psi-otr-0.4.tar.gz 33077 RMD160 661384cbc2b0dc0edc8c548a2948ba36fe9ad11c SHA1 2029fc822d3484b2f2f4e281d1b67df3300604e3 SHA256 af0bfbbbf875e6221fafadabd5ce92d347af0359a69177773ae746e6db885347
+EBUILD psi-otr-0.4.ebuild 763 RMD160 2d2e7be7509d900ad0d69ced2db257eccd563f61 SHA1 03665a8c505cf552d3561c48990499461aa15318 SHA256 a3274083aaa018c58913d080d88e6668aa5306168a0b88f32b82d4dac56e32fe

net-im/psi-otr/psi-otr-0.4.ebuild

+# Copyright 1999-2009 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+
+EAPI="1"
+
+inherit eutils qt4 multilib
+
+MY_P="psi-otr-0.4"
+S=${WORKDIR}/${MY_P}
+
+DESCRIPTION="OTR Encryption for the Qt4 Jabber client Psi"
+HOMEPAGE="http://public.tfh-berlin.de/~s30935/"
+SRC_URI="http://public.tfh-berlin.de/~s30935/files/${P}.tar.gz"
+
+LICENSE="GPL"
+SLOT="0"
+KEYWORDS="~amd64"
+RESTRICT="test"
+
+DEPEND="=net-im/psi-0.12.1
+	=net-libs/libotr-3.1.0"
+
+src_unpack() {
+	unpack ${A}
+	cd "${S}"
+}
+
+pkg_setup() {
+	qt4_pkg_setup
+}
+
+src_compile() {
+	cd ${S}
+	sed -i "s/\/usr\/local/\/usr/g" psi-otr.pro
+	eqmake4 psi-otr.pro || die "qmake failed"
+}
+
+src_install() {
+	emake INSTALL_ROOT="${D}" install || die "emake install failed"
+}

net-im/psi/Manifest

+AUX psi-0.10-gpg2.patch 505 RMD160 bfccc6ee984fac7b93ef0343a16c84bd6653d60d SHA1 b9d79a567cbbca837fb69a05ea8e59e07fdadf36 SHA256 cedeef3a18d0f7c4d50d1d86d9de88cceddf352977b2ae7df72451f3ba188348
+AUX psi-0.12.1-build-error.patch 719 RMD160 401d3d17d9617ead7a78d78431a19c65c21b5667 SHA1 f47f6365c04872ba0a977241ee9d756eee640f0b SHA256 8daaf3e27d153b0c3e97b203adfc081fa06dd0d46a85a219baac9b181d0c51bb
+AUX psi-0.12.1-plugin-otr.patch 23803 RMD160 21f74fddc7bc398179a0ac16700a7fa6263053ef SHA1 fc1fc9986a4633af5fc1f54d795142790d4a1390 SHA256 5e9fcee721a50dbb266136e2564900009e07c8b71c30c44a245c212adcfce299
+AUX psi-0.12.1-qt-4.5-compatibility.patch 524 RMD160 c68887a6bc31ad20cd42c427769ecd3cfed53280 SHA1 5afbaa1474eec179a6c3ce1f1ea2deafd0a22369 SHA256 5e5c3d8089092c7b81eb6295a701c634ebd223ee6791f36ed56d83d72374ac13
+AUX psi-desktop2.patch 508 RMD160 50037b740407ec36e5d01386f145f5f055e4eae0 SHA1 71ddba6d8cafa8b7de218620dd7373758cc064d9 SHA256 b4045dafc0bc00b0167449693fc3e9b2f53041a070a93954f8939ee0866efa8e
+AUX psi-echoplugin.patch 785 RMD160 eba6e881b251062d5f102d0a9450239eb778cf75 SHA1 1ba5d83ce9cf517e13eb6510ea16b62641c276f1 SHA256 9476e8de292427a7c3e209a72cd2ee5663bfe76e88b89618414adde84991c8ff
+AUX psi-indicator.png 300 RMD160 507ab090f82276492bbf6af23eab78e2f8c8ccf2 SHA1 2adcd9b63b2f0ba98415c8bb526d1a57c24d88f4 SHA256 a0e9adcd0409d23c9033170ceb8f22980ba6d5e14f19234630f9986bfb94bce2
+AUX psi-jingle-gcc4.patch 3220 RMD160 6c7b6f7874d7ddea19847a94608bee790314be7d SHA1 654e0ce48b3dabbb5be264f479c852227087242b SHA256 b8fc648ec149acba256a4ca406095a6c134a8b1862430375f39d56aa739f2b74
+AUX psi-pathfix2.patch 364 RMD160 029db596437aba9d85a8cbde30d8f1247f6cf050 SHA1 43165fa61e08b6a60249efed830c58b1693b879f SHA256 2f9e94219e858f8ea9a8771adac90430dc6199d6f8de2cc6778288583580d0d8
+AUX psi-ptr_64bit_fix.patch 606 RMD160 8433eea58b4e10be562ecb8f2e2f33e9b188af99 SHA1 909271955a1c5329169774ae49f2cbbdf3110a6f SHA256 a221fa08a98f071310c88f69ef88114e48b8744d211ede9bcbb21fe6fbb9675d
+AUX psi-reverse_trayicon2.patch 937 RMD160 bbf8ba2c512ceab7b3fe82af12ff9b647d6b3c9f SHA1 78f492bf1a2dbac8924c7eaeb2f193fac71493b5 SHA256 2a690a7cda661884ce3424530ac6569a7fcb1e6c97342c120767a0d5058c403c
+DIST psi-0.12.1.tar.bz2 2112404 RMD160 a5fc850796b0078bc1a03f4ff93a03611ee11e80 SHA1 6fdcea3a072b40333faecc37acdb925f9bf8c5c3 SHA256 a8022faadbbe15bc4691338b1d83400adf069f773b7fa3b462552515990b277e
+DIST psi-langs-20090217.tar.bz2 641414 RMD160 03e95fc690aa0e1ea49b7ac277ef0ecea91285f8 SHA1 de5e149d6fc55a464af6e614121b8c228b6e1432 SHA256 59f17d6547e4c911e83199fcd3908fa1bf4db312ae25d2c14e27d4c536915f9c
+EBUILD psi-0.12.1.ebuild 2822 RMD160 0bfdd8507ae1df3247d1e8206063a4d740299909 SHA1 be112ed41cda7df427c9d98557ac56a4297fea48 SHA256 e84fac1f24f3561b79bf4523fd935ede0c27169e3ec2c8fd183e29a67cafe6ec

net-im/psi/files/psi-0.10-gpg2.patch

+diff -urNp psi-0.10.org/src/tools/openpgp/gpgop.cpp psi-0.10/src/tools/openpgp/gpgop.cpp
+--- psi-0.10.org/src/tools/openpgp/gpgop.cpp	2005-08-21 20:44:28.000000000 +0300
++++ psi-0.10/src/tools/openpgp/gpgop.cpp	2007-06-28 18:55:55.000000000 +0300
+@@ -377,7 +377,7 @@ void GpgOp::proc_statusLine(const QStrin
+ 		rest = str.mid(n+1);
+ 	}
+ 
+-	if(s == "NEED_PASSPHRASE") {
++	if(s == "GET_HIDDEN") {
+ 		if(!(d->tryAgent && getenv("GPG_AGENT_INFO"))) {
+ 			if(!d->didPassphrase) {
+ 				d->didPassphrase = true;

net-im/psi/files/psi-0.12.1-build-error.patch

+commit 360310c8f2dc07c5ff50d4c26b6b984a2c66f5be
+Author: Justin Karneges <justin@affinix.com>
+Date:   Thu Feb 5 22:53:05 2009 -0800
+
+    make these references less weird
+
+diff --git a/src/mainwin.cpp b/src/mainwin.cpp
+index d12497d..6c130e2 100644
+--- a/src/mainwin.cpp
++++ b/src/mainwin.cpp
+@@ -428,9 +428,9 @@ MainWin::~MainWin()
+ 
+ void MainWin::registerAction( IconAction* action )
+ {
+-	char activated[] = SIGNAL( activated() );
+-	char toggled[]   = SIGNAL( toggled(bool) );
+-	char setChecked[]     = SLOT( setChecked(bool) );
++	const char *activated  = SIGNAL( activated() );
++	const char *toggled    = SIGNAL( toggled(bool) );
++	const char *setChecked = SLOT( setChecked(bool) );
+ 
+ 	struct {
+ 		const char* name;

net-im/psi/files/psi-0.12.1-plugin-otr.patch

+Index: src/pluginmanager.h
+===================================================================
+--- src/pluginmanager.h	(Revision 1195)
++++ src/pluginmanager.h	(Arbeitskopie)
+@@ -4,9 +4,12 @@
+ #include <QtCore>
+ #include <QList>
+ #include <QMap>
++#include <QToolButton>
++#include <QAction>
+ 
+ #include "userlist.h"
+ #include "optionstree.h"
++#include "../iris/include/im.h"
+ 
+ class PsiPlugin;
+ 
+@@ -22,6 +25,8 @@
+ 
+ class QPluginLoader;
+ 
++using namespace XMPP;
++
+ class PluginManager : public QObject
+ {
+ 	Q_OBJECT
+@@ -30,9 +35,15 @@
+ 
+ 	QStringList availablePlugins();
+ 
++	QList<QAction*> getChatDlgMenuEntries(QWidget* parent, 
++									      PsiAccount* account, 
++	                                      const XMPP::Jid& otherjid);
++
+ 	void addAccount( const PsiAccount* account, XMPP::Client* client);
+-	void message( PsiAccount* account, const XMPP::Jid& from, 
+-	const UserListItem*, const QString& message );
++	QString incomingMessage( PsiAccount* account, const XMPP::Jid& from, QString message );
++	HTMLElement incomingMessage( PsiAccount* account, const XMPP::Jid& from, HTMLElement htmlMessage );
++	QString outgoingMessage( PsiAccount* account, const XMPP::Jid& from, QString message );
++				
+ 	bool loadPlugin( const QString& file );
+ 	void loadEnabledPlugins();
+ 	bool unloadPlugin( const QString& file );
+@@ -41,6 +52,13 @@
+ 	QString shortName( const QString& plugin );
+ 	QWidget* getOptionsWidget( const QString& plugin );
+ 	bool processEvent( const PsiAccount* account, QDomElement &event );
++	void statusChanged(QString account, QString jid, QString resource, int prio, QString status, 
++			   QString text);
++	void contactOffline(QString account, QString contact);
++	void contactOnline(QString account, QString contact);
++	void login(QString jid);
++	void logout(QString jid);
++	void quitProgram();
+ 	
+ 	const QVariant getGlobalOption(const QString& option);
+ 	
+@@ -80,6 +98,8 @@
+ 	void optionChanged(const QString& option);
+ 	void sendStanza( const PsiAccount* account, const QDomElement& stanza);
+ 	void sendStanza( const PsiAccount* account, const QString& stanza);
++	void sendStanza(const QString& fromJid, const QString& stanza);
++	void getHomeDir(QString&);
+ };
+ 
+ #endif
+Index: src/about.ui
+===================================================================
+--- src/about.ui	(Revision 1195)
++++ src/about.ui	(Arbeitskopie)
+@@ -101,8 +101,11 @@
+          </property>
+          <property name="text" >
+           <string>A cross-platform Jabber client designed for the Jabber power user.&lt;br>
+-&lt;br>
++	  &lt;br>
+ Copyright © 2001-2008 The Psi Team.&lt;br>
++
++This version of Psi has been been patched by Timo Engel (timo-e@freenet.de)
++
+ </string>
+          </property>
+          <property name="textFormat" >
+Index: src/psiplugin.h
+===================================================================
+--- src/psiplugin.h	(Revision 1195)
++++ src/psiplugin.h	(Arbeitskopie)
+@@ -28,7 +28,9 @@
+ 
+ #include <QObject>
+ #include <QtCore>
+-#include <QDomNode>
++#include <QtXml>
++#include <QAction>
++#include <QToolButton>
+ 
+ class PsiAccount;
+ class QDomElement;
+@@ -53,6 +55,7 @@
+ 	 * \return Plugin name
+ 	 */
+ 	virtual QString name() const = 0;
++
+ 	/** \brief Short name for the plugin
+ 	 *	This is the short name of the plugin, used for options structures. 
+ 	 * It must consist of only alphanumerics (no spaces or punctuation).
+@@ -66,11 +69,40 @@
+ 	 * \return Plugin version string
+ 	 */
+ 	virtual QString version() const = 0; 
+-	
+-	virtual void message( const PsiAccount* account, const QString& message, const QString& fromJid, const QString& fromDisplay) 
+-	{Q_UNUSED(account);Q_UNUSED(message);Q_UNUSED(fromJid);Q_UNUSED(fromDisplay);}
+ 
+ 	/**
++	 * Allows the plugin to add a entry to the chat dialog menu.
++	 */
++	virtual QAction* getChatDlgMenuEntry(QWidget* parent,
++				       	     const QString& fromJid,
++				             const QString& toJid)
++	{Q_UNUSED(parent);Q_UNUSED(fromJid);Q_UNUSED(toJid);return NULL;}
++
++	/**
++	 * process incoming message
++	 */
++	virtual QString incomingMessage( const QString& fromJid,
++			      const QString& toJid, 
++			      const QString& message) 
++	{Q_UNUSED(fromJid);Q_UNUSED(toJid);Q_UNUSED(message);return NULL;}
++
++	/**
++	 * process incoming HTML message
++	 */
++	virtual QDomElement incomingMessage( const QString& fromJid,
++			      const QString& toJid, 
++			      const QDomElement& html) 
++	{Q_UNUSED(fromJid);Q_UNUSED(toJid);Q_UNUSED(html);return QDomElement();}
++
++	/** 
++	 * process outgoing message
++	 */
++	virtual QString outgoingMessage(const QString& fromJid, 
++					const QString& toJid, 
++					const QString& message)
++	{Q_UNUSED(fromJid);Q_UNUSED(toJid);Q_UNUSED(message); return NULL;}
++
++	/**
+ 	 * \brief Plugin options widget
+ 	 * This method is called by the Psi options system to retrieve
+ 	 * a widget containing the options for this plugin.
+@@ -81,10 +113,17 @@
+ 	virtual QWidget* options() {return NULL;} 
+ 	
+ 
+-	virtual bool processEvent( const PsiAccount* account, QDomNode &event ) {Q_UNUSED(account);Q_UNUSED(event);return true;}
++	/**
++	 * 
++	 *
++	 */
++	virtual bool processEvent( const PsiAccount* account, QDomNode &event ) 
++	{Q_UNUSED(account);Q_UNUSED(event);return true;}
+ 
++
+ 	/**
+-	 * Convenience method for plugins, allowing them to convert a QDomElement to a QString
++	 * Convenience method for plugins, allowing them to convert a QDomElement 
++	 * to a QString
+ 	 */
+ 	static QString toString(const QDomNode& xml)
+ 	{
+@@ -93,7 +132,53 @@
+ 		xml.save(stream, 0);
+ 		return QString(*stream.string());
+ 	}
+-	
++
++	/* initialize the plugin. called from the pluginmanager after loading */
++	virtual void init() {return;}
++
++	/* a contact has become available */
++	virtual void contactOnline(QString account, QString jid) {
++		Q_UNUSED(jid);
++		Q_UNUSED(account);
++		return;
++	}
++
++	/* a contact has become unavailable */
++	virtual void contactOffline(QString account, QString jid) {
++		Q_UNUSED(jid);
++		Q_UNUSED(account);
++		return;
++	}
++
++	/* a contact has changed its status */
++	virtual void statusChanged(QString account, QString jid, QString resource, int prio, 
++		QString status, QString text) {
++		Q_UNUSED(account);
++		Q_UNUSED(jid);
++		Q_UNUSED(resource);
++		Q_UNUSED(prio);
++		Q_UNUSED(status);
++		Q_UNUSED(text);
++		return;
++	}
++
++	/* account logged in */
++	virtual void login(QString jid) {
++		Q_UNUSED(jid);
++		return;
++	}
++
++	/* account went offline */
++	virtual void logout(QString jid) {
++		Q_UNUSED(jid);
++		return;
++	}
++
++	/* user want to exit psi */
++	virtual void quitProgram() {
++		return;
++	}
++
+ signals:
+ 	/**
+ 	 *	\brief Signals that the plugin wants to send a stanza.
+@@ -101,7 +186,7 @@
+ 	 * \param account The account name, as used by the plugin interface.
+ 	 * \param stanza The stanza to be sent.
+ 	 */
+-	//void sendStanza( const PsiAccount* account, const QDomElement& stanza);
++	void sendStanza( const PsiAccount* account, const QDomElement& stanza);
+ 
+ 	/**
+ 	 *	\brief Signals that the plugin wants to send a stanza.
+@@ -111,7 +196,14 @@
+ 	 */
+ 	void sendStanza( const PsiAccount* account, const QString& stanza);
+ 	
++	
+ 	/**
++	 * Send a stanza from the account with the jid fromJid.
++	 *
++	 */
++	void sendStanza( const QString& fromJid, const QString& stanza);
++	
++	/**
+ 	 * \brief Requests an item in the Psi menu for the plugin
+ 	 * 
+ 	 * \param label The text to be inserted in the menu
+@@ -162,6 +254,11 @@
+ 	 */
+ 	void getGlobalOption( const QString& option, QVariant& value);
+ 	
++	/**
++	 * Returns the home-directory used by psi
++	 */
++	void getHomeDir(QString& dir);
++
+ //protected:
+ 
+ 	
+Index: src/options/opt_plugins.h
+===================================================================
+--- src/options/opt_plugins.h	(Revision 1195)
++++ src/options/opt_plugins.h	(Arbeitskopie)
+@@ -14,8 +14,8 @@
+ 	~OptionsTabPlugins();
+ 
+ 	QWidget *widget();
+-	void applyOptions(Options *opt);
+-	void restoreOptions(const Options *opt);
++	void applyOptions();
++	void restoreOptions();
+ 
+ private:
+ 	QWidget *w;
+Index: src/options/opt_plugins.cpp
+===================================================================
+--- src/options/opt_plugins.cpp	(Revision 1195)
++++ src/options/opt_plugins.cpp	(Arbeitskopie)
+@@ -53,23 +53,21 @@
+ 	return w;
+ }
+ 
+-void OptionsTabPlugins::applyOptions(Options *opt)
++void OptionsTabPlugins::applyOptions()
+ {
+ 	if ( !w )
+ 		return;
+ 
+ 	OptPluginsUI *d = (OptPluginsUI *)w;
+ 	Q_UNUSED(d);
+-	Q_UNUSED(opt);
+ }
+ 
+-void OptionsTabPlugins::restoreOptions(const Options *opt)
++void OptionsTabPlugins::restoreOptions()
+ {
+ 	if ( !w )
+ 		return;
+ 
+ 	OptPluginsUI *d = (OptPluginsUI *)w;
+-	Q_UNUSED(opt);
+ 	Q_UNUSED(d);
+ }
+ 
+@@ -104,6 +102,15 @@
+ 		.arg(PluginManager::instance()->shortName(d->cb_plugins->currentText()));
+ 	bool value=d->cb_loadPlugin->isChecked(); 
+ 	PsiOptions::instance()->setOption(option, value);
++	if ( value) {
++		PluginManager::instance()->loadEnabledPlugins();
++		pluginSelected(0);
++	}
++	else {
++		delete d->pluginOptions;
++		PluginManager::instance()->unloadPlugin( d->cb_plugins->currentText());
++		d->pluginOptions = new QLabel(tr("This plugin has no user configurable options"));
++	}
+ }
+ 
+ void OptionsTabPlugins::pluginSelected(int index)
+Index: src/main.h
+===================================================================
+--- src/main.h	(Revision 1195)
++++ src/main.h	(Arbeitskopie)
+@@ -24,6 +24,8 @@
+ #include <QString>
+ #include <QObject>
+ 
++#include "pluginmanager.h"
++
+ class PsiCon;
+ 
+ class PsiMain : public QObject
+Index: src/psichatdlg.cpp
+===================================================================
+--- src/psichatdlg.cpp	(Revision 1195)
++++ src/psichatdlg.cpp	(Arbeitskopie)
+@@ -38,6 +38,7 @@
+ #include "userlist.h"
+ #include "jidutil.h"
+ #include "textutil.h"
++#include "pluginmanager.h"
+ 
+ PsiChatDlg::PsiChatDlg(const Jid& jid, PsiAccount* pa, TabManager* tabManager)
+ 		: ChatDlg(jid, pa, tabManager)
+@@ -189,6 +190,12 @@
+ 
+ 	act_compact_ = new IconAction(tr("Toggle Compact/Full size"), "psi/compact", tr("Toggle Compact/Full size"), 0, this);
+ 	connect(act_compact_, SIGNAL(activated()), SLOT(toggleSmallChat()));
++
++#ifdef PSI_PLUGINS
++	act_plugins_ = PluginManager::instance()->getChatDlgMenuEntries(this, 
++	                                                                account(),
++								        							jid());
++#endif
+ }
+ 
+ void PsiChatDlg::initToolBar()
+@@ -207,6 +214,12 @@
+ 	if (account()->voiceCaller()) {
+ 		ui_.toolbar->addAction(act_voice_);
+ 	}
++#ifdef PSI_PLUGINS
++	foreach (QAction* i, act_plugins_ )
++	{
++		ui_.toolbar->addAction(i);
++	}
++#endif
+ }
+ 
+ void PsiChatDlg::contextMenuEvent(QContextMenuEvent *)
+@@ -364,6 +377,13 @@
+ 
+ 	pm_settings_->addAction(act_info_);
+ 	pm_settings_->addAction(act_history_);
++#ifdef PSI_PLUGINS
++	foreach (QAction* a, act_plugins_)
++	{
++		pm_settings_->insertSeparator();
++		pm_settings_->addAction(a);
++	}
++#endif
+ }
+ 
+ void PsiChatDlg::updateCounter()
+Index: src/psiaccount.cpp
+===================================================================
+--- src/psiaccount.cpp	(Revision 1195)
++++ src/psiaccount.cpp	(Arbeitskopie)
+@@ -1243,6 +1243,9 @@
+ // disconnect or stop reconnecting
+ void PsiAccount::logout(bool fast, const Status &s)
+ {
++#ifdef PSI_PLUGINS	
++	PluginManager::instance()->logout(jid().node() + "@" + jid().domain());
++#endif
+ 	if(!isActive())
+ 		return;
+ 
+@@ -1447,6 +1450,9 @@
+ 
+ 	// ask for roster
+ 	d->client->rosterRequest();
++#ifdef PSI_PLUGINS
++	PluginManager::instance()->login(jid().node() + "@" + jid().domain());
++#endif
+ }
+ 
+ void PsiAccount::cs_connectionClosed()
+@@ -1618,7 +1624,7 @@
+ 		str = tr("Broken security layer (SASL)");
+ 	else
+ 		str = tr("None");
+-	//printf("str[%s], reconn=%d\n", str.latin1(), reconn);
++//printf("str[%s], reconn=%d\n", str.latin1(), reconn);
+ 	*_str = str;
+ 	*_reconn = reconn;
+ }
+@@ -1864,6 +1870,11 @@
+ 		UserResourceList::Iterator rit = u->userResourceList().find(j.resource());
+ 		bool found = (rit == u->userResourceList().end()) ? false: true;
+ 		if(!found) {
++#ifdef PSI_PLUGINS
++			PluginManager::instance()->contactOnline(
++				jid().node() + "@" + jid().domain(),
++				j.node() + "@" + j.domain());
++#endif
+ 			popupType = PopupOnline;
+ 
+ 			UserResource ur(r);
+@@ -1949,6 +1960,15 @@
+ 			}
+ 		}
+ 	}
++#ifdef PSI_PLUGINS
++	PluginManager::instance()->statusChanged(
++		jid().node() + "@" + jid().domain(),
++		j.node() + "@" + j.domain(),
++		r.name(),
++		r.priority(),
++		r.status().show(),
++		r.status().status());
++#endif
+ }
+ 
+ void PsiAccount::client_resourceUnavailable(const Jid &j, const Resource &r)
+@@ -2019,6 +2039,11 @@
+ 		PsiGrowlNotifier::instance()->popup(this, PsiPopup::AlertOffline, j, r, u);
+ #endif
+ 	}
++#ifdef PSI_PLUGINS
++	PluginManager::instance()->contactOffline(
++		jid().node() + "@" + jid().domain(),
++		j.node() + "@" + j.domain());
++#endif
+ }
+ 
+ void PsiAccount::client_presenceError(const Jid &j, int, const QString &str)
+@@ -3493,6 +3518,14 @@
+ 		}
+ 	}
+ 
++#ifdef PSI_PLUGINS
++        if (! nm.body().isEmpty()) {
++                nm.setBody(PluginManager::instance()->outgoingMessage(this, nm.to(), nm.body()));
++        }
++#endif
++
++
++
+ 	d->client->sendMessage(nm);
+ 
+ 	// only toggle if not an invite or body is not empty
+@@ -3764,6 +3797,32 @@
+ 	//FIXME(KIS): must now cause the event to be recreated from this xml or such. Horrid. 	
+ #endif
+ 	
++#ifdef PSI_PLUGINS
++	if(e->type() == PsiEvent::Message) {
++		MessageEvent *me = (MessageEvent *)e;
++		Message msg = me->message();
++		UserListItem *ulItem=NULL;
++		if ( !ul.isEmpty() ) {
++			ulItem=ul.first();
++		}
++		
++		if (msg.containsHTML() && ! msg.html().text().isEmpty() ) {
++			HTMLElement htmlPart = PluginManager::instance()->incomingMessage(this,
++				msg.from(),
++				msg.html());
++			msg.setHTML(htmlPart, msg.lang());
++			msg.setBody(htmlPart.text());
++		}
++        	else if (! msg.body().isEmpty()) {
++                	msg.setBody( PluginManager::instance()->incomingMessage(this, 
++							      msg.from(),
++							      msg.body()));
++        	}
++		me->setMessage(msg);
++		e = me;
++	}
++#endif
++	
+ 	if(d->acc.opt_log && activationType != FromXml) {
+ 		if(e->type() == PsiEvent::Message || e->type() == PsiEvent::Auth) {
+ 			// don't log private messages
+@@ -3772,10 +3831,14 @@
+ 		}
+ 	}
+ 
++	
+ 	if(e->type() == PsiEvent::Message) {
++	
+ 		MessageEvent *me = (MessageEvent *)e;
+-		const Message &m = me->message();
++		Message msg = me->message();
++		const Message &m = msg;
+ 
++
+ 		// Pass message events to chat window
+ 		if ((m.containsEvents() || m.chatState() != StateNone) && m.body().isEmpty()) {
+ 			if (PsiOptions::instance()->getOption("options.messages.send-composing-events").toBool()) {
+@@ -3840,13 +3903,7 @@
+ 			// FIXME: handle message errors
+ 			//msg.text = QString(tr("<big>[Error Message]</big><br>%1").arg(plain2rich(msg.text)));
+ 		}
+-#ifdef PSI_PLUGINS
+-		UserListItem *ulItem=NULL;
+-		if ( !ul.isEmpty() )
+-			ulItem=ul.first();
+-		PluginManager::instance()->message(this,e->from(),ulItem,((MessageEvent*)e)->message().body());
+-#endif
+-	}
++}
+ 	else if(e->type() == PsiEvent::HttpAuth) {
+ 		playSound(PsiOptions::instance()->getOption("options.ui.notifications.sounds.system-message").toString());
+ 	}
+Index: src/main.cpp
+===================================================================
+--- src/main.cpp	(Revision 1195)
++++ src/main.cpp	(Arbeitskopie)
+@@ -265,6 +265,9 @@
+ 
+ void PsiMain::bail()
+ {
++#ifdef PSI_PLUGINS
++	PluginManager::instance()->quitProgram();
++#endif
+ 	if(pcon) {
+ 		delete pcon;
+ 		pcon = 0;
+Index: src/psichatdlg.h
+===================================================================
+--- src/psichatdlg.h	(Revision 1195)
++++ src/psichatdlg.h	(Arbeitskopie)
+@@ -69,7 +69,9 @@
+ 	IconAction* act_file_;
+ 	IconAction* act_compact_;
+ 	IconAction* act_voice_;
+-
++#ifdef PSI_PLUGINS
++	QList<QAction*> act_plugins_;
++#endif
+ 	bool smallChat_;
+ 	QDateTime lastMsgTime_;
+ };
+Index: src/pluginmanager.cpp
+===================================================================
+--- src/pluginmanager.cpp	(Revision 1195)
++++ src/pluginmanager.cpp	(Arbeitskopie)
+@@ -7,6 +7,7 @@
+ #include "userlist.h"
+ #include "applicationinfo.h"
+ #include "psioptions.h"
++#include "psiaccount.h"
+ #include <QtCrypto>
+ #include "xmpp_client.h"
+ 
+@@ -71,6 +72,7 @@
+  */
+ void PluginManager::optionChanged(const QString& option)
+ {
++	Q_UNUSED(option);
+ 	//QString("%1.%2").arg(loadOptionPrefix).arg(shortNames_[plugin]);
+ }
+ 
+@@ -164,12 +166,17 @@
+ 	plugins_.insert( plugin->name(), plugin );
+ 	
+ 	qDebug() << "connecting to plugin " << plugin->name();
++	connect(plugin, SIGNAL(sendStanza(const QString&, const QString&)),
++		this,   SLOT(sendStanza(const QString&, const QString&)));
+ 	connect( plugin, SIGNAL(sendStanza(const PsiAccount*, const QDomElement&)), this, SLOT(sendStanza(const PsiAccount*, const QDomElement&)));
+ 	connect( plugin, SIGNAL(sendStanza(const PsiAccount*, const QString&)), this, SLOT(sendStanza(const PsiAccount*, const QString&)));
+ 	connect( plugin, SIGNAL(setPluginOption( const QString&, const QVariant& )), this, SLOT( setPluginOption( const QString&, const QVariant& )));
+ 	connect( plugin, SIGNAL(getPluginOption( const QString&, QVariant&)), this, SLOT( getPluginOption( const QString&, QVariant&)));
+ 	connect( plugin, SIGNAL(setGlobalOption( const QString&, const QVariant& )), this, SLOT( setGlobalOption( const QString&, const QVariant& )));
+ 	connect( plugin, SIGNAL(getGlobalOption( const QString&, QVariant&)), this, SLOT( getGlobalOption( const QString&, QVariant&)));
++	connect(plugin, SIGNAL(getHomeDir(QString&)),
++		this, SLOT(getHomeDir(QString&)));
++	plugin->init();
+ 	return true;
+ }
+ 
+@@ -274,6 +281,9 @@
+ 		QDir dir(d);
+ 		foreach(QString file, dir.entryList()) {
+ 		  	file=dir.absoluteFilePath(file);
++		  	if (file.endsWith("..") || file.endsWith(".") ) {
++		  		continue;
++		  	}
+ 			qWarning(qPrintable(QString("Found plugin: %1").arg(file)));
+ 			if ( !loaders_.contains(file) ) { 
+ 				loadPlugin(file);
+@@ -341,7 +351,8 @@
+  */
+ void PluginManager::getPluginOption( const QString& option, QVariant& value)
+ {
+-	
++	Q_UNUSED(option);
++	Q_UNUSED(value);
+ }
+ 
+ /**
+@@ -373,17 +384,82 @@
+ 	else
+ 		qDebug("not valid option");
+ }
+-	
+-void PluginManager::message(PsiAccount* account, const XMPP::Jid& from, const UserListItem* ul, const QString& message)
++
++
++
++QList<QAction*> PluginManager::getChatDlgMenuEntries(QWidget* parent, 
++                                                     PsiAccount* account,
++					           						 const XMPP::Jid& otherjid)
+ {
+-	QString fromString=QString("%1").arg(from.full());
++	const QString accountString = QString("%1").arg(account->jid().full());
++	const QString otherJidString = QString("%1").arg(otherjid.full());
++	QList<QAction*> res;
++ 	foreach(PsiPlugin* plugin, plugins_.values() ) 
++	{
++		QAction* m = plugin->getChatDlgMenuEntry(parent, accountString,
++											     otherJidString);
++		if (m) {
++			res.append(m);
++		}
++	}
++	return res;
++}
++
++
++
++/**
++ * incomingMessage. Function is only for non-HTML messages.
++ */
++QString PluginManager::incomingMessage(PsiAccount* account, const XMPP::Jid& from, 
++	QString message) {
++	const QString toString = QString("%1").arg(account->jid().full());
++	const QString fromString=QString("%1").arg(from.full());
++	//qDebug() << "pluginmanager: incomming message from " << fromString 
++	//	 << " to " << toString;
+ 	qDebug() << "message from" << fromString;
+ 	foreach(PsiPlugin* plugin, plugins_.values() ) {
+-		plugin->message( account, message , fromString , from.full() );
++		message = plugin->incomingMessage(fromString, toString, message );
++		//qDebug() << plugin->shortName() << " returned: " << endl
++		//	<< message << "\n--\n";
+ 	}
++	//qDebug() << "PluginManager::incomingMessage:\n" << message << endl << "--";
++	return message;
+ }
+ 
+ /**
++ * incommingMessage with HTML content.
++ */
++HTMLElement PluginManager::incomingMessage(PsiAccount* account, const XMPP::Jid& from,
++                                           HTMLElement htmlMessage)
++{
++	const QString toString = QString("%1").arg(account->jid().full());
++	const QString fromString=QString("%1").arg(from.full());
++	//qDebug() << "pluginmanager: incomming message from " << fromString 
++	//	 << " to " << toString;
++	QDomElement body = htmlMessage.body();
++
++	//QString str;
++	//QTextStream ts( &str, IO_WriteOnly );
++	//body.save(ts, 8);
++	//qDebug() << "--\n" << str << "\n--\n\n";
++
++	foreach(PsiPlugin* plugin, plugins_.values())
++	{
++		body = plugin->incomingMessage(fromString, toString, body);
++		//qDebug() << plugin->shortName() << " returned: " << endl
++		//	<< message << "\n--\n";
++	}
++	
++	//QString str;
++	//QTextStream ts( &str, IO_WriteOnly );
++	//body.save(ts, 2);
++	//qDebug() << "pluginmanager: modified message:\n" << str << "\n--\n";
++		
++	htmlMessage.setBody(body);
++	return htmlMessage;
++}
++
++/**
+  * \brief Give each plugin the opportunity to process the incoming event
+  * 
+  * Each plugin is passed the event in turn. Any plugin may then modify the event
+@@ -429,7 +505,27 @@
+ 	clients_[account]->send(stanza);
+ }
+ 
++
+ /**
++ * Sends a stanza from the account spezified with fromJid.
++ *
++ */
++void PluginManager::sendStanza(const QString& fromJid, const QString& stanza) {
++	//qDebug() << "pluginmanager: sending stanza from account " << fromJid 
++	//	<< endl << stanza << "\n--";
++	QMapIterator<const PsiAccount*, XMPP::Client*> iterator(clients_);
++	while (iterator.hasNext()) {
++		iterator.next();
++		const PsiAccount* account = iterator.key();
++		if ( ! QString::compare(account->jid().full(), fromJid, Qt::CaseInsensitive)) {
++			clients_.value(account)->send(stanza);
++			break;
++		}
++	}
++}
++
++
++/**
+  * Tells the plugin manager about an XMPP::Client and the owning PsiAccount
+  */
+ void PluginManager::addAccount( const PsiAccount* account, XMPP::Client* client)
+@@ -447,6 +543,83 @@
+ 	return true;
+ }
+ 
++
++/**
++ * process an outgoing message
++ */
++QString PluginManager::outgoingMessage( PsiAccount* account, const XMPP::Jid& to, QString message ) {
++	const QString toString=QString("%1").arg(to.full());
++	const QString fromString = QString("%1").arg(account->jid().full());
++	//qDebug() << "pluginmanager: outgoing message from " << fromString << " to "
++	//	<< toString;
++	foreach(PsiPlugin* plugin, plugins_.values() ) {
++		message = plugin->outgoingMessage( fromString, toString, message );
++	}
++	return message;
++
++}
++
++/**
++ * Get the home-directory used by psi.
++ */
++void PluginManager::getHomeDir(QString& dir) {
++	dir = ApplicationInfo::homeDir();
++}
++
++/**
++ * A user from the roster has changed his status.
++ */
++void PluginManager::statusChanged(QString account, QString jid, QString resource, int prio, QString status, QString text) {
++	foreach(PsiPlugin* plugin, plugins_.values() ) {
++		plugin->statusChanged(account, jid, resource, prio, status, text);
++	}
++}
++
++/**
++ * A user from the roster has gone offline
++ */
++void PluginManager::contactOffline(QString account, QString jid) {
++	foreach(PsiPlugin* plugin, plugins_.values() ) {
++		plugin->contactOffline(account, jid);
++	}
++}
++
++/**
++ * A user from the roster has become available
++ */
++void PluginManager::contactOnline(QString account, QString jid) {
++	foreach(PsiPlugin* plugin, plugins_.values() ) {
++		plugin->contactOnline(account, jid);
++	}
++}
++
++/**
++ * A local account has succsesfully logged in
++ */
++void PluginManager::login(QString jid) {
++	foreach(PsiPlugin* plugin, plugins_.values() ) {
++		plugin->login(jid);
++	}
++
++}
++
++/**
++ * Account has logged of from the server.
++ */
++void PluginManager::logout(QString jid) {
++	foreach(PsiPlugin* plugin, plugins_.values() ) {
++		plugin->logout(jid);
++	}
++
++}
++
++void PluginManager::quitProgram() {
++	foreach(PsiPlugin* plugin, plugins_.values() ) {
++		plugin->quitProgram();
++	}
++}
++
++	
+ PluginManager* PluginManager::instance_ = NULL;
+ const QString PluginManager::loadOptionPrefix = "plugins.auto-load";
+ const QString PluginManager::pluginOptionPrefix = "plugins.options";

net-im/psi/files/psi-0.12.1-qt-4.5-compatibility.patch

+--- src/main.cpp.old	2009-02-14 21:52:12.000000000 +0500
++++ src/main.cpp	2009-02-14 21:54:42.000000000 +0500
+@@ -274,9 +274,9 @@
+ 
+ int main(int argc, char *argv[])
+ {
++	PsiApplication app(argc, argv);
+ 	// it must be initialized first in order for ApplicationInfo::resourcesDir() to work
+ 	QCA::Initializer init;
+-	PsiApplication app(argc, argv);
+ 	QApplication::addLibraryPath(ApplicationInfo::resourcesDir());
+ 	QApplication::addLibraryPath(ApplicationInfo::homeDir());
+ 	QApplication::setQuitOnLastWindowClosed(false);

net-im/psi/files/psi-desktop2.patch

+diff -Naur psi-0.10-test3-orig/psi.desktop psi-0.10-test3/psi.desktop
+--- psi-0.10-test3-orig/psi.desktop	2005-11-07 00:39:22.000000000 +0000
++++ psi-0.10-test3/psi.desktop	2005-11-07 01:16:22.000000000 +0000
+@@ -1,7 +1,11 @@
+ Encoding=UTF-8
+ Name=Psi
+ GenericName=Jabber Client
++GenericName[pl]=Klient Jabbera
++GenericName[fr]=Client Jabber
+ Comment=Communicate over the Jabber network
++Comment[pl]=Komunikator sieci Jabber
++Comment[fr]=Communiquer sur le réseau Jabber
+ Icon=psi
+ Exec=psi
+ Terminal=false

net-im/psi/files/psi-echoplugin.patch

+diff -ru psi-dev-snapshot-2007-02-04-orig/src/plugins/generic/echo/echoplugin.cpp psi-dev-snapshot-2007-02-04/src/plugins/generic/echo/echoplugin.cpp
+--- psi-dev-snapshot-2007-02-04-orig/src/plugins/generic/echo/echoplugin.cpp	2007-02-04 06:30:25.000000000 +0100
++++ psi-dev-snapshot-2007-02-04/src/plugins/generic/echo/echoplugin.cpp	2007-02-05 02:29:04.000000000 +0100
+@@ -60,7 +60,7 @@
+ {
+ 	qWarning(qPrintable(QString("Received message '%1', echoing back to %2").arg(message).arg(fromDisplay)));
+ 	QVariant option;
+-	emit getGlobalOption(message, &option);
++	emit getGlobalOption(message, option);
+ 	QString reply;
+ 	if (option.isValid())
+ 		reply=QString("<message to=\"%1\" type=\"chat\"><body>Option %2 = %3 </body></message>").arg(fromJid).arg(message).arg(option.toString());

net-im/psi/files/psi-indicator.png

Added
New image

net-im/psi/files/psi-jingle-gcc4.patch

+Nur in psi-dev-snapshot-2006-10-16.fixed: conf.log.
+Nur in psi-dev-snapshot-2006-10-16.fixed: conf.pri.
+Nur in psi-dev-snapshot-2006-10-16.fixed: Makefile.
+Nur in psi-dev-snapshot-2006-10-16.fixed: psi.
+Nur in psi-dev-snapshot-2006-10-16.fixed/src: config.h.
+Nur in psi-dev-snapshot-2006-10-16.fixed/src: Makefile.
+Nur in psi-dev-snapshot-2006-10-16.fixed/src: .moc.
+Nur in psi-dev-snapshot-2006-10-16.fixed/src: .obj.
+Nur in psi-dev-snapshot-2006-10-16.fixed/src: psi.
+Nur in psi-dev-snapshot-2006-10-16.fixed/src: .rcc.
+Nur in psi-dev-snapshot-2006-10-16.fixed/src: .ui.
+Nur in psi-dev-snapshot-2006-10-16.fixed/third-party/libjingle: liblibjingle.a.
+Nur in psi-dev-snapshot-2006-10-16.fixed/third-party/libjingle: Makefile.
+Nur in psi-dev-snapshot-2006-10-16.fixed/third-party/libjingle: .obj.
+diff -aurp psi-dev-snapshot-2006-10-16/third-party/libjingle/talk/base/base64.h psi-dev-snapshot-2006-10-16.fixed/third-party/libjingle/talk/base/base64.h
+--- psi-dev-snapshot-2006-10-16/third-party/libjingle/talk/base/base64.h	2006-10-16 06:30:14.000000000 +0200
++++ psi-dev-snapshot-2006-10-16.fixed/third-party/libjingle/talk/base/base64.h	2006-10-16 20:44:28.000000000 +0200
+@@ -22,8 +22,8 @@ public:
+   static string decode(const string & data);
+   static string encodeFromArray(const char * data, size_t len);
+ private:
+-  static const string Base64::Base64Table;
+-  static const string::size_type Base64::DecodeTable[];
++  static const string Base64Table;
++  static const string::size_type DecodeTable[];
+ };
+ 
+ #endif
+diff -aurp psi-dev-snapshot-2006-10-16/third-party/libjingle/talk/base/stringutils.h psi-dev-snapshot-2006-10-16.fixed/third-party/libjingle/talk/base/stringutils.h
+--- psi-dev-snapshot-2006-10-16/third-party/libjingle/talk/base/stringutils.h	2006-10-16 06:30:14.000000000 +0200
++++ psi-dev-snapshot-2006-10-16.fixed/third-party/libjingle/talk/base/stringutils.h	2006-10-16 20:45:25.000000000 +0200
+@@ -255,7 +255,7 @@ size_t asccpyn(wchar_t* buffer, size_t b
+ template<>
+ struct Traits<char> {
+   typedef std::string string;
+-  inline static const char* Traits<char>::empty_str() { return ""; }
++  inline static const char* empty_str() { return ""; }
+ };
+ 
+ ///////////////////////////////////////////////////////////////////////////////
+diff -aurp psi-dev-snapshot-2006-10-16/third-party/libjingle/talk/xmpp/xmppclient.h psi-dev-snapshot-2006-10-16.fixed/third-party/libjingle/talk/xmpp/xmppclient.h
+--- psi-dev-snapshot-2006-10-16/third-party/libjingle/talk/xmpp/xmppclient.h	2006-10-16 06:30:14.000000000 +0200
++++ psi-dev-snapshot-2006-10-16.fixed/third-party/libjingle/talk/xmpp/xmppclient.h	2006-10-16 21:12:38.000000000 +0200
+@@ -133,7 +133,7 @@ private:
+     }
+   }
+ 
+-  std::string XmppClient::GetStateName(int state) const {
++  std::string GetStateName(int state) const {
+     switch (state) {
+       case STATE_PRE_XMPP_LOGIN:      return "PRE_XMPP_LOGIN";
+       case STATE_START_XMPP_LOGIN:  return "START_XMPP_LOGIN";
+Nur in psi-dev-snapshot-2006-10-16.fixed/third-party/qca: libqca.a.
+Nur in psi-dev-snapshot-2006-10-16.fixed/third-party/qca: Makefile.
+Nur in psi-dev-snapshot-2006-10-16.fixed/third-party/qca: .moc.
+Nur in psi-dev-snapshot-2006-10-16.fixed/third-party/qca: .obj.

net-im/psi/files/psi-pathfix2.patch

+diff -Naur psi-0.10-test1-orig/src/src.pro psi-0.10-test1/src/src.pro
+--- psi-0.10-test1-orig/src/src.pro	2005-08-21 17:44:36.000000000 +0000
++++ psi-0.10-test1/src/src.pro	2005-08-24 22:19:38.000000000 +0000
+@@ -4,7 +4,7 @@
+ 
+ # Configuration
+ TEMPLATE = app
+-CONFIG  += qt thread x11
++CONFIG  += qt thread x11 no_fixpath
+ 
+ CONFIG += debug
+ #CONFIG += use_crash

net-im/psi/files/psi-ptr_64bit_fix.patch

+diff -Naur psi-dev-snapshot-2007-01-12-orig/src/pluginmanager.cpp psi-dev-snapshot-2007-01-12/src/pluginmanager.cpp
+--- psi-dev-snapshot-2007-01-12-orig/src/pluginmanager.cpp	2007-01-12 06:30:08.000000000 +0100
++++ psi-dev-snapshot-2007-01-12/src/pluginmanager.cpp	2007-01-13 01:54:03.000000000 +0100
+@@ -422,7 +422,6 @@
+  */ 
+ void PluginManager::sendStanza( const PsiAccount* account, const QString& stanza)
+ {
+-	qDebug(qPrintable(QString("Want to send stanza  to account %2").arg((int)account)));
+ 	if (!clients_.contains(account) || !verifyStanza(stanza))
+ 		return;
+ 	clients_[account]->send(stanza);

net-im/psi/files/psi-reverse_trayicon2.patch

+
+Created by Przemysław 'Troll' Maciąg <pmaciag (at) gmail (dot) com>
+
+In cvs for 0.9.3 version somebody broke's trayicon...
+This patch restores ability to show proper trayicon
+in FVWM and few others (light) WM's.
+
+diff -u -p -r1.24 -r1.26
+--- src/tools/trayicon/trayicon_x11.cpp	2004/02/28 16:52:39	1.24
++++ src/tools/trayicon/trayicon_x11.cpp	2004/08/20 03:22:01	1.26
+@@ -251,11 +261,6 @@ TrayIconFreeDesktop::TrayIconFreeDesktop
+ 
+ 	if ( manager_window != None )
+ 		send_message(dsp, manager_window, SYSTEM_TRAY_REQUEST_DOCK, winId(), 0, 0);
+-	else
+-	{
+-		object->hide();
+-		return;
+-	}
+ 
+ 	// some KDE mumbo-jumbo... why is it there? anybody?
+ 	Atom kwm_dockwindow_atom = XInternAtom(dsp, "KWM_DOCKWINDOW", false);
+@@ -345,9 +371,7 @@ void TrayIcon::sysInstall()
+ 		d = (TrayIconPrivate *)(new TrayIconFreeDesktop(this, pm));
+ 
+ 	sysUpdateToolTip();
++	d->show();
+-
+-	if ( v_isWMDock )
+-		d->show();
+ }
+ 
+ void TrayIcon::sysRemove()

net-im/psi/psi-0.12.1.ebuild

+# Copyright 1999-2009 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: /var/cvsroot/gentoo-x86/net-im/psi/psi-0.12.1.ebuild,v 1.9 2009/03/23 10:11:10 pva Exp $
+
+EAPI="2"
+
+inherit eutils qt4 multilib
+
+LANGPACK_VER="20090217"
+
+DESCRIPTION="Qt4 Jabber client, with Licq-like interface"
+HOMEPAGE="http://psi-im.org/"
+SRC_URI="mirror://sourceforge/${PN}/${P}.tar.bz2
+	mirror://gentoo/${PN}-langs-${LANGPACK_VER}.tar.bz2"
+
+LICENSE="GPL-2"
+SLOT="0"
+KEYWORDS="amd64 hppa ppc ppc64 sparc x86 ~x86-fbsd"
+IUSE="crypt dbus debug doc spell ssl xscreensaver otr"
+RESTRICT="test"
+
+LANGS="cs de eo es_ES fr it mk pl pt_BR ru uk ur_PK vi zh zh_TW"
+for LNG in ${LANGS}; do
+	IUSE="${IUSE} linguas_${LNG}"
+	#SRC_URI="${SRC_URI} http://psi-im.org/download/lang/psi_${LNG/ur_PK/ur_pk}.qm"
+done
+
+COMMON_DEPEND=">=x11-libs/qt-gui-4.4:4[qt3support,dbus?]
+	app-crypt/qca:2
+	spell? ( app-text/aspell )
+	xscreensaver? ( x11-libs/libXScrnSaver )"
+
+DEPEND="${COMMON_DEPEND}
+	doc? ( app-doc/doxygen )"
+
+RDEPEND="${COMMON_DEPEND}
+	crypt? ( >=app-crypt/qca-gnupg-2.0.0_beta2 )
+	ssl? ( >=app-crypt/qca-ossl-2.0.0_beta2 )
+	otr? ( =net-libs/libotr-3.1.0 )"
+
+PDEPEND="otr? ( =net-im/psi-otr-0.4 )"
+
+src_prepare() {
+	epatch "${FILESDIR}/${P}-qt-4.5-compatibility.patch"
+	epatch "${FILESDIR}/${P}-build-error.patch"
+	epatch "${FILESDIR}/${P}-plugin-otr.patch"
+}
+
+src_configure() {
+	# disable growl as it is a MacOS X extension only
+	local myconf="--prefix=/usr --qtdir=/usr"
+	myconf="${myconf} --disable-growl --disable-bundled-qca"
+	use debug && myconf="${myconf} --enable-debug"
+	use dbus || myconf="${myconf} --disable-qdbus"
+	use spell || myconf="${myconf} --disable-aspell"
+	use xscreensaver || myconf="${myconf} --disable-xss"
+
+	# cannot use econf because of non-standard configure script
+	./configure ${myconf} || die "configure failed"
+	use otr && echo "DEFINES += PSI_PLUGINS" >> /var/tmp/portage/net-im/${P}/work/${P}/conf.pri \
+	&& echo "CONFIG += psi_plugins" >> /var/tmp/portage/net-im/${P}/work/${P}/conf.pri
+}
+
+src_compile() {
+	eqmake4 ${PN}.pro
+
+	SUBLIBS="-L/usr/${get_libdir}/qca2" emake || die "emake failed"
+
+	if use doc; then
+		cd doc
+		mkdir -p api # 259632
+		make api_public || die "make api_public failed"
+	fi
+}
+
+src_install() {
+	emake INSTALL_ROOT="${D}" install || die "emake install failed"
+
+	# this way the docs will be installed in the standard gentoo dir
+	newdoc iconsets/roster/README README.roster || die
+	newdoc iconsets/system/README README.system || die
+	newdoc certs/README README.certs || die
+	dodoc README || die
+
+	if use doc; then
+		cd doc
+		dohtml -r api || die "dohtml failed"
+	fi
+
+	# install translations
+	cd "${WORKDIR}/${PN}-langs"
+	insinto /usr/share/${PN}/
+	for LNG in ${LANGS}; do
+		if use linguas_${LNG}; then
+			doins ${PN}_${LNG/ur_PK/ur_pk}.qm || die
+		fi
+	done
+}