summaryrefslogtreecommitdiffstats
path: root/kontact/interfaces
diff options
context:
space:
mode:
authortoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
committertoma <toma@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-11-25 17:56:58 +0000
commit460c52653ab0dcca6f19a4f492ed2c5e4e963ab0 (patch)
tree67208f7c145782a7e90b123b982ca78d88cc2c87 /kontact/interfaces
downloadtdepim-460c52653ab0dcca6f19a4f492ed2c5e4e963ab0.tar.gz
tdepim-460c52653ab0dcca6f19a4f492ed2c5e4e963ab0.zip
Copy the KDE 3.5 branch to branches/trinity for new KDE 3.5 features.
BUG:215923 git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdepim@1054174 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kontact/interfaces')
-rw-r--r--kontact/interfaces/Makefile.am15
-rw-r--r--kontact/interfaces/core.cpp129
-rw-r--r--kontact/interfaces/core.h102
-rw-r--r--kontact/interfaces/kontactplugin.desktop71
-rw-r--r--kontact/interfaces/plugin.cpp259
-rw-r--r--kontact/interfaces/plugin.h291
-rw-r--r--kontact/interfaces/summary.cpp116
-rw-r--r--kontact/interfaces/summary.h94
-rw-r--r--kontact/interfaces/uniqueapphandler.cpp201
-rw-r--r--kontact/interfaces/uniqueapphandler.h123
10 files changed, 1401 insertions, 0 deletions
diff --git a/kontact/interfaces/Makefile.am b/kontact/interfaces/Makefile.am
new file mode 100644
index 000000000..94a15dda3
--- /dev/null
+++ b/kontact/interfaces/Makefile.am
@@ -0,0 +1,15 @@
+INCLUDES = -I$(top_srcdir) $(all_includes)
+
+lib_LTLIBRARIES = libkpinterfaces.la
+
+libkpinterfaces_la_SOURCES = core.cpp plugin.cpp summary.cpp uniqueapphandler.cpp
+libkpinterfaces_la_LDFLAGS = $(all_libraries) -no-undefined -version-info 1:0:0
+libkpinterfaces_la_LIBADD = ../../libkdepim/libkdepim.la $(LIB_KPARTS)
+
+kpincludedir = $(includedir)/kontact
+kpinclude_HEADERS = core.h plugin.h summary.h
+
+METASOURCES = AUTO
+
+servicetypedir = $(kde_servicetypesdir)
+servicetype_DATA = kontactplugin.desktop
diff --git a/kontact/interfaces/core.cpp b/kontact/interfaces/core.cpp
new file mode 100644
index 000000000..19ed8bade
--- /dev/null
+++ b/kontact/interfaces/core.cpp
@@ -0,0 +1,129 @@
+/*
+ This file is part of KDE Kontact.
+
+ Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org>
+ Copyright (c) 2002-2003 Daniel Molkentin <molkentin@kde.org>
+ Copyright (c) 2003 Cornelius Schumacher <schumacher@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 "core.h"
+
+#include <kparts/part.h>
+#include <kparts/componentfactory.h>
+#include <kdebug.h>
+#include <qtimer.h>
+#include <klocale.h>
+
+using namespace Kontact;
+
+class Core::Private
+{
+public:
+ QString lastErrorMessage;
+};
+
+Core::Core( QWidget *parent, const char *name )
+ : KParts::MainWindow( parent, name )
+{
+ d = new Private;
+ QTimer* timer = new QTimer( this );
+ mLastDate = QDate::currentDate();
+ connect(timer, SIGNAL( timeout() ), SLOT( checkNewDay() ) );
+ timer->start( 1000*60 );
+}
+
+Core::~Core()
+{
+ delete d;
+}
+
+KParts::ReadOnlyPart *Core::createPart( const char *libname )
+{
+ kdDebug(5601) << "Core::createPart(): " << libname << endl;
+
+ QMap<QCString,KParts::ReadOnlyPart *>::ConstIterator it;
+ it = mParts.find( libname );
+ if ( it != mParts.end() ) return it.data();
+
+ kdDebug(5601) << "Creating new KPart" << endl;
+
+ int error = 0;
+ KParts::ReadOnlyPart *part =
+ KParts::ComponentFactory::
+ createPartInstanceFromLibrary<KParts::ReadOnlyPart>
+ ( libname, this, 0, this, "kontact", QStringList(), &error );
+
+ KParts::ReadOnlyPart *pimPart = dynamic_cast<KParts::ReadOnlyPart*>( part );
+ if ( pimPart ) {
+ mParts.insert( libname, pimPart );
+ QObject::connect( pimPart, SIGNAL( destroyed( QObject * ) ),
+ SLOT( slotPartDestroyed( QObject * ) ) );
+ } else {
+ // TODO move to KParts::ComponentFactory
+ switch( error ) {
+ case KParts::ComponentFactory::ErrNoServiceFound:
+ d->lastErrorMessage = i18n( "No service found" );
+ break;
+ case KParts::ComponentFactory::ErrServiceProvidesNoLibrary:
+ d->lastErrorMessage = i18n( "Program error: the .desktop file for the service does not have a Library key." );
+ break;
+ case KParts::ComponentFactory::ErrNoLibrary:
+ d->lastErrorMessage = KLibLoader::self()->lastErrorMessage();
+ break;
+ case KParts::ComponentFactory::ErrNoFactory:
+ d->lastErrorMessage = i18n( "Program error: the library %1 does not provide a factory." ).arg( libname );
+ break;
+ case KParts::ComponentFactory::ErrNoComponent:
+ d->lastErrorMessage = i18n( "Program error: the library %1 does not support creating components of the specified type" ).arg( libname );
+ break;
+ }
+ kdWarning(5601) << d->lastErrorMessage << endl;
+ }
+
+ return pimPart;
+}
+
+void Core::slotPartDestroyed( QObject * obj )
+{
+ // the part was deleted, we need to remove it from the part map to not return
+ // a dangling pointer in createPart
+ QMap<QCString, KParts::ReadOnlyPart*>::Iterator end = mParts.end();
+ QMap<QCString, KParts::ReadOnlyPart*>::Iterator it = mParts.begin();
+ for ( ; it != end; ++it ) {
+ if ( it.data() == obj ) {
+ mParts.remove( it );
+ return;
+ }
+ }
+}
+
+void Core::checkNewDay()
+{
+ if ( mLastDate != QDate::currentDate() )
+ emit dayChanged( QDate::currentDate() );
+
+ mLastDate = QDate::currentDate();
+}
+
+QString Core::lastErrorMessage() const
+{
+ return d->lastErrorMessage;
+}
+
+#include "core.moc"
+// vim: sw=2 sts=2 et tw=80
diff --git a/kontact/interfaces/core.h b/kontact/interfaces/core.h
new file mode 100644
index 000000000..2ebe088f9
--- /dev/null
+++ b/kontact/interfaces/core.h
@@ -0,0 +1,102 @@
+/*
+ This file is part of KDE Kontact.
+
+ Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org>
+ Copyright (c) 2002-2003 Daniel Molkentin <molkentin@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_CORE_H
+#define KONTACT_CORE_H
+
+#include <qdatetime.h>
+#include <kdepimmacros.h>
+#include <kparts/mainwindow.h>
+#include <kparts/part.h>
+
+class KAction;
+
+namespace Kontact
+{
+
+class Plugin;
+
+/**
+ This class provides the interface to the Kontact core for the plugins.
+*/
+class KDE_EXPORT Core : public KParts::MainWindow
+{
+ Q_OBJECT
+ public:
+ virtual ~Core();
+
+ /**
+ Selects the given plugin @param plugin and raises the associated
+ part.
+ */
+ virtual void selectPlugin( Kontact::Plugin *plugin ) = 0;
+
+ /**
+ This is an overloaded member function. It behaves essentially like the
+ above function.
+ */
+ virtual void selectPlugin( const QString &plugin ) = 0;
+
+ /**
+ Returns the pointer list of available plugins.
+ */
+ virtual QValueList<Kontact::Plugin*> pluginList() const = 0;
+
+ /**
+ @internal (for Plugin)
+ */
+ KParts::ReadOnlyPart *createPart( const char *libname );
+
+ /**
+ @internal (for Plugin)
+ Tell kontact that a part was loaded
+ */
+ virtual void partLoaded( Plugin* plugin, KParts::ReadOnlyPart * part ) = 0;
+
+ signals:
+ /**
+ Emitted when a new day starts
+ */
+ void dayChanged( const QDate& );
+
+ protected:
+ Core( QWidget *parentWidget = 0, const char *name = 0 );
+
+ QString lastErrorMessage() const;
+
+ private slots:
+ void slotPartDestroyed( QObject * );
+ void checkNewDay();
+
+ private:
+ QMap<QCString,KParts::ReadOnlyPart *> mParts;
+ QDate mLastDate;
+
+ class Private;
+ Private *d;
+};
+
+}
+
+#endif
+
+// vim: sw=2 sts=2 et tw=80
diff --git a/kontact/interfaces/kontactplugin.desktop b/kontact/interfaces/kontactplugin.desktop
new file mode 100644
index 000000000..28803bc6d
--- /dev/null
+++ b/kontact/interfaces/kontactplugin.desktop
@@ -0,0 +1,71 @@
+[Desktop Entry]
+Type=ServiceType
+X-KDE-ServiceType=Kontact/Plugin
+Name=Kontact Plugin
+Name[af]=Kontact inprop module
+Name[ar]=قابس Kontact
+Name[be]=Дапаўненне Кантакту
+Name[bg]=Приставка на Kontact
+Name[br]=Lugent Kontact
+Name[bs]=Dodatak za Kontact
+Name[ca]=Endollable Kontact
+Name[cs]=Modul aplikace Kontact
+Name[cy]=Ategyn Kontact
+Name[da]=Kontact-plugin
+Name[de]=Kontact-Modul
+Name[el]=Πρόσθετο Kontact
+Name[es]=Plugin Kontact
+Name[et]=Kontacti plugin
+Name[eu]=Kontact plugin-a
+Name[fa]=وصلۀ Kontact
+Name[fi]=Kontact-liitännäinen
+Name[fr]=Module Kontact
+Name[ga]=Breiseán Kontact
+Name[gl]=Extensión de Kontact
+Name[he]=תוסף Kontact
+Name[hi]=कॉन्टेक्ट प्लगइन
+Name[hu]=Kontact-bővítőmodul
+Name[is]=Kontact íforrit
+Name[it]=Plugin Kontact
+Name[ja]=Kontact プラグイン
+Name[ka]=Kontact მოდული
+Name[kk]=Kontact модулі
+Name[km]=កម្មវិធី​ជំនួយ Kontact
+Name[lt]=Kontact priedas
+Name[mk]=Приклучок за Контакт
+Name[ms]=Plugin Kontact
+Name[nb]=Kontact-programtillegg
+Name[nds]=Kontact-Moduul
+Name[ne]=सम्पर्क प्लगइन
+Name[nn]=Kontact-programtillegg
+Name[pl]=Wtyczka Kontakt
+Name[pt]='Plugin' do Kontact
+Name[pt_BR]=Plug-in do Kontact
+Name[ro]=Modul Kontact
+Name[ru]=Модуль Kontact
+Name[se]=Kontact-lassemoduvla
+Name[sl]=Vstavek za Kontact
+Name[sr]=Прикључак Kontact-а
+Name[sr@Latn]=Priključak Kontact-a
+Name[sv]=Kontact-insticksprogram
+Name[ta]=சொருகுப்பொருளை தொடர்புக்கொள்
+Name[tg]=Модули Kontact
+Name[tr]=Kontact Eklentisi
+Name[uk]=Втулок Kontact
+Name[uz]=Kontact uchun plagin
+Name[uz@cyrillic]=Kontact учун плагин
+Name[zh_CN]=Kontact 插件
+Name[zh_TW]=Kontack 外掛程式
+
+[PropertyDef::X-KDE-KontactPluginVersion]
+Type=int
+[PropertyDef::X-KDE-KontactPartLibraryName]
+Type=QString
+[PropertyDef::X-KDE-KontactPartExecutableName]
+Type=QString
+[PropertyDef::X-KDE-KontactPartLoadOnStart]
+Type=bool
+[PropertyDef::X-KDE-KontactPluginHasSummary]
+Type=bool
+[PropertyDef::X-KDE-KontactPluginHasPart]
+Type=bool
diff --git a/kontact/interfaces/plugin.cpp b/kontact/interfaces/plugin.cpp
new file mode 100644
index 000000000..33662015c
--- /dev/null
+++ b/kontact/interfaces/plugin.cpp
@@ -0,0 +1,259 @@
+/*
+ This file is part of KDE Kontact.
+
+ Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org>
+ Copyright (c) 2002-2003 Daniel Molkentin <molkentin@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 <qobjectlist.h>
+
+#include <dcopclient.h>
+#include <kaboutdata.h>
+#include <kglobal.h>
+#include <kparts/componentfactory.h>
+#include <kdebug.h>
+#include <kinstance.h>
+#include <krun.h>
+
+#include "core.h"
+#include "plugin.h"
+
+using namespace Kontact;
+
+class Plugin::Private
+{
+ public:
+ Kontact::Core *core;
+ DCOPClient *dcopClient;
+ QPtrList<KAction> *newActions;
+ QPtrList<KAction> *syncActions;
+ QString identifier;
+ QString title;
+ QString icon;
+ QString executableName;
+ QCString partLibraryName;
+ bool hasPart;
+ KParts::ReadOnlyPart *part;
+ bool disabled;
+};
+
+
+Plugin::Plugin( Kontact::Core *core, QObject *parent, const char *name )
+ : KXMLGUIClient( core ), QObject( parent, name ), d( new Private )
+{
+ core->factory()->addClient( this );
+ KGlobal::locale()->insertCatalogue(name);
+
+ d->core = core;
+ d->dcopClient = 0;
+ d->newActions = new QPtrList<KAction>;
+ d->syncActions = new QPtrList<KAction>;
+ d->hasPart = true;
+ d->part = 0;
+ d->disabled = false;
+}
+
+
+Plugin::~Plugin()
+{
+ delete d->part;
+ delete d->dcopClient;
+ delete d;
+}
+
+void Plugin::setIdentifier( const QString &identifier )
+{
+ d->identifier = identifier;
+}
+
+QString Plugin::identifier() const
+{
+ return d->identifier;
+}
+
+void Plugin::setTitle( const QString &title )
+{
+ d->title = title;
+}
+
+QString Plugin::title() const
+{
+ return d->title;
+}
+
+void Plugin::setIcon( const QString &icon )
+{
+ d->icon = icon;
+}
+
+QString Plugin::icon() const
+{
+ return d->icon;
+}
+
+void Plugin::setExecutableName( const QString& bin )
+{
+ d->executableName = bin;
+}
+
+QString Plugin::executableName() const
+{
+ return d->executableName;
+}
+
+void Plugin::setPartLibraryName( const QCString &libName )
+{
+ d->partLibraryName = libName;
+}
+
+KParts::ReadOnlyPart *Plugin::loadPart()
+{
+ return core()->createPart( d->partLibraryName );
+}
+
+const KAboutData *Plugin::aboutData()
+{
+ kdDebug(5601) << "Plugin::aboutData(): libname: " << d->partLibraryName << endl;
+
+ const KInstance *instance =
+ KParts::Factory::partInstanceFromLibrary( d->partLibraryName );
+
+ if ( instance ) {
+ return instance->aboutData();
+ } else {
+ kdError() << "Plugin::aboutData(): Can't load instance for "
+ << title() << endl;
+ return 0;
+ }
+}
+
+KParts::ReadOnlyPart *Plugin::part()
+{
+ if ( !d->part ) {
+ d->part = createPart();
+ if ( d->part ) {
+ connect( d->part, SIGNAL( destroyed() ), SLOT( partDestroyed() ) );
+ core()->partLoaded( this, d->part );
+ }
+ }
+ return d->part;
+}
+
+QString Plugin::tipFile() const
+{
+ return QString::null;
+}
+
+
+DCOPClient* Plugin::dcopClient() const
+{
+ if ( !d->dcopClient ) {
+ d->dcopClient = new DCOPClient();
+ // ### Note: maybe we could use executableName().latin1() instead here.
+ // But this requires that dcopClient is NOT called by the constructor,
+ // and is called by some new virtual void init() later on.
+ d->dcopClient->registerAs( name(), false );
+ }
+
+ return d->dcopClient;
+}
+
+void Plugin::insertNewAction( KAction *action )
+{
+ d->newActions->append( action );
+}
+
+void Plugin::insertSyncAction( KAction *action )
+{
+ d->syncActions->append( action );
+}
+
+QPtrList<KAction> *Plugin::newActions() const
+{
+ return d->newActions;
+}
+
+QPtrList<KAction> *Plugin::syncActions() const
+{
+ return d->syncActions;
+}
+
+Kontact::Core *Plugin::core() const
+{
+ return d->core;
+}
+
+void Plugin::select()
+{
+}
+
+void Plugin::configUpdated()
+{
+}
+
+void Plugin::partDestroyed()
+{
+ d->part = 0;
+}
+
+void Plugin::slotConfigUpdated()
+{
+ configUpdated();
+}
+
+void Plugin::bringToForeground()
+{
+ if (!d->executableName.isEmpty())
+ KRun::runCommand(d->executableName);
+}
+
+bool Kontact::Plugin::showInSideBar() const
+{
+ return d->hasPart;
+}
+
+void Kontact::Plugin::setShowInSideBar( bool hasPart )
+{
+ d->hasPart = hasPart;
+}
+
+void Kontact::Plugin::setDisabled( bool disabled )
+{
+ d->disabled = disabled;
+}
+
+bool Kontact::Plugin::disabled() const
+{
+ return d->disabled;
+}
+
+void Kontact::Plugin::loadProfile( const QString& )
+{
+}
+
+void Kontact::Plugin::saveToProfile( const QString& ) const
+{
+}
+
+void Plugin::virtual_hook( int, void* ) {
+ //BASE::virtual_hook( id, data );
+}
+
+#include "plugin.moc"
+
+// vim: sw=2 et sts=2 tw=80
diff --git a/kontact/interfaces/plugin.h b/kontact/interfaces/plugin.h
new file mode 100644
index 000000000..c80227984
--- /dev/null
+++ b/kontact/interfaces/plugin.h
@@ -0,0 +1,291 @@
+/*
+ This file is part of KDE Kontact.
+
+ Copyright (c) 2001 Matthias Hoelzer-Kluepfel <mhk@kde.org>
+ Copyright (c) 2002-2003 Daniel Molkentin <molkentin@kde.org>
+ Copyright (c) 2003 Cornelius Schumacher <schumacher@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_PLUGIN_H
+#define KONTACT_PLUGIN_H
+
+#include <qobject.h>
+#include <kxmlguiclient.h>
+#include <kdepimmacros.h>
+#include <qptrlist.h>
+
+class QStringList;
+class DCOPClient;
+class DCOPObject;
+class KAboutData;
+class KAction;
+class KConfig;
+class QWidget;
+namespace KParts { class ReadOnlyPart; }
+
+/**
+ Increase this version number whenever you make a change
+ in the API.
+ */
+#define KONTACT_PLUGIN_VERSION 6
+
+namespace Kontact
+{
+
+class Core;
+class Summary;
+
+/**
+ Base class for all Plugins in Kontact. Inherit from it
+ to get a plugin. It can insert an icon into the sidepane,
+ add widgets to the widgetstack and add menu items via XMLGUI.
+ */
+class KDE_EXPORT Plugin : public QObject, virtual public KXMLGUIClient
+{
+ Q_OBJECT
+
+ public:
+ /**
+ Creates a new Plugin, note that name parameter name is required if
+ you want your plugin to do dcop via it's own instance of
+ DCOPClient by calling dcopClient.
+ @note name MUST be the name of the application that
+ provides the part! This is the name used for DCOP registration.
+ It's ok to have several plugins using the same application name.
+ */
+ Plugin( Core *core, QObject *parent, const char *name );
+
+ ~Plugin();
+
+ /**
+ Sets the identifier.
+ */
+ void setIdentifier( const QString &identifier );
+
+ /**
+ Returns the identifier. It is used as argument for several
+ methods of Kontacts core.
+ */
+ QString identifier() const;
+
+ /**
+ Sets the localized title.
+ */
+ void setTitle( const QString &title );
+
+ /**
+ Returns the localized title.
+ */
+ QString title() const;
+
+ /**
+ Sets the icon name.
+ */
+ void setIcon( const QString &icon );
+
+ /**
+ Returns the icon name.
+ */
+ QString icon() const;
+
+ /**
+ Sets the name of executable (if existant).
+ */
+ void setExecutableName( const QString &bin );
+
+ /**
+ Returns the name of the binary (if existant).
+ */
+ QString executableName() const;
+
+ /**
+ Set name of library which contains the KPart used by this plugin.
+ */
+ void setPartLibraryName( const QCString & );
+
+ /**
+ Create the DCOP interface for the given @p serviceType, if this
+ plugin provides it. Return false otherwise.
+ */
+ virtual bool createDCOPInterface( const QString& /*serviceType*/ ) { return false; }
+
+ /**
+ Reimplement this method and return wether a standalone application is still running
+ This is only required if your part is also available as standalone application.
+ */
+ virtual bool isRunningStandalone() { return false; }
+
+ /**
+ Reimplement this method if your application needs a different approach to be brought
+ in the foreground. The default behaviour is calling the binary.
+ This is only required if your part is also available as standalone application.
+ */
+ virtual void bringToForeground();
+
+ /**
+ Reimplement this method if you want to add your credits to the Kontact
+ about dialog.
+ */
+ virtual const KAboutData *aboutData();
+
+ /**
+ You can use this method if you need to access the current part. You can be
+ sure that you always get the same pointer as long as the part has not been
+ deleted.
+ */
+ KParts::ReadOnlyPart *part();
+
+ /**
+ Reimplement this method and return the a path relative to "data" to the tips file.
+ */
+ virtual QString tipFile() const;
+
+ /**
+ This function is called when the plugin is selected by the user before the
+ widget of the KPart belonging to the plugin is raised.
+ */
+ virtual void select();
+
+ /**
+ This function is called whenever the config dialog has been closed
+ successfully.
+ */
+ virtual void configUpdated();
+
+ /**
+ Reimplement this method if you want to add a widget for your application
+ to Kontact's summary page.
+ */
+ virtual Summary *createSummaryWidget( QWidget * /*parent*/ ) { return 0; }
+
+ /**
+ Returns wether the plugin provides a part that should be shown in the sidebar.
+ */
+ virtual bool showInSideBar() const;
+
+ /**
+ Set if the plugin provides a part that should be shown in the sidebar.
+ */
+ void setShowInSideBar( bool hasPart );
+
+ /**
+ Reimplement this method if you want to add checks before closing down the main kontact
+ window. Return true if it's OK to close the window. If any loaded plugin returns false
+ from this method, then the main kontact window will not close.
+ */
+ virtual bool queryClose() const { return true; }
+
+ /**
+ Retrieve the current DCOP Client for the plugin.
+
+ The clients name is taken from the name argument in the constructor.
+ @note: The DCOPClient object will only be created when this method is
+ called for the first time. Make sure that the part has been loaded
+ before calling this method, if it's the one that contains the DCOP
+ interface that other parts might use.
+ */
+ DCOPClient *dcopClient() const;
+
+ /**
+ Return the weight of the plugin. The higher the weight the lower it will
+ be displayed in the sidebar. The default implementation returns 0.
+ */
+ virtual int weight() const { return 0; }
+
+ /**
+ Insert "New" action.
+ */
+ void insertNewAction( KAction *action );
+
+ /**
+ Insert "Sync" action.
+ */
+ void insertSyncAction( KAction *action );
+
+ /**
+ FIXME: write API doc for Kontact::Plugin::newActions().
+ */
+ QPtrList<KAction>* newActions() const;
+
+ /**
+ FIXME: write API doc for Kontact::Plugin::syncActions().
+ */
+ QPtrList<KAction>* syncActions() const;
+
+ /**
+ Returns a list of action name which shall be hidden in the main toolbar.
+ */
+ virtual QStringList invisibleToolbarActions() const { return QStringList(); }
+
+ /**
+ Return, if the plugin can handle the drag object of the given mime type.
+ */
+ virtual bool canDecodeDrag( QMimeSource * ) { return false; }
+
+ /**
+ Process drop event.
+ */
+ virtual void processDropEvent( QDropEvent * ) {}
+
+ virtual void loadProfile( const QString& directoryPath );
+
+ virtual void saveToProfile( const QString& directoryPath ) const;
+
+ /**
+ * Session management: read properties
+ */
+ virtual void readProperties( KConfig * ) {}
+
+ /**
+ * Session management: save properties
+ */
+ virtual void saveProperties( KConfig * ) {}
+
+ Core *core() const;
+
+ bool disabled() const;
+ void setDisabled( bool v );
+
+ public slots:
+ /**
+ internal usage
+ */
+ void slotConfigUpdated();
+
+ protected:
+ /**
+ Reimplement and return the part here. Reimplementing createPart() is
+ mandatory!
+ */
+ virtual KParts::ReadOnlyPart *createPart() = 0;
+
+ KParts::ReadOnlyPart *loadPart();
+
+ virtual void virtual_hook( int id, void* data );
+
+ private slots:
+ void partDestroyed();
+
+ private:
+ class Private;
+ Private *d;
+};
+
+}
+
+#endif
diff --git a/kontact/interfaces/summary.cpp b/kontact/interfaces/summary.cpp
new file mode 100644
index 000000000..f4e38771d
--- /dev/null
+++ b/kontact/interfaces/summary.cpp
@@ -0,0 +1,116 @@
+/*
+ This file is part of KDE Kontact.
+
+ Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>
+ Copyright (c) 2003 Daniel Molkentin <molkentin@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 "summary.h"
+
+#include <qimage.h>
+#include <qdragobject.h>
+#include <qhbox.h>
+#include <qfont.h>
+#include <qlabel.h>
+#include <qpainter.h>
+
+#include <kiconloader.h>
+#include <kdialog.h>
+
+using namespace Kontact;
+
+Summary::Summary( QWidget *parent, const char *name )
+ : QWidget( parent, name )
+{
+ setAcceptDrops( true );
+}
+
+Summary::~Summary()
+{
+}
+
+QWidget* Summary::createHeader(QWidget *parent, const QPixmap& icon, const QString& heading)
+{
+ QHBox* hbox = new QHBox( parent );
+ hbox->setMargin( 2 );
+
+ QFont boldFont;
+ boldFont.setBold( true );
+ boldFont.setPointSize( boldFont.pointSize() + 2 );
+
+ QLabel *label = new QLabel( hbox );
+ label->setPixmap( icon );
+ label->setFixedSize( label->sizeHint() );
+ label->setPaletteBackgroundColor( colorGroup().mid() );
+ label->setAcceptDrops( true );
+
+ label = new QLabel( heading, hbox );
+ label->setAlignment( AlignLeft|AlignVCenter );
+ label->setIndent( KDialog::spacingHint() );
+ label->setFont( boldFont );
+ label->setPaletteForegroundColor( colorGroup().light() );
+ label->setPaletteBackgroundColor( colorGroup().mid() );
+
+ hbox->setPaletteBackgroundColor( colorGroup().mid() );
+
+ hbox->setMaximumHeight( hbox->minimumSizeHint().height() );
+
+ return hbox;
+}
+
+void Summary::mousePressEvent( QMouseEvent *event )
+{
+ mDragStartPoint = event->pos();
+
+ QWidget::mousePressEvent( event );
+}
+
+void Summary::mouseMoveEvent( QMouseEvent *event )
+{
+ if ( (event->state() & LeftButton) &&
+ (event->pos() - mDragStartPoint).manhattanLength() > 4 ) {
+
+ QDragObject *drag = new QTextDrag( "", this, "SummaryWidgetDrag" );
+
+ QPixmap pm = QPixmap::grabWidget( this );
+ if ( pm.width() > 300 )
+ pm = pm.convertToImage().smoothScale( 300, 300, QImage::ScaleMin );
+
+ QPainter painter;
+ painter.begin( &pm );
+ painter.setPen( Qt::gray );
+ painter.drawRect( 0, 0, pm.width(), pm.height() );
+ painter.end();
+ drag->setPixmap( pm );
+ drag->dragMove();
+ } else
+ QWidget::mouseMoveEvent( event );
+}
+
+void Summary::dragEnterEvent( QDragEnterEvent *event )
+{
+ event->accept( QTextDrag::canDecode( event ) );
+}
+
+void Summary::dropEvent( QDropEvent *event )
+{
+ int alignment = (event->pos().y() < (height() / 2) ? Qt::AlignTop : Qt::AlignBottom);
+ emit summaryWidgetDropped( this, event->source(), alignment );
+}
+
+#include "summary.moc"
diff --git a/kontact/interfaces/summary.h b/kontact/interfaces/summary.h
new file mode 100644
index 000000000..8ef96ef2c
--- /dev/null
+++ b/kontact/interfaces/summary.h
@@ -0,0 +1,94 @@
+/*
+ This file is part of KDE Kontact.
+
+ Copyright (c) 2003 Cornelius Schumacher <schumacher@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_SUMMARY_H
+#define KONTACT_SUMMARY_H
+
+#include <qwidget.h>
+#include <qpixmap.h>
+#include <kdepimmacros.h>
+
+class KStatusBar;
+
+namespace Kontact
+{
+
+/**
+ Summary widget for display in the Summary View plugin.
+ */
+class KDE_EXPORT Summary : public QWidget
+{
+ Q_OBJECT
+
+ public:
+ Summary( QWidget *parent, const char *name = 0 );
+
+ virtual ~Summary();
+
+ /**
+ Return logical height of summary widget. This is used to calculate how
+ much vertical space relative to other summary widgets this widget will use
+ in the summary view.
+ */
+ virtual int summaryHeight() const { return 1; }
+
+ /**
+ Creates a heading for a typical summary view with an icon and a heading.
+ */
+ QWidget *createHeader( QWidget* parent, const QPixmap &icon,
+ const QString& heading );
+
+ /**
+ Return list of strings identifying configuration modules for this summary
+ part. The string has to be suitable for being passed to
+ KCMultiDialog::addModule().
+ */
+ virtual QStringList configModules() const { return QStringList(); }
+
+ public slots:
+ virtual void configChanged() {}
+
+ /**
+ This is called if the displayed information should be updated.
+ @param force true if the update was requested by the user
+ */
+ virtual void updateSummary( bool force = false ) { Q_UNUSED( force ); }
+
+ signals:
+ void message( const QString &message );
+ void summaryWidgetDropped( QWidget *target, QWidget *widget, int alignment );
+
+ protected:
+ virtual void mousePressEvent( QMouseEvent* );
+ virtual void mouseMoveEvent( QMouseEvent* );
+ virtual void dragEnterEvent( QDragEnterEvent* );
+ virtual void dropEvent( QDropEvent* );
+
+ private:
+ KStatusBar *mStatusBar;
+ QPoint mDragStartPoint;
+
+ class Private;
+ Private *d;
+};
+
+}
+
+#endif
diff --git a/kontact/interfaces/uniqueapphandler.cpp b/kontact/interfaces/uniqueapphandler.cpp
new file mode 100644
index 000000000..de77df7d5
--- /dev/null
+++ b/kontact/interfaces/uniqueapphandler.cpp
@@ -0,0 +1,201 @@
+/*
+ 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 "core.h"
+#include <kwin.h>
+#include <dcopclient.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kuniqueapplication.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
+
+ 6) start "kontact --module summaryplugin"
+ 6a) type "dcop kmail kmail newInstance" -> kontact switches to kmail (#103775)
+ 6b) type "kmail" -> kontact is brought to front
+ 6c) type "kontact" -> kontact is brought to front
+ 6d) type "kontact --module summaryplugin" -> kontact switches to summary
+
+*/
+
+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(); // implemented by plugin
+
+ // 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();
+
+ // OK, we're done, reload the initial kontact command line options,
+ // so that "kontact --module foo" keeps working (#103775).
+
+ KCmdLineArgs::reset(); // forget options defined above
+ loadKontactCommandLineOptions();
+
+ } 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;
+ }
+}
+
+static KCmdLineOptions options[] =
+{
+ { "module <module>", I18N_NOOP( "Start with a specific Kontact module" ), 0 },
+ { "iconify", I18N_NOOP( "Start in iconified (minimized) mode" ), 0 },
+ { "list", I18N_NOOP( "List all possible modules and exit" ), 0 },
+ KCmdLineLastOption
+};
+
+void Kontact::UniqueAppHandler::loadKontactCommandLineOptions()
+{
+ KCmdLineArgs::addCmdLineOptions( options );
+ KUniqueApplication::addCmdLineOptions();
+ KApplication::addCmdLineOptions();
+}
+
+#include "uniqueapphandler.moc"
diff --git a/kontact/interfaces/uniqueapphandler.h b/kontact/interfaces/uniqueapphandler.h
new file mode 100644
index 000000000..23a593af6
--- /dev/null
+++ b/kontact/interfaces/uniqueapphandler.h
@@ -0,0 +1,123 @@
+/*
+ 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 <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; }
+
+ /// Load the kontact command line options.
+ static void loadKontactCommandLineOptions();
+
+ 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 */