summaryrefslogtreecommitdiffstats
path: root/kontact_plugin
diff options
context:
space:
mode:
Diffstat (limited to 'kontact_plugin')
-rw-r--r--kontact_plugin/Makefile.am18
-rw-r--r--kontact_plugin/basket.desktop42
-rw-r--r--kontact_plugin/basket_plugin.cpp107
-rw-r--r--kontact_plugin/basket_plugin.h63
-rw-r--r--kontact_plugin/basket_v4.desktop43
-rw-r--r--kontact_plugin/basketdcopiface_stub.cpp56
-rw-r--r--kontact_plugin/kontact_basketplugin.setdlg24
-rw-r--r--kontact_plugin/uniqueapphandler.cpp171
-rw-r--r--kontact_plugin/uniqueapphandler.h120
9 files changed, 644 insertions, 0 deletions
diff --git a/kontact_plugin/Makefile.am b/kontact_plugin/Makefile.am
new file mode 100644
index 0000000..1a63eea
--- /dev/null
+++ b/kontact_plugin/Makefile.am
@@ -0,0 +1,18 @@
+INCLUDES = -I$(top_srcdir)/src -I$(top_builddir)/src -I$(top_srcdir) $(all_includes)
+
+kde_module_LTLIBRARIES = libkontact_basket.la
+libkontact_basket_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN)
+libkontact_basket_la_LIBADD = -lkpinterfaces -lDCOP -lqt-mt -lkdecore -lkdeui
+
+noinst_HEADERS = basket_plugin.h uniqueapphandler.h
+libkontact_basket_la_SOURCES = basket_plugin.cpp uniqueapphandler.cpp basketdcopiface.stub
+
+METASOURCES = AUTO
+
+basketdcopiface_DIR = $(top_srcdir)/src
+
+servicedir = $(kde_servicesdir)/kontact
+service_DATA = basket.desktop basket_v4.desktop
+
+basketsetdlgdir = $(kde_datadir)/kontact/ksettingsdialog
+basketsetdlg_DATA = kontact_basketplugin.setdlg
diff --git a/kontact_plugin/basket.desktop b/kontact_plugin/basket.desktop
new file mode 100644
index 0000000..67cb657
--- /dev/null
+++ b/kontact_plugin/basket.desktop
@@ -0,0 +1,42 @@
+[Desktop Entry]
+Encoding=UTF-8
+Type=Service
+Icon=basket
+ServiceTypes=Kontact/Plugin,KPluginInfo
+
+X-KDE-Library=libkontact_basket
+X-KDE-KontactPluginVersion=5
+X-KDE-KontactPartLibraryName=libbasketpart
+X-KDE-KontactPartExecutableName=basket
+X-KDE-KontactPartLoadOnStart=true
+X-KDE-KontactPluginHasSummary=false
+
+X-KDE-PluginInfo-Website=http://basket.kde.org/
+X-KDE-PluginInfo-Name=kontact_basketplugin
+X-KDE-PluginInfo-Version=1.0.3.1
+X-KDE-PluginInfo-License=GPL
+X-KDE-PluginInfo-EnabledByDefault=true
+
+Comment=BasKet Note Pads plugin for Kontact
+Comment[de]=Plugin BasKet Notizblätter für Kontact
+Comment[es]=Complemento de los blocs de notas BasKet para Kontact
+Comment[fr]=Module Blocs notes BasKet pour Kontact
+Comment[it]=Plugin Blocco appunti BasKet per Kontact
+Comment[ja]=BasKet メモパッドの Kontact 統合プラグイン
+Comment[nb]=Kurvnotat-tillegg for Kontakt
+Comment[nn]=Korgnotat-tillegg for Kontakt
+Comment[pt]=Plugin do Bloco de Notas BasKet para o Kontact
+Comment[ru]=Модуль Альбом заметок Basket для Kontact
+Comment[tr]=Kontact için Basket Not Tutucu Eklentisi
+
+Name=Baskets
+Name[de]=Körbe
+Name[es]=Cestas
+Name[fr]=Paniers
+Name[it]=Canestri
+Name[ja]=バスケット
+Name[nb]=Kurver
+Name[nn]=Korger
+Name[pt]=Cestos
+Name[ru]=Корзины
+Name[tr]=Sepetler
diff --git a/kontact_plugin/basket_plugin.cpp b/kontact_plugin/basket_plugin.cpp
new file mode 100644
index 0000000..ea92b33
--- /dev/null
+++ b/kontact_plugin/basket_plugin.cpp
@@ -0,0 +1,107 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Petri Damsten *
+ * damu@iki.fi *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#include <kgenericfactory.h>
+#include <kparts/componentfactory.h>
+#include <kontact/core.h>
+#include <klocale.h>
+#include <kcmdlineargs.h>
+#include <dcopref.h>
+#include "basketdcopiface_stub.h"
+#include "basket_plugin.h"
+#include "basket_options.h"
+#include "basket_part.h"
+
+typedef KGenericFactory<BasketPlugin, Kontact::Core> BasketPluginFactory;
+K_EXPORT_COMPONENT_FACTORY( libkontact_basket,
+ BasketPluginFactory( "kontact_basketplugin" ) )
+
+BasketPlugin::BasketPlugin( Kontact::Core *core, const char *, const QStringList& )
+ : Kontact::Plugin( core, core, "basket" )
+{
+ setInstance( BasketPluginFactory::instance() );
+ insertNewAction(new KAction( i18n("&New Basket..."), "basket", CTRL+SHIFT+Key_B,
+ this, SLOT(newBasket()), actionCollection(), "basket_new" ));
+
+ m_uniqueAppWatcher = new Kontact::UniqueAppWatcher(
+ new Kontact::UniqueAppHandlerFactory<BasketUniqueAppHandler>(), this);
+}
+
+BasketPlugin::~BasketPlugin()
+{
+}
+
+KParts::ReadOnlyPart* BasketPlugin::createPart()
+{
+ BasketPart* part = static_cast<BasketPart*>(loadPart());
+ if(!part)
+ return 0;
+
+ m_stub = new BasketDcopInterface_stub(dcopClient(), "basket", "BasketIface");
+ connect(part, SIGNAL(showPart()), this, SLOT(showPart()));
+ return part;
+}
+
+void BasketPlugin::newBasket()
+{
+ (void) part(); // ensure part is loaded
+ Q_ASSERT(m_stub);
+ if (m_stub) {
+ kdDebug() << k_funcinfo << endl;
+ m_stub->newBasket();
+ }
+}
+
+void BasketPlugin::showPart()
+{
+ core()->selectPlugin(this);
+}
+
+#if 0
+bool BasketPlugin::createDCOPInterface( const QString& serviceType )
+{
+ kdDebug() << k_funcinfo << serviceType << endl;
+ return false;
+}
+#endif
+bool BasketPlugin::isRunningStandalone()
+{
+ return m_uniqueAppWatcher->isRunningStandalone();
+}
+
+void BasketUniqueAppHandler::loadCommandLineOptions()
+{
+ KCmdLineArgs::addCmdLineOptions(basket_options);
+}
+
+int BasketUniqueAppHandler::newInstance()
+{
+ (void)plugin()->part();
+ DCOPRef kmail("basket", "BasketIface");
+ DCOPReply reply = kmail.call("handleCommandLine", false);
+ if (reply.isValid()) {
+ bool handled = reply;
+ if ( !handled )
+ return Kontact::UniqueAppHandler::newInstance();
+ }
+ return 0;
+}
+
+#include "basket_plugin.moc"
diff --git a/kontact_plugin/basket_plugin.h b/kontact_plugin/basket_plugin.h
new file mode 100644
index 0000000..f49cef1
--- /dev/null
+++ b/kontact_plugin/basket_plugin.h
@@ -0,0 +1,63 @@
+/***************************************************************************
+ * Copyright (C) 2006 by Petri Damsten *
+ * damu@iki.fi *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
+ ***************************************************************************/
+
+#ifndef BASKET_PLUGIN_H
+#define BASKET_PLUGIN_H
+
+#include <klocale.h>
+#include <kparts/part.h>
+#include <kontact/plugin.h>
+#include "uniqueapphandler.h"
+#include "basketdcopiface_stub.h"
+
+class KAboutData;
+
+class BasketUniqueAppHandler : public Kontact::UniqueAppHandler
+{
+ public:
+ BasketUniqueAppHandler( Kontact::Plugin* plugin ) : Kontact::UniqueAppHandler( plugin ) {}
+ virtual void loadCommandLineOptions();
+ virtual int newInstance();
+};
+
+class BasketPlugin : public Kontact::Plugin
+{
+ Q_OBJECT
+
+ public:
+ BasketPlugin( Kontact::Core *core, const char *name,
+ const QStringList & );
+ ~BasketPlugin();
+
+ int weight() const { return 700; }
+ virtual bool isRunningStandalone();
+ //virtual bool createDCOPInterface( const QString& serviceType );
+
+ public slots:
+ void newBasket();
+ void showPart();
+
+ protected:
+ KParts::ReadOnlyPart *createPart();
+ BasketDcopInterface_stub *m_stub;
+ Kontact::UniqueAppWatcher *m_uniqueAppWatcher;
+};
+
+#endif
diff --git a/kontact_plugin/basket_v4.desktop b/kontact_plugin/basket_v4.desktop
new file mode 100644
index 0000000..84954a5
--- /dev/null
+++ b/kontact_plugin/basket_v4.desktop
@@ -0,0 +1,43 @@
+[Desktop Entry]
+Encoding=UTF-8
+Type=Service
+Icon=basket
+ServiceTypes=Kontact/Plugin,KPluginInfo
+
+X-KDE-Library=libkontact_basket
+X-KDE-KontactPluginVersion=4
+X-KDE-KontactPartLibraryName=libbasketpart
+X-KDE-KontactPartExecutableName=basket
+X-KDE-KontactPartLoadOnStart=true
+X-KDE-KontactPluginHasSummary=false
+
+X-KDE-PluginInfo-Website=http://basket.kde.org/
+X-KDE-PluginInfo-Name=kontact_basketplugin
+X-KDE-PluginInfo-Version=1.0.3.1
+X-KDE-PluginInfo-License=GPL
+X-KDE-PluginInfo-EnabledByDefault=true
+
+Comment=BasKet Note Pads plugin for Kontact
+Comment[de]=Plugin BasKet Notizblätter für Kontact
+Comment[es]=Complemento de los blocs de notas BasKet para Kontact
+Comment[fr]=Module Blocs notes BasKet pour Kontact
+Comment[it]=Plugin Blocco appunti BasKet per Kontact
+Comment[ja]=BasKet メモパッドの Kontact 統合プラグイン
+Comment[nb]=Kurvnotat-tillegg for Kontakt
+Comment[nn]=Korgnotat-tillegg for Kontakt
+Comment[pt]=Plugin do Bloco de Notas BasKet para o Kontact
+Comment[ru]=Модуль Альбом заметок Basket для Kontact
+Comment[tr]=Kontact için Basket Not Tutucu Eklentisi
+
+Name=Baskets
+Name[de]=Körbe
+Name[es]=Cestas
+Name[fr]=Paniers
+Name[it]=Canestri
+Name[ja]=バスケット
+Name[nb]=Kurver
+Name[nn]=Korger
+Name[pt]=Cestos
+Name[ru]=Корзины
+Name[tr]=Sepetler
+
diff --git a/kontact_plugin/basketdcopiface_stub.cpp b/kontact_plugin/basketdcopiface_stub.cpp
new file mode 100644
index 0000000..eff3122
--- /dev/null
+++ b/kontact_plugin/basketdcopiface_stub.cpp
@@ -0,0 +1,56 @@
+/****************************************************************************
+**
+** DCOP Stub Implementation created by dcopidl2cpp from basketdcopiface.kidl
+**
+** WARNING! All changes made in this file will be lost!
+**
+*****************************************************************************/
+
+#include "basketdcopiface_stub.h"
+#include <dcopclient.h>
+
+#include <kdatastream.h>
+
+
+BasketDcopInterface_stub::BasketDcopInterface_stub( const QCString& app, const QCString& obj )
+ : DCOPStub( app, obj )
+{
+}
+
+BasketDcopInterface_stub::BasketDcopInterface_stub( DCOPClient* client, const QCString& app, const QCString& obj )
+ : DCOPStub( client, app, obj )
+{
+}
+
+BasketDcopInterface_stub::BasketDcopInterface_stub( const DCOPRef& ref )
+ : DCOPStub( ref )
+{
+}
+
+void BasketDcopInterface_stub::newBasket()
+{
+ if ( !dcopClient() ) {
+ setStatus( CallFailed );
+ return;
+ }
+ QByteArray data;
+ dcopClient()->send( app(), obj(), "newBasket()", data );
+ setStatus( CallSucceeded );
+}
+
+void BasketDcopInterface_stub::handleCommandLine()
+{
+ if ( !dcopClient() ) {
+ setStatus( CallFailed );
+ return;
+ }
+ QByteArray data, replyData;
+ QCString replyType;
+ if ( dcopClient()->call( app(), obj(), "handleCommandLine()", data, replyType, replyData ) ) {
+ setStatus( CallSucceeded );
+ } else {
+ callFailed();
+ }
+}
+
+
diff --git a/kontact_plugin/kontact_basketplugin.setdlg b/kontact_plugin/kontact_basketplugin.setdlg
new file mode 100644
index 0000000..b6f9b29
--- /dev/null
+++ b/kontact_plugin/kontact_basketplugin.setdlg
@@ -0,0 +1,24 @@
+[Basket]
+Name=Baskets
+Name[de]=Körbe
+Name[es]=Cestas
+Name[fr]=Paniers
+Name[it]=Canestri
+Name[ja]=バスケット
+Name[nb]=Kurver
+Name[nn]=Korger
+Name[es]=Cestas
+Name[pt]=Cestos
+Name[ru]=Корзины
+Comment=BasKet Note Pads component
+Comment[de]=Komponente BasKet Notizblätter
+Comment[es]=Componente para las notas de basket
+Comment[fr]=Composant Blocs notes BasKet
+Comment[it]=Componente Blocco appunti BasKet
+Comment[ja]=BasKet メモパッドコンポーネント
+Comment[nb]=Kurvnotat-komponent
+Comment[nn]=Korgnotat-komponent
+Comment[es]=Componente para las notas de basket
+Comment[pt]=Componente do Bloco de Notas BasKet
+Comment[ru]=Модуль Альбом заметок Basket для Kontact
+Icon=basket
diff --git a/kontact_plugin/uniqueapphandler.cpp b/kontact_plugin/uniqueapphandler.cpp
new file mode 100644
index 0000000..29dc888
--- /dev/null
+++ b/kontact_plugin/uniqueapphandler.cpp
@@ -0,0 +1,171 @@
+/*
+ This file is part of KDE Kontact.
+
+ Copyright (c) 2003 David Faure <faure@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#include "uniqueapphandler.h"
+#include <kstartupinfo.h>
+#include <kapplication.h>
+#include <kcmdlineargs.h>
+#include <kontact/core.h>
+#include <kwin.h>
+#include <dcopclient.h>
+#include <kdebug.h>
+
+/*
+ Test plan for the various cases of interaction between standalone apps and kontact:
+
+ 1) start kontact, select "Mail".
+ 1a) type "korganizer" -> it switches to korganizer
+ 1b) type "kmail" -> it switches to kmail
+ 1c) type "kaddressbook" -> it switches to kaddressbook
+ 1d) type "kmail foo@kde.org" -> it opens a kmail composer, without switching
+ 1e) type "knode" -> it switches to knode
+ 1f) type "kaddressbook --new-contact" -> it opens a kaddressbook contact window
+ 1g) type "knode news://foobar/group" -> it pops up "can't resolve hostname"
+
+ 2) close kontact. Launch kmail. Launch kontact again.
+ 2a) click "Mail" icon -> kontact doesn't load a part, but activates the kmail window
+ 2b) type "kmail foo@kde.org" -> standalone kmail opens composer.
+ 2c) close kmail, click "Mail" icon -> kontact loads the kmail part.
+ 2d) type "kmail" -> kontact is brought to front
+
+ 3) close kontact. Launch korganizer, then kontact.
+ 3a) both Todo and Calendar activate the running korganizer.
+ 3b) type "korganizer" -> standalone korganizer is brought to front
+ 3c) close korganizer, click Calendar or Todo -> kontact loads part.
+ 3d) type "korganizer" -> kontact is brought to front
+
+ 4) close kontact. Launch kaddressbook, then kontact.
+ 4a) "Contacts" icon activate the running kaddressbook.
+ 4b) type "kaddressbook" -> standalone kaddressbook is brought to front
+ 4c) close kaddressbook, type "kaddressbook -a foo@kde.org" -> kontact loads part and opens editor
+ 4d) type "kaddressbook" -> kontact is brought to front
+
+ 5) close kontact. Launch knode, then kontact.
+ 5a) "News" icon activate the running knode.
+ 5b) type "knode" -> standalone knode is brought to front
+ 5c) close knode, type "knode news://foobar/group" -> kontact loads knode and pops up msgbox
+ 5d) type "knode" -> kontact is brought to front
+
+*/
+
+using namespace Kontact;
+
+int UniqueAppHandler::newInstance()
+{
+ // This bit is duplicated from KUniqueApplication::newInstance()
+ if ( kapp->mainWidget() ) {
+ kapp->mainWidget()->show();
+ KWin::forceActiveWindow( kapp->mainWidget()->winId() );
+ KStartupInfo::appStarted();
+ }
+
+ // Then ensure the part appears in kontact
+ mPlugin->core()->selectPlugin( mPlugin );
+ return 0;
+}
+
+bool UniqueAppHandler::process( const QCString &fun, const QByteArray &data,
+ QCString& replyType, QByteArray &replyData )
+{
+ if ( fun == "newInstance()" ) {
+ replyType = "int";
+
+ KCmdLineArgs::reset(); // forget options defined by other "applications"
+ loadCommandLineOptions();
+
+ // This bit is duplicated from KUniqueApplication::processDelayed()
+ QDataStream ds( data, IO_ReadOnly );
+ KCmdLineArgs::loadAppArgs( ds );
+ if ( !ds.atEnd() ) { // backwards compatibility
+ QCString asn_id;
+ ds >> asn_id;
+ kapp->setStartupId( asn_id );
+ }
+
+ QDataStream _replyStream( replyData, IO_WriteOnly );
+ _replyStream << newInstance( );
+ } else if ( fun == "load()" ) {
+ replyType = "bool";
+ (void)mPlugin->part(); // load the part without bringing it to front
+
+ QDataStream _replyStream( replyData, IO_WriteOnly );
+ _replyStream << true;
+ } else {
+ return DCOPObject::process( fun, data, replyType, replyData );
+ }
+ return true;
+}
+
+QCStringList UniqueAppHandler::interfaces()
+{
+ QCStringList ifaces = DCOPObject::interfaces();
+ ifaces += "Kontact::UniqueAppHandler";
+ return ifaces;
+}
+
+QCStringList UniqueAppHandler::functions()
+{
+ QCStringList funcs = DCOPObject::functions();
+ funcs << "int newInstance()";
+ funcs << "bool load()";
+ return funcs;
+}
+
+UniqueAppWatcher::UniqueAppWatcher( UniqueAppHandlerFactoryBase* factory, Plugin* plugin )
+ : QObject( plugin ), mFactory( factory ), mPlugin( plugin )
+{
+ // The app is running standalone if 1) that name is known to DCOP
+ mRunningStandalone = kapp->dcopClient()->isApplicationRegistered( plugin->name() );
+
+ // and 2) it's not registered by kontact (e.g. in another plugin)
+ if ( mRunningStandalone && kapp->dcopClient()->findLocalClient( plugin->name() ) )
+ mRunningStandalone = false;
+
+ if ( mRunningStandalone ) {
+ kapp->dcopClient()->setNotifications( true );
+ connect( kapp->dcopClient(), SIGNAL( applicationRemoved( const QCString& ) ),
+ this, SLOT( unregisteredFromDCOP( const QCString& ) ) );
+ } else {
+ mFactory->createHandler( mPlugin );
+ }
+}
+
+UniqueAppWatcher::~UniqueAppWatcher()
+{
+ if ( mRunningStandalone )
+ kapp->dcopClient()->setNotifications( false );
+
+ delete mFactory;
+}
+
+void UniqueAppWatcher::unregisteredFromDCOP( const QCString& appId )
+{
+ if ( appId == mPlugin->name() && mRunningStandalone ) {
+ disconnect( kapp->dcopClient(), SIGNAL( applicationRemoved( const QCString& ) ),
+ this, SLOT( unregisteredFromDCOP( const QCString& ) ) );
+ kdDebug(5601) << k_funcinfo << appId << endl;
+ mFactory->createHandler( mPlugin );
+ kapp->dcopClient()->setNotifications( false );
+ mRunningStandalone = false;
+ }
+}
+
+#include "uniqueapphandler.moc"
diff --git a/kontact_plugin/uniqueapphandler.h b/kontact_plugin/uniqueapphandler.h
new file mode 100644
index 0000000..e954eb7
--- /dev/null
+++ b/kontact_plugin/uniqueapphandler.h
@@ -0,0 +1,120 @@
+/*
+ This file is part of KDE Kontact.
+
+ Copyright (c) 2003 David Faure <faure@kde.org>
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public License
+ along with this library; see the file COPYING.LIB. If not, write to
+ the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ Boston, MA 02110-1301, USA.
+*/
+
+#ifndef KONTACT_UNIQUEAPPHANDLER_H
+#define KONTACT_UNIQUEAPPHANDLER_H
+
+#include <dcopobject.h>
+#include <kontact/plugin.h>
+#include <kdepimmacros.h>
+
+namespace Kontact
+{
+
+/**
+ * DCOP Object that has the name of the standalone application (e.g. "kmail")
+ * and implements newInstance() so that running the separate application does
+ * the right thing when kontact is running.
+ * By default this means simply bringing the main window to the front,
+ * but newInstance can be reimplemented.
+ */
+class KDE_EXPORT UniqueAppHandler : public DCOPObject
+{
+ K_DCOP
+
+ public:
+ UniqueAppHandler( Plugin* plugin ) : DCOPObject( plugin->name() ), mPlugin( plugin ) {}
+
+ /// This must be reimplemented so that app-specific command line options can be parsed
+ virtual void loadCommandLineOptions() = 0;
+
+ /// We can't use k_dcop and dcopidl here, because the data passed
+ /// to newInstance can't be expressed in terms of normal data types.
+ virtual int newInstance();
+
+ Plugin* plugin() const { return mPlugin; }
+
+ private:
+ Plugin* mPlugin;
+};
+
+/// Base class for UniqueAppHandler
+class UniqueAppHandlerFactoryBase
+{
+ public:
+ virtual UniqueAppHandler* createHandler( Plugin* ) = 0;
+};
+
+/**
+ * Used by UniqueAppWatcher below, to create the above UniqueAppHandler object
+ * when necessary.
+ * The template argument is the UniqueAppHandler-derived class.
+ * This allows to remove the need to subclass UniqueAppWatcher.
+ */
+template <class T> class UniqueAppHandlerFactory : public UniqueAppHandlerFactoryBase
+{
+ public:
+ virtual UniqueAppHandler* createHandler( Plugin* plugin ) {
+ (void)plugin->dcopClient(); // ensure that we take over the DCOP name
+ return new T( plugin );
+ }
+};
+
+
+/**
+ * If the standalone application is running by itself, we need to watch
+ * for when the user closes it, and activate the uniqueapphandler then.
+ * This prevents, on purpose, that the standalone app can be restarted.
+ * Kontact takes over from there.
+ *
+ */
+class KDE_EXPORT UniqueAppWatcher : public QObject
+{
+ Q_OBJECT
+
+ public:
+ /**
+ * Create an instance of UniqueAppWatcher, which does everything necessary
+ * for the "unique application" behavior: create the UniqueAppHandler as soon
+ * as possible, i.e. either right now or when the standalone app is closed.
+ *
+ * @param factory templatized factory to create the handler. Example:
+ * ... Note that the watcher takes ownership of the factory.
+ * @param plugin is the plugin application
+ */
+ UniqueAppWatcher( UniqueAppHandlerFactoryBase* factory, Plugin* plugin );
+
+ virtual ~UniqueAppWatcher();
+
+ bool isRunningStandalone() const { return mRunningStandalone; }
+
+ protected slots:
+ void unregisteredFromDCOP( const QCString& appId );
+
+ private:
+ bool mRunningStandalone;
+ UniqueAppHandlerFactoryBase* mFactory;
+ Plugin* mPlugin;
+};
+
+} // namespace
+
+#endif /* KONTACT_UNIQUEAPPHANDLER_H */