summaryrefslogtreecommitdiffstats
path: root/libkdepim/komposer/core
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 /libkdepim/komposer/core
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 'libkdepim/komposer/core')
-rw-r--r--libkdepim/komposer/core/Makefile.am28
-rw-r--r--libkdepim/komposer/core/attachment.cpp112
-rw-r--r--libkdepim/komposer/core/attachment.h61
-rw-r--r--libkdepim/komposer/core/core.cpp357
-rw-r--r--libkdepim/komposer/core/core.h107
-rw-r--r--libkdepim/komposer/core/corewidget.cpp32
-rw-r--r--libkdepim/komposer/core/corewidget.h48
-rw-r--r--libkdepim/komposer/core/editor.cpp51
-rw-r--r--libkdepim/komposer/core/editor.h104
-rw-r--r--libkdepim/komposer/core/komposer.kcfg26
-rw-r--r--libkdepim/komposer/core/komposerIface.h85
-rw-r--r--libkdepim/komposer/core/komposerconfig.desktop58
-rw-r--r--libkdepim/komposer/core/komposereditor.desktop57
-rw-r--r--libkdepim/komposer/core/komposerplugin.desktop60
-rw-r--r--libkdepim/komposer/core/komposerui.rc51
-rw-r--r--libkdepim/komposer/core/plugin.cpp80
-rw-r--r--libkdepim/komposer/core/plugin.h75
-rw-r--r--libkdepim/komposer/core/pluginmanager.cpp489
-rw-r--r--libkdepim/komposer/core/pluginmanager.h251
-rw-r--r--libkdepim/komposer/core/prefsmodule.cpp142
-rw-r--r--libkdepim/komposer/core/prefsmodule.h70
-rw-r--r--libkdepim/komposer/core/settings.kcfgc9
-rw-r--r--libkdepim/komposer/core/tests/Makefile.am20
-rw-r--r--libkdepim/komposer/core/tests/main.cpp52
-rw-r--r--libkdepim/komposer/core/tests/managertest.cpp43
-rw-r--r--libkdepim/komposer/core/tests/managertest.h44
-rw-r--r--libkdepim/komposer/core/tests/tester.cpp30
-rw-r--r--libkdepim/komposer/core/tests/tester.h71
-rw-r--r--libkdepim/komposer/core/tests/testfactory.h71
-rw-r--r--libkdepim/komposer/core/tests/testkomposer.cpp18
-rw-r--r--libkdepim/komposer/core/tests/testmanager.cpp53
-rw-r--r--libkdepim/komposer/core/tests/testmanager.h25
32 files changed, 2780 insertions, 0 deletions
diff --git a/libkdepim/komposer/core/Makefile.am b/libkdepim/komposer/core/Makefile.am
new file mode 100644
index 000000000..6a7bcd984
--- /dev/null
+++ b/libkdepim/komposer/core/Makefile.am
@@ -0,0 +1,28 @@
+AM_CPPFLAGS = -I$(top_builddir)/libkdepim $(all_includes)
+METASOURCES = AUTO
+
+lib_LTLIBRARIES = libkomposer.la
+
+libkomposer_la_SOURCES = plugin.cpp editor.cpp core.cpp attachment.cpp corewidget.cpp \
+ settings.kcfgc pluginmanager.cpp komposerIface.skel
+libkomposer_la_LDFLAGS = -no-undefined $(KDE_RPATH) -version-info 1:0:0 $(all_libraries)
+libkomposer_la_LIBADD = $(LIB_KPARTS) $(top_builddir)/libkdepim/libkdepim.la -lkutils
+
+#kde_module_LTLIBRARIES = kcm_komposer.la
+
+#kcm_komposer_la_SOURCES = prefsmodule.cpp
+#kcm_komposer_la_LDFLAGS = -module -avoid-version -no-undefined $(all_libraries)
+#kcm_komposer_la_LIBADD = libkomposer.la $(top_builddir)/libkdepim/libkdepim.la $(LIB_KDECORE)
+
+kpincludedir = $(includedir)/komposer
+kpinclude_HEADERS = plugin.h editor.h core.h
+
+rcdir = $(kde_datadir)/komposer
+rc_DATA = komposerui.rc
+
+kde_kcfg_DATA = komposer.kcfg
+
+servicetypedir = $(kde_servicetypesdir)
+servicetype_DATA = komposerplugin.desktop komposereditor.desktop
+
+kde_services_DATA = komposerconfig.desktop
diff --git a/libkdepim/komposer/core/attachment.cpp b/libkdepim/komposer/core/attachment.cpp
new file mode 100644
index 000000000..f5b936c0c
--- /dev/null
+++ b/libkdepim/komposer/core/attachment.cpp
@@ -0,0 +1,112 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
+/**
+ * attachment.cpp
+ *
+ * Copyright (C) 2003 Zack Rusin <zack@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#include "attachment.h"
+
+using namespace Komposer;
+
+class Attachment::Private
+{
+public:
+ QString name;
+ QCString cte;
+ QByteArray data;
+ QCString type;
+ QCString subType;
+ QCString paramAttr;
+ QString paramValue;
+ QCString contDisp;
+};
+
+Attachment::Attachment( const QString &name,
+ const QCString &cte,
+ const QByteArray &data,
+ const QCString &type,
+ const QCString &subType,
+ const QCString &paramAttr,
+ const QString &paramValue,
+ const QCString &contDisp )
+ : d( new Private )
+{
+ d->name = name;
+ d->cte = cte;
+ d->data = data;
+ d->type = type;
+ d->subType = subType;
+ d->paramAttr = paramAttr;
+ d->paramValue = paramValue;
+ d->contDisp = contDisp;
+}
+
+Attachment::~Attachment()
+{
+ delete d; d = 0;
+}
+
+QString
+Attachment::name() const
+{
+ return d->name;
+}
+
+QCString
+Attachment::cte() const
+{
+ return d->cte;
+}
+
+QByteArray
+Attachment::data() const
+{
+ return d->data;
+}
+
+QCString
+Attachment::type() const
+{
+ return d->type;
+}
+
+
+QCString
+Attachment::subType() const
+{
+ return d->subType;
+}
+
+QCString
+Attachment::paramAttr() const
+{
+ return d->paramAttr;
+}
+
+QString
+Attachment::paramValue() const
+{
+ return d->paramValue;
+}
+
+QCString
+Attachment::contentDisposition() const
+{
+ return d->contDisp;
+}
+
diff --git a/libkdepim/komposer/core/attachment.h b/libkdepim/komposer/core/attachment.h
new file mode 100644
index 000000000..fc19fb2da
--- /dev/null
+++ b/libkdepim/komposer/core/attachment.h
@@ -0,0 +1,61 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
+/**
+ * attachment.h
+ *
+ * Copyright (C) 2003 Zack Rusin <zack@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#ifndef KOMPOSER_ATTACHMENT_H
+#define KOMPOSER_ATTACHMENT_H
+
+#include <qstring.h>
+#include <qcstring.h>
+#include <qvaluelist.h>
+
+namespace Komposer
+{
+
+ class Attachment
+ {
+ public:
+ Attachment( const QString &name,
+ const QCString &cte,
+ const QByteArray &data,
+ const QCString &type,
+ const QCString &subType,
+ const QCString &paramAttr,
+ const QString &paramValue,
+ const QCString &contDisp );
+ ~Attachment();
+
+ QString name() const;
+ QCString cte() const;
+ QByteArray data() const;
+ QCString type() const;
+ QCString subType() const;
+ QCString paramAttr() const;
+ QString paramValue() const;
+ QCString contentDisposition() const;
+
+ private:
+ class Private;
+ Private *d;
+ };
+ typedef QValueList<Attachment> AttachmentList;
+}
+
+#endif
diff --git a/libkdepim/komposer/core/core.cpp b/libkdepim/komposer/core/core.cpp
new file mode 100644
index 000000000..6a14fdb38
--- /dev/null
+++ b/libkdepim/komposer/core/core.cpp
@@ -0,0 +1,357 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
+/**
+ * core.cpp
+ *
+ * Copyright (C) 2003 Zack Rusin <zack@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include "core.h"
+
+#include "pluginmanager.h"
+#include "editor.h"
+#include "plugin.h"
+
+#include <ksettings/dialog.h>
+#include <kplugininfo.h>
+#include <kapplication.h>
+#include <kconfig.h>
+#include <ktrader.h>
+#include <klibloader.h>
+#include <kstdaction.h>
+#include <klistbox.h>
+#include <kiconloader.h>
+#include <kstandarddirs.h>
+#include <kshortcut.h>
+#include <klocale.h>
+#include <kstatusbar.h>
+#include <kguiitem.h>
+#include <kpopupmenu.h>
+#include <kshortcut.h>
+#include <kcmultidialog.h>
+#include <kaction.h>
+#include <kstdaccel.h>
+#include <kdebug.h>
+
+#include <qwidgetstack.h>
+#include <qhbox.h>
+#include <qwidget.h>
+
+using namespace Komposer;
+
+Core::Core( QWidget *parent, const char *name )
+ : KomposerIface( "KomposerIface" ),
+ KMainWindow( parent, name ), m_currentEditor( 0 )
+{
+ initWidgets();
+ initCore();
+ initConnections();
+ setInstance( new KInstance( "komposer" ) );
+
+ createActions();
+ setXMLFile( "komposerui.rc" );
+
+ createGUI( 0 );
+
+ resize( 600, 400 ); // initial size
+ setAutoSaveSettings();
+
+ loadSettings();
+}
+
+Core::~Core()
+{
+ saveSettings();
+
+ //Prefs::self()->writeConfig();
+}
+
+void
+Core::addEditor( Komposer::Editor *editor )
+{
+ if ( editor->widget() ) {
+ m_stack->addWidget( editor->widget() );
+ m_stack->raiseWidget( editor->widget() );
+ editor->widget()->show();
+ m_currentEditor = editor;
+ }
+
+ // merge the editors GUI into the main window
+ //insertChildClient( editor );
+ guiFactory()->addClient( editor );
+}
+
+void
+Core::addPlugin( Komposer::Plugin *plugin )
+{
+ //insertChildClient( plugin );
+ guiFactory()->addClient( plugin );
+}
+
+void
+Core::slotPluginLoaded( Plugin *plugin )
+{
+ kdDebug() << "Plugin loaded "<<endl;
+
+ Editor *editor = dynamic_cast<Editor*>( plugin );
+ if ( editor ) {
+ addEditor( editor );
+ } else {
+ addPlugin( plugin );
+ }
+}
+
+void
+Core::slotAllPluginsLoaded()
+{
+ QValueList<KPluginInfo*> plugins = m_pluginManager->availablePlugins();
+ kdDebug()<<"Number of available plugins is "<< plugins.count() <<endl;
+ for ( QValueList<KPluginInfo*>::iterator it = plugins.begin(); it != plugins.end(); ++it ) {
+ KPluginInfo *i = ( *it );
+ kdDebug()<<"\tAvailable plugin "<< i->pluginName()
+ <<", comment = "<< i->comment() <<endl;
+ }
+
+ if ( !m_stack->visibleWidget() ) {
+ m_pluginManager->loadPlugin( "komposer_defaulteditor", PluginManager::LoadAsync );
+ }
+}
+
+#if 0
+void
+Core::slotActivePartChanged( KParts::Part *part )
+{
+ if ( !part ) {
+ createGUI( 0 );
+ return;
+ }
+
+ kdDebug() << "Part activated: " << part << " with stack id. "
+ << m_stack->id( part->widget() )<< endl;
+
+ createGUI( part );
+}
+
+void
+Core::selectEditor( Komposer::Editor *editor )
+{
+ if ( !editor )
+ return;
+
+ KParts::Part *part = editor->part();
+
+ editor->select();
+
+ QPtrList<KParts::Part> *partList = const_cast<QPtrList<KParts::Part>*>(
+ m_partManager->parts() );
+ if ( partList->find( part ) == -1 )
+ addPart( part );
+
+ m_partManager->setActivePart( part );
+ QWidget *view = part->widget();
+ Q_ASSERT( view );
+
+ kdDebug()<<"Raising view "<<view<<endl;
+ if ( view )
+ {
+ m_stack->raiseWidget( view );
+ view->show();
+ view->setFocus();
+ m_currentEditor = editor;
+ }
+}
+
+void
+Core::selectEditor( const QString &editorName )
+{
+
+}
+#endif
+
+void
+Core::loadSettings()
+{
+ //kdDebug()<<"Trying to select "<< Prefs::self()->m_activeEditor <<endl;
+ //selectEditor( Prefs::self()->m_activeEditor );
+
+ //m_activeEditors = Prefs::self()->m_activeEditors;
+}
+
+void
+Core::saveSettings()
+{
+ //if ( m_currentEditor )
+ //Prefs::self()->m_activeEditor = m_currentEditor->identifier();
+}
+
+void
+Core::slotQuit()
+{
+ kdDebug()<<"exit"<<endl;
+ m_pluginManager->shutdown();
+}
+
+void
+Core::slotPreferences()
+{
+ if ( m_dlg == 0 )
+ m_dlg = new KSettings::Dialog( this );
+ m_dlg->show();
+}
+
+void
+Core::initWidgets()
+{
+ statusBar()->show();
+ QHBox *topWidget = new QHBox( this );
+ setCentralWidget( topWidget );
+ m_stack = new QWidgetStack( topWidget );
+}
+
+void
+Core::initCore()
+{
+ m_pluginManager = new PluginManager( this );
+ connect( m_pluginManager, SIGNAL(pluginLoaded(Plugin*)),
+ SLOT(slotPluginLoaded(Plugin*)) );
+ connect( m_pluginManager, SIGNAL(allPluginsLoaded()),
+ SLOT(slotAllPluginsLoaded()) );
+
+
+ m_pluginManager->loadAllPlugins();
+ kdDebug()<<"Loading"<<endl;
+}
+
+void
+Core::initConnections()
+{
+ connect( kapp, SIGNAL(shutDown()),
+ SLOT(slotQuit()) );
+}
+
+void
+Core::createActions()
+{
+ KStdAction::close( this, SLOT(slotClose()), actionCollection() );
+
+ (void) new KAction( i18n( "&Send" ), "mail_send", CTRL+Key_Return,
+ this, SLOT(slotSendNow()), actionCollection(),
+ "send_default" );
+
+ (void) new KAction( i18n( "&Queue" ), "queue", 0,
+ this, SLOT(slotSendLater()),
+ actionCollection(), "send_alternative" );
+
+ (void) new KAction( i18n( "Save in &Drafts Folder" ), "filesave", 0,
+ this, SLOT(slotSaveDraft()),
+ actionCollection(), "save_in_drafts" );
+ (void) new KAction( i18n( "&Insert File..." ), "fileopen", 0,
+ this, SLOT(slotInsertFile()),
+ actionCollection(), "insert_file" );
+ (void) new KAction( i18n( "&Address Book" ), "contents",0,
+ this, SLOT(slotAddrBook()),
+ actionCollection(), "addressbook" );
+ (void) new KAction( i18n( "&New Composer" ), "mail_new",
+ KStdAccel::shortcut( KStdAccel::New ),
+ this, SLOT(slotNewComposer()),
+ actionCollection(), "new_composer" );
+
+ (void) new KAction( i18n( "&Attach File..." ), "attach",
+ 0, this, SLOT(slotAttachFile()),
+ actionCollection(), "attach_file" );
+}
+
+void
+Core::slotClose()
+{
+ close( false );
+}
+
+void
+Core::slotSendNow()
+{
+
+}
+
+void
+Core::slotSendLater()
+{
+
+}
+
+void
+Core::slotSaveDraft()
+{
+
+}
+
+void
+Core::slotInsertFile()
+{
+
+}
+
+void
+Core::slotAddrBook()
+{
+
+}
+
+void
+Core::slotNewComposer()
+{
+
+}
+
+void
+Core::slotAttachFile()
+{
+
+}
+
+void
+Core::send( int how )
+{
+
+}
+
+void
+Core::addAttachment( const KURL &url, const QString &comment )
+{
+
+}
+
+void
+Core::setBody( const QString &body )
+{
+ m_currentEditor->setText( body );
+}
+
+void
+Core::addAttachment( const QString &name,
+ const QCString &cte,
+ const QByteArray &data,
+ const QCString &type,
+ const QCString &subType,
+ const QCString &paramAttr,
+ const QString &paramValue,
+ const QCString &contDisp )
+{
+
+}
+
+#include "core.moc"
diff --git a/libkdepim/komposer/core/core.h b/libkdepim/komposer/core/core.h
new file mode 100644
index 000000000..0c5149610
--- /dev/null
+++ b/libkdepim/komposer/core/core.h
@@ -0,0 +1,107 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
+/**
+ * core.h
+ *
+ * Copyright (C) 2003 Zack Rusin <zack@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#ifndef KOMPOSER_CORE_H
+#define KOMPOSER_CORE_H
+
+#include "komposerIface.h"
+
+#include <kmainwindow.h>
+#include <qptrlist.h>
+
+namespace KSettings {
+ class Dialog;
+}
+class QWidgetStack;
+
+namespace Komposer
+{
+
+ class Editor;
+ class Plugin;
+ class PluginManager;
+
+ /**
+ * This class provides the interface to the Komposer core for the editor.
+ */
+ class Core : public KMainWindow, virtual public KomposerIface
+ {
+ Q_OBJECT
+ public:
+ Core( QWidget *parentWidget = 0, const char *name = 0 );
+ virtual ~Core();
+
+ public slots:
+ virtual void send( int how );
+ virtual void addAttachment( const KURL &url, const QString &comment );
+ virtual void setBody( const QString &body );
+ virtual void addAttachment( const QString &name,
+ const QCString &cte,
+ const QByteArray &data,
+ const QCString &type,
+ const QCString &subType,
+ const QCString &paramAttr,
+ const QString &paramValue,
+ const QCString &contDisp );
+
+
+
+ protected slots:
+ //void slotActivePartChanged( KParts::Part *part );
+ void slotPluginLoaded( Plugin* );
+ void slotAllPluginsLoaded();
+ void slotPreferences();
+ void slotQuit();
+ void slotClose();
+
+ void slotSendNow();
+ void slotSendLater();
+ void slotSaveDraft();
+ void slotInsertFile();
+ void slotAddrBook();
+ void slotNewComposer();
+ void slotAttachFile();
+
+ protected:
+ virtual void initWidgets();
+ void initCore();
+ void initConnections();
+ void loadSettings();
+ void saveSettings();
+ void createActions();
+
+ void addEditor( Komposer::Editor *editor );
+ void addPlugin( Komposer::Plugin *plugin );
+
+ private:
+ QWidgetStack *m_stack;
+ Editor *m_currentEditor;
+ PluginManager *m_pluginManager;
+
+ KSettings::Dialog *m_dlg;
+
+ class Private;
+ Private *d;
+};
+
+}
+
+#endif
diff --git a/libkdepim/komposer/core/corewidget.cpp b/libkdepim/komposer/core/corewidget.cpp
new file mode 100644
index 000000000..74fa92375
--- /dev/null
+++ b/libkdepim/komposer/core/corewidget.cpp
@@ -0,0 +1,32 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
+/**
+ * corewidget.cpp
+ *
+ * Copyright (C) 2003 Zack Rusin <zack@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include "corewidget.h"
+
+using namespace Komposer;
+
+CoreWidget::CoreWidget( QWidget *parent, const char *name )
+ : QWidget( parent, name )
+{
+}
+
+#include "corewidget.moc"
diff --git a/libkdepim/komposer/core/corewidget.h b/libkdepim/komposer/core/corewidget.h
new file mode 100644
index 000000000..b4166d8a0
--- /dev/null
+++ b/libkdepim/komposer/core/corewidget.h
@@ -0,0 +1,48 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
+/**
+ * corewidget.h
+ *
+ * Copyright (C) 2003-2004 Zack Rusin <zack@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#ifndef COREWIDGET_H
+#define COREWIDGET_H
+
+#include "attachment.h"
+
+#include <qwidget.h>
+
+namespace Komposer
+{
+
+ class CoreWidget : public QWidget
+ {
+ Q_OBJECT
+ public:
+ CoreWidget( QWidget *parent, const char *name=0 );
+
+ virtual QString subject() const =0;
+ virtual QStringList to() const =0;
+ virtual QStringList cc() const =0;
+ virtual QStringList bcc() const =0;
+ virtual QString from() const =0;
+ virtual QString replyTo() const =0;
+ virtual AttachmentList attachments() const =0;
+ };
+}
+
+#endif
diff --git a/libkdepim/komposer/core/editor.cpp b/libkdepim/komposer/core/editor.cpp
new file mode 100644
index 000000000..2e3bfd51b
--- /dev/null
+++ b/libkdepim/komposer/core/editor.cpp
@@ -0,0 +1,51 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
+/**
+ * editor.cpp
+ *
+ * Copyright (C) 2003 Zack Rusin <zack@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include "editor.h"
+#include "core.h"
+
+namespace Komposer {
+
+class Editor::Private {
+public:
+ QString id;
+};
+
+Editor::Editor( QObject *parent, const char *name, const QStringList &args )
+ : Plugin( parent, name, args ), d( new Private )
+{
+}
+
+Editor::~Editor()
+{
+ delete d; d = 0;
+}
+
+void
+Editor::select()
+{
+}
+
+
+}
+
+#include "editor.moc"
diff --git a/libkdepim/komposer/core/editor.h b/libkdepim/komposer/core/editor.h
new file mode 100644
index 000000000..3b8d601a5
--- /dev/null
+++ b/libkdepim/komposer/core/editor.h
@@ -0,0 +1,104 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
+/**
+ * editor.h
+ *
+ * Copyright (C) 2003-2004 Zack Rusin <zack@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef KOMPOSER_EDITOR_H
+#define KOMPOSER_EDITOR_H
+
+#include "plugin.h"
+
+#include <qstringlist.h>
+
+namespace KParts {
+ class Part;
+}
+
+namespace Komposer {
+
+ class Core;
+
+ class Editor : public Plugin
+ {
+ Q_OBJECT
+ public:
+ enum TextType {
+ Plain = 1 << 0,
+ RichText = 1 << 1,
+ HTML = 1 << 2
+ };
+ virtual ~Editor();
+
+ /**
+ * This is the magic function that all derivatives have to reimplement.
+ * It returns the actual editor component.
+ */
+ virtual QWidget *widget() =0;
+
+ int supportedTextFormats() const;
+
+ /**
+ * Returns the full text inside the editor.
+ */
+ virtual QString text() const =0;
+
+ /**
+ * 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();
+
+ /**
+ * Reimplement this method and return a @ref QStringList of all config
+ * modules your application part should offer via Komposer. Note that the
+ * part and the module will have to take care for config syncing themselves.
+ * Usually @p DCOP used for that purpose.
+ *
+ * @note Make sure you offer the modules in the form:
+ * <code>"pathrelativetosettings/mysettings.desktop"</code>
+ */
+ virtual QStringList configModules() const { return QStringList(); }
+
+
+ public slots:
+ /**
+ * Sets the text of the opened editor.
+ * Most commonly used on replaying.
+ * If any text is present if will be deleted.
+ */
+ virtual void setText( const QString &txt ) =0;
+
+ /**
+ * Changes currently used signature. If no signature is present
+ * a new one should be appened.
+ */
+ virtual void changeSignature( const QString &txt ) =0;
+
+ protected:
+ Editor( QObject *parent, const char *name, const QStringList &args );
+
+ private:
+ class Private;
+ Private *d;
+ };
+
+}
+
+#endif
diff --git a/libkdepim/komposer/core/komposer.kcfg b/libkdepim/komposer/core/komposer.kcfg
new file mode 100644
index 000000000..111584b88
--- /dev/null
+++ b/libkdepim/komposer/core/komposer.kcfg
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
+ http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
+ <kcfgfile name="komposerrc"/>
+
+ <group name="Colors">
+
+ <entry type="Color" name="foregroundColor">
+ </entry>
+
+ <entry type="Color" name="backgroundColor">
+ </entry>
+
+ <entry type="Color" name="QuotedText$(Level)" key="quotedColor_$(Level)">
+ <parameter name="Level" type="Int" max="3"/>
+ <default param="0">#ff0000</default>
+ <default param="1">#00ff00</default>
+ <default param="2">#0000ff</default>
+ <default param="3">#ffff00</default>
+ </entry>
+
+ </group>
+
+</kcfg>
diff --git a/libkdepim/komposer/core/komposerIface.h b/libkdepim/komposer/core/komposerIface.h
new file mode 100644
index 000000000..bf8877c6a
--- /dev/null
+++ b/libkdepim/komposer/core/komposerIface.h
@@ -0,0 +1,85 @@
+/*
+ * komposerIface.h
+ *
+ * Copyright (C) 2004 Zack Rusin <zack@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#ifndef KOMPOSERIFACE_H
+#define KOMPOSERIFACE_H
+
+#include <dcopobject.h>
+#include <kurl.h>
+
+namespace Komposer
+{
+
+/**
+ DCOP interface for mail composer window. The address header fields are set,
+ when the composer is constructed. KMailIface::openComposer() returns a
+ reference to the DCOP interface of the new composer window, which provides the
+ functions defined in the MailComposerIface.
+*/
+class KomposerIface : virtual public DCOPObject
+{
+ K_DCOP
+k_dcop:
+ /**
+ Send message.
+
+ @param how 0 for deafult method, 1 for sending now, 2 for sending later.
+ */
+ virtual void send(int how) = 0;
+
+ /**
+ Add url as attachment with a user-defined comment.
+ */
+ virtual void addAttachment( const KURL &url, const QString &comment) = 0;
+
+ /**
+ Set message body.
+ */
+ virtual void setBody( const QString &body ) = 0;
+
+ /**
+ Add attachment.
+
+ @param name Name of Attachment
+ @param cte Content Transfer Encoding
+ @param data Data to be attached
+ @param type MIME content type
+ @param subType MIME content sub type
+ @param paramAttr Attribute name of parameter of content type
+ @param paramValue Value of parameter of content type
+ @param contDisp Content disposition
+ */
+ virtual void addAttachment( const QString &name,
+ const QCString &cte,
+ const QByteArray &data,
+ const QCString &type,
+ const QCString &subType,
+ const QCString &paramAttr,
+ const QString &paramValue,
+ const QCString &contDisp ) = 0;
+public:
+ KomposerIface( const char *name )
+ : DCOPObject( name )
+ {}
+};
+
+}
+
+#endif
diff --git a/libkdepim/komposer/core/komposerconfig.desktop b/libkdepim/komposer/core/komposerconfig.desktop
new file mode 100644
index 000000000..9076759d5
--- /dev/null
+++ b/libkdepim/komposer/core/komposerconfig.desktop
@@ -0,0 +1,58 @@
+[Desktop Entry]
+Exec=kcmshell komposerconfig
+Icon=komposer
+Type=Application
+Terminal=false
+
+X-KDE-ModuleType=Library
+X-KDE-Library=komposer
+X-KDE-FactoryName=komposerconfig
+X-KDE-HasReadOnlyMode=false
+
+Name=Komposer
+Name[cy]=Kyfansoddydd
+Name[da]=Brevskriver
+Name[hi]=कमà¥à¤ªà¥‹à¤œà¤¼à¤°
+Name[ms]=Penggubah
+Name[ne]=कमà¥à¤ªà¥‹à¤œà¤°
+Name[pt]=Kompositor
+Name[ta]=கமà¯à®ªà¯‹à®šà®°à¯
+Comment=KDE Komposer
+Comment[bg]=ПиÑане на форматиран текÑÑ‚
+Comment[br]=Komposer KDE
+Comment[ca]=Compositor per a KDE
+Comment[cy]=Cyfansoddydd KDE
+Comment[da]=KDE Brevskriver
+Comment[de]=KDE-Komposer
+Comment[fr]=Komposer KDE
+Comment[ga]=Komposer KDE
+Comment[hi]=केडीई कमà¥à¤ªà¥‹à¤œà¤¼à¤°
+Comment[ka]=KDE კáƒáƒ›áƒžáƒáƒ–იტáƒáƒ áƒ˜
+Comment[ms]=Penggubah KDE
+Comment[nds]=Nettbreef-Editor vun KDE
+Comment[ne]=केडीई कमà¥à¤ªà¥‹à¤œà¤°
+Comment[nn]=KDE, tekstredigerar for e-post
+Comment[pl]=Komposer dla KDE
+Comment[pt]=Kompositor do KDE
+Comment[pt_BR]=Konposer do KDE
+Comment[ru]=Композитор KDE
+Comment[ta]=கேடிஇ கமà¯à®ªà¯‹à®šà®°à¯
+Comment[tg]=Композитори KDE
+Keywords=komposer
+Keywords[bg]=редактор, ÑÑŠÑтавител, форматиране, текÑÑ‚, komposer
+Keywords[ca]=compositor
+Keywords[cy]=komposer,kyfansoddydd
+Keywords[da]=brevskriver
+Keywords[de]=Komposer
+Keywords[fy]=komposer,opstellen, opsteller
+Keywords[hi]=कमà¥à¤ªà¥‹à¤œà¤¼à¤°
+Keywords[ka]=komposer,ნáƒáƒ¢áƒ”ბი
+Keywords[nds]=Komposer
+Keywords[ne]=कमà¥à¤ªà¥‹à¤œà¤°
+Keywords[nl]=komposer,opstellen
+Keywords[nn]=komposer,tekstredigerar,epost
+Keywords[ru]=komposer,ноты
+Keywords[sr]=komposer,ÑаÑтављач
+Keywords[sr@Latn]=komposer,sastavljaÄ
+Keywords[ta]=கமà¯à®ªà¯‹à®šà®°à¯
+Keywords[tg]=komposer,нотаҳо
diff --git a/libkdepim/komposer/core/komposereditor.desktop b/libkdepim/komposer/core/komposereditor.desktop
new file mode 100644
index 000000000..2e84bd17c
--- /dev/null
+++ b/libkdepim/komposer/core/komposereditor.desktop
@@ -0,0 +1,57 @@
+[Desktop Entry]
+Type=ServiceType
+X-KDE-ServiceType=Komposer/Editor
+X-KDE-Derived=Komposer/Plugin
+Comment=Komposer Editor
+Comment[af]=Komposer Redigeerder
+Comment[bg]=ПиÑане на форматиран текÑÑ‚
+Comment[br]=Aozer Komposer
+Comment[bs]=Komposer editor
+Comment[ca]=Compositor per a KDE
+Comment[cs]=Komposer editor
+Comment[da]=Komposer editor
+Comment[el]=ΕπεξεÏγαστής Komposer
+Comment[eo]=Komposer-redaktilo
+Comment[es]=Editor Komposer
+Comment[et]=Komposeri redaktor
+Comment[eu]=Komposer editorea
+Comment[fa]=ویرایشگر Komposer
+Comment[fi]=Komposer-muokkain
+Comment[fr]=Éditeur Komposer
+Comment[fy]=Komposer-bewurker
+Comment[ga]=Eagarthóir Komposer
+Comment[gl]=Editor Komposer
+Comment[he]=עורך של Komposer
+Comment[hu]=Komposer
+Comment[is]=Komposer ritill
+Comment[it]=Komposer editor
+Comment[ja]=Komposer,エディタ
+Comment[ka]=Komposer-ის რედáƒáƒ¥áƒ¢áƒáƒ áƒ˜
+Comment[kk]=Komposer өңдегіші
+Comment[km]=កម្មវិធី​និពន្ធ Komposer
+Comment[ko]=Komposer 편집기
+Comment[lt]=Komposer redaktorius
+Comment[ms]=Editor Komposer
+Comment[nb]=Komposer redigerer
+Comment[nds]=Komposer-Editor
+Comment[ne]=कमà¥à¤ªà¥‹à¤œà¤° समà¥à¤ªà¤¾à¤¦à¤•
+Comment[nl]=Komposer-editor
+Comment[nn]=Komposer redigerar
+Comment[pl]=Edytor Komposer
+Comment[pt]=Editor Kompositor
+Comment[pt_BR]=Editor de Mensagens
+Comment[ru]=Редактор Komposer
+Comment[sk]=Editor Komposer
+Comment[sl]=Urejevalnik Komposer
+Comment[sr]=Уређивач Komposer
+Comment[sr@Latn]=UreÄ‘ivaÄ Komposer
+Comment[sv]=Komposer editor
+Comment[ta]=கமà¯à®ªà¯‹à®šà®°à¯ தொகà¯à®ªà¯à®ªà®¾à®©à¯
+Comment[tg]=Муҳаррири Komposer
+Comment[tr]=Komposer Düzenleyicisi
+Comment[uk]=Редактор Komposer
+Comment[zh_CN]=Komposer 编辑器
+Comment[zh_TW]=Komposer 編輯器
+
+[PropertyDef::X-Komposer-Weight]
+Type=int
diff --git a/libkdepim/komposer/core/komposerplugin.desktop b/libkdepim/komposer/core/komposerplugin.desktop
new file mode 100644
index 000000000..08b450d6d
--- /dev/null
+++ b/libkdepim/komposer/core/komposerplugin.desktop
@@ -0,0 +1,60 @@
+[Desktop Entry]
+Type=ServiceType
+X-KDE-ServiceType=Komposer/Plugin
+X-KDE-Derived=KPluginInfo
+Name=Komposer Plugin
+Name[af]=Komposer inprop module
+Name[bg]=ПриÑтавка за Komposer
+Name[br]=Lugent Komposer
+Name[bs]=Komposer dodatak
+Name[ca]=Endollable Komposer
+Name[cs]=Komposer modul
+Name[cy]=Ategyn Kyfansoddydd
+Name[da]=Brevskriver-plugin
+Name[de]=Komposer-Modul
+Name[el]=ΠÏόσθετο του Komposer
+Name[eo]=Komposer-kromaĵo
+Name[es]=Accesorio Komposer
+Name[et]=Komposeri plugin
+Name[eu]=Komposer plugin-a
+Name[fa]=وصلۀ Komposer
+Name[fi]=Komposer-liitännäinen
+Name[fr]=Module de Komposer
+Name[fy]=Komposer-plugin
+Name[ga]=Breiseán Komposer
+Name[gl]=Extensión Komposer
+Name[he]=תןסף Kompoer
+Name[hi]=कमà¥à¤ªà¥‹à¤œà¤¼à¤° पà¥à¤²à¤—इन
+Name[hu]=Komposer bővítőmodul
+Name[is]=Komposer íforrit
+Name[it]=Plugin Komposer
+Name[ja]=Komposer プラグイン
+Name[ka]=Komposer მáƒáƒ“ული
+Name[kk]=Komposer плагин модулі
+Name[km]=កម្មវិធី​ជំនួយ Komposer
+Name[ko]=Komposer 플러그ì¸
+Name[lt]=Komposer priedas
+Name[ms]=Plugin Komposer
+Name[nb]=Komposer-programtillegg
+Name[nds]=Komposer-Moduul
+Name[ne]=कमà¥à¤ªà¥‹à¤œà¤° पà¥à¤²à¤—इन
+Name[nn]=Komposer-programtillegg
+Name[pl]=Wtyczka Komposer
+Name[pt]='Plugin' do Kompositor
+Name[pt_BR]=Plug-in do Komposer
+Name[ro]=Modul Komposer
+Name[ru]=Модуль Komposer
+Name[sk]=Modul Komposer
+Name[sl]=Vstavek za Komposer
+Name[sr]=Прикључак Komposer-а
+Name[sr@Latn]=PrikljuÄak Komposer-a
+Name[sv]=Komposer-insticksprogram
+Name[ta]=கமà¯à®ªà¯‹à®šà®°à¯ சொரà¯à®•à¯à®ªà¯à®ªà¯Šà®°à¯à®³à¯
+Name[tg]=Модули Komposer
+Name[tr]=Komposer Eklentisi
+Name[uk]=Втулок Komposer
+Name[zh_CN]=Komposer æ’件
+Name[zh_TW]=Komposer 外掛程å¼
+
+[PropertyDef::X-Komposer-Version]
+Type=int
diff --git a/libkdepim/komposer/core/komposerui.rc b/libkdepim/komposer/core/komposerui.rc
new file mode 100644
index 000000000..83ec4d299
--- /dev/null
+++ b/libkdepim/komposer/core/komposerui.rc
@@ -0,0 +1,51 @@
+<!DOCTYPE kpartgui >
+<kpartgui version="2" name="komposer" >
+<MenuBar>
+ <Menu name="file" noMerge="1">
+ <text>&amp;Message</text>
+ <Action name="new_composer" />
+ <Action name="open_mailreader" />
+ <Separator/>
+ <Action name="send_default" />
+ <Action name="send_alternative" />
+ <Action name="save_in_drafts" />
+ <Separator/>
+ <Action name="insert_file" />
+ <Action name="file_print" />
+ <Separator/>
+ <Merge/>
+ <Separator/>
+ <Action name="file_close" />
+ </Menu>
+ <Merge />
+ <Menu noMerge="1" name="attach">
+ <text>&amp;Attach</text>
+ <Merge/>
+ <Separator/>
+ <Action name="attach_file"/>
+ <Action name="remove_attachment"/>
+ <Action name="attachment_properties"/>
+ </Menu>
+ <Menu noMerge="1" name="Tools">
+ <text>&amp;Tools</text>
+ <Merge/>
+ <Action name="addressbook"/>
+ </Menu>
+ <Menu noMerge="1" name="settings">
+ <text>&amp;Settings</text>
+ <Merge/>
+ <Separator/>
+ <Action name="settings_configure_komposer"/>
+ </Menu>
+</MenuBar>
+<ToolBar position="Top" iconText="IconOnly" noMerge="1" name="mainToolBar"><text>Main Toolbar</text>
+ <Action name="send_default" />
+ <Action name="send_alternative" />
+ <Separator/>
+ <Action name="attach_file"/>
+ <Separator/>
+ <Merge/>
+ <Separator/>
+ <Action name="help_whats_this"/>
+</ToolBar>
+</kpartgui>
diff --git a/libkdepim/komposer/core/plugin.cpp b/libkdepim/komposer/core/plugin.cpp
new file mode 100644
index 000000000..5706b0d08
--- /dev/null
+++ b/libkdepim/komposer/core/plugin.cpp
@@ -0,0 +1,80 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
+/**
+ * plugin.cpp
+ *
+ * Copyright (C) 2003 Zack Rusin <zack@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#include "plugin.h"
+
+#include "core.h"
+
+#include <kdebug.h>
+#include <qstring.h>
+
+namespace Komposer
+{
+
+class Plugin::Private
+{
+public:
+ //Core* core;
+};
+
+Plugin::Plugin( QObject *parent, const char *name, const QStringList & )
+ : QObject( parent, name ), d( new Private )
+{
+ //d->core = core;
+}
+
+Plugin::~Plugin()
+{
+ delete d; d = 0;
+}
+
+void
+Plugin::startedComposing()
+{
+}
+
+void
+Plugin::sendClicked()
+{
+}
+
+void
+Plugin::quitClicked()
+{
+}
+
+void
+Plugin::aboutToUnload()
+{
+ kdDebug()<<"plugin unloading"<<endl;
+ emit readyForUnload();
+}
+
+Core*
+Plugin::core() const
+{
+ return 0;
+ //return d->core;
+}
+
+}//end namespace Komposer
+
+#include "plugin.moc"
diff --git a/libkdepim/komposer/core/plugin.h b/libkdepim/komposer/core/plugin.h
new file mode 100644
index 000000000..402a7bc81
--- /dev/null
+++ b/libkdepim/komposer/core/plugin.h
@@ -0,0 +1,75 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
+/**
+ * plugin.h
+ *
+ * Copyright (C) 2003 Zack Rusin <zack@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#ifndef KOMPOSER_PLUGIN_H
+#define KOMPOSER_PLUGIN_H
+
+#include <qobject.h>
+#include <kxmlguiclient.h>
+
+namespace Komposer
+{
+ class Core;
+
+ class Plugin : public QObject,
+ virtual public KXMLGUIClient
+ {
+ Q_OBJECT
+ public:
+ virtual ~Plugin();
+
+ signals:
+ void statusMessage( const QString & );
+ void readyForUnload();
+
+ protected slots:
+ /**
+ * Called when a new message is created.
+ */
+ virtual void startedComposing();
+
+ /**
+ * Called after the send button has been pressed
+ * and before the message has been sent.
+ */
+ virtual void sendClicked();
+
+ /**
+ * Called after the quit button has been pressed
+ */
+ virtual void quitClicked();
+
+ virtual void aboutToUnload();
+
+ protected:
+ Core *core() const;
+ protected:
+ friend class PluginManager;
+ Plugin( QObject *parent, const char *name, const QStringList& args = QStringList() );
+
+ private:
+ class Private;
+ Private *d;
+ };
+
+}
+
+#endif
diff --git a/libkdepim/komposer/core/pluginmanager.cpp b/libkdepim/komposer/core/pluginmanager.cpp
new file mode 100644
index 000000000..82e7f0e9b
--- /dev/null
+++ b/libkdepim/komposer/core/pluginmanager.cpp
@@ -0,0 +1,489 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 2; -*-
+/**
+ * pluginmanager.cpp
+ * Most of this code has been lifted from Martijn's KopetePluginManager class
+ *
+ * Copyright (C) 2004 Zack Rusin <zack@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#include "pluginmanager.h"
+
+#include "plugin.h"
+
+#include <qapplication.h>
+#include <qfile.h>
+#include <qregexp.h>
+#include <qtimer.h>
+#include <qvaluestack.h>
+
+#include <kapplication.h>
+#include <kdebug.h>
+#include <kparts/componentfactory.h>
+#include <kplugininfo.h>
+#include <ksettings/dispatcher.h>
+#include <ksimpleconfig.h>
+#include <kstandarddirs.h>
+#include <kstaticdeleter.h>
+#include <kurl.h>
+
+
+namespace Komposer
+{
+
+class PluginManager::Private
+{
+public:
+ // All available plugins, regardless of category, and loaded or not
+ QValueList<KPluginInfo*> plugins;
+
+ // Dict of all currently loaded plugins, mapping the KPluginInfo to
+ // a plugin
+ QMap<KPluginInfo*, Plugin*> loadedPlugins;
+
+ // The plugin manager's mode. The mode is StartingUp until loadAllPlugins()
+ // has finished loading the plugins, after which it is set to Running.
+ // ShuttingDown and DoneShutdown are used during Komposer shutdown by the
+ // async unloading of plugins.
+ enum ShutdownMode { StartingUp, Running, ShuttingDown, DoneShutdown };
+ ShutdownMode shutdownMode;
+
+ KSharedConfig::Ptr config;
+ // Plugins pending for loading
+ QValueStack<QString> pluginsToLoad;
+};
+
+PluginManager::PluginManager( QObject *parent )
+ : QObject( parent )
+{
+ d = new Private;
+
+ // We want to add a reference to the application's event loop so we
+ // can remain in control when all windows are removed.
+ // This way we can unload plugins asynchronously, which is more
+ // robust if they are still doing processing.
+ kapp->ref();
+ d->shutdownMode = Private::StartingUp;
+
+ KSettings::Dispatcher::self()->registerInstance( KGlobal::instance(),
+ this, SLOT( loadAllPlugins() ) );
+
+ d->plugins = KPluginInfo::fromServices(
+ KTrader::self()->query( QString::fromLatin1( "Komposer/Plugin" ),
+ QString::fromLatin1( "[X-Komposer-Version] == 1" ) ) );
+}
+
+PluginManager::~PluginManager()
+{
+ if ( d->shutdownMode != Private::DoneShutdown ) {
+ slotShutdownTimeout();
+#if 0
+ kdWarning() << k_funcinfo
+ << "Destructing plugin manager without going through "
+ << "the shutdown process!"
+ << endl
+ << kdBacktrace(10) << endl;
+#endif
+ }
+
+ // Quick cleanup of the remaining plugins, hope it helps
+ QMap<KPluginInfo*, Plugin*>::ConstIterator it;
+ for ( it = d->loadedPlugins.begin(); it != d->loadedPlugins.end(); /* EMPTY */ )
+ {
+ // Remove causes the iterator to become invalid, so pre-increment first
+ QMap<KPluginInfo*, Plugin*>::ConstIterator nextIt( it );
+ ++nextIt;
+ kdWarning() << k_funcinfo << "Deleting stale plugin '"
+ << it.data()->name() << "'" << endl;
+ delete it.data();
+ it = nextIt;
+ }
+
+ delete d;
+}
+
+QValueList<KPluginInfo*>
+PluginManager::availablePlugins( const QString &category ) const
+{
+ if ( category.isEmpty() )
+ return d->plugins;
+
+ QValueList<KPluginInfo*> result;
+ QValueList<KPluginInfo*>::ConstIterator it;
+ for ( it = d->plugins.begin(); it != d->plugins.end(); ++it )
+ {
+ if ( ( *it )->category() == category )
+ result.append( *it );
+ }
+
+ return result;
+}
+
+QMap<KPluginInfo*, Plugin*>
+PluginManager::loadedPlugins( const QString &category ) const
+{
+ QMap<KPluginInfo*, Plugin*> result;
+ QMap<KPluginInfo*, Plugin*>::ConstIterator it;
+ for ( it = d->loadedPlugins.begin(); it != d->loadedPlugins.end(); ++it )
+ {
+ if ( category.isEmpty() || it.key()->category() == category )
+ result.insert( it.key(), it.data() );
+ }
+
+ return result;
+}
+
+void
+PluginManager::shutdown()
+{
+ d->shutdownMode = Private::ShuttingDown;
+
+ // Remove any pending plugins to load, we're shutting down now :)
+ d->pluginsToLoad.clear();
+
+ // Ask all plugins to unload
+ if ( d->loadedPlugins.empty() ) {
+ d->shutdownMode = Private::DoneShutdown;
+ } else {
+ QMap<KPluginInfo*, Plugin*>::ConstIterator it;
+ for ( it = d->loadedPlugins.begin(); it != d->loadedPlugins.end(); /* EMPTY */ )
+ {
+ // Remove causes the iterator to become invalid, so pre-increment first
+ QMap<KPluginInfo*, Plugin*>::ConstIterator nextIt( it );
+ ++nextIt;
+ it.data()->aboutToUnload();
+ it = nextIt;
+ }
+ }
+
+ QTimer::singleShot( 3000, this, SLOT(slotShutdownTimeout()) );
+}
+
+void
+PluginManager::slotPluginReadyForUnload()
+{
+ // Using QObject::sender() is on purpose here, because otherwise all
+ // plugins would have to pass 'this' as parameter, which makes the API
+ // less clean for plugin authors
+ Plugin* plugin = dynamic_cast<Plugin*>( const_cast<QObject*>( sender() ) );
+ if ( !plugin )
+ {
+ kdWarning() << k_funcinfo << "Calling object is not a plugin!" << endl;
+ return;
+
+ }
+ kdDebug()<<"manager unloading"<<endl;
+ plugin->deleteLater();
+}
+
+void
+PluginManager::slotShutdownTimeout()
+{
+ // When we were already done the timer might still fire.
+ // Do nothing in that case.
+ if ( d->shutdownMode == Private::DoneShutdown )
+ return;
+
+#ifndef NDEBUG
+ QStringList remaining;
+ for ( QMap<KPluginInfo*, Plugin*>::ConstIterator it = d->loadedPlugins.begin();
+ it != d->loadedPlugins.end(); ++it )
+ remaining.append( it.key()->pluginName() );
+
+ kdWarning() << k_funcinfo << "Some plugins didn't shutdown in time!" << endl
+ << "Remaining plugins: "
+ << remaining.join( QString::fromLatin1( ", " ) ) << endl
+ << "Forcing Komposer shutdown now." << endl;
+#endif
+
+ slotShutdownDone();
+}
+
+void
+PluginManager::slotShutdownDone()
+{
+ d->shutdownMode = Private::DoneShutdown;
+
+ kapp->deref();
+}
+
+void
+PluginManager::loadAllPlugins()
+{
+ // FIXME: We need session management here - Martijn
+
+ if ( !d->config )
+ d->config = KSharedConfig::openConfig( "komposerrc" );
+
+ QMap<QString, QString> entries = d->config->entryMap(
+ QString::fromLatin1( "Plugins" ) );
+
+ QMap<QString, QString>::Iterator it;
+ for ( it = entries.begin(); it != entries.end(); ++it )
+ {
+ QString key = it.key();
+ if ( key.endsWith( QString::fromLatin1( "Enabled" ) ) )
+ {
+ key.setLength( key.length() - 7 );
+ //kdDebug() << k_funcinfo << "Set " << key << " to " << it.data() << endl;
+
+ if ( it.data() == QString::fromLatin1( "true" ) )
+ {
+ if ( !plugin( key ) )
+ d->pluginsToLoad.push( key );
+ }
+ else
+ {
+ // FIXME: Does this ever happen? As loadAllPlugins is only called on startup
+ // I'd say 'no'. If it does, it should be made async
+ // though. - Martijn
+ if ( plugin( key ) )
+ unloadPlugin( key );
+ }
+ }
+ }
+
+ // Schedule the plugins to load
+ QTimer::singleShot( 0, this, SLOT( slotLoadNextPlugin() ) );
+}
+
+void PluginManager::slotLoadNextPlugin()
+{
+ if ( d->pluginsToLoad.isEmpty() )
+ {
+ if ( d->shutdownMode == Private::StartingUp )
+ {
+ d->shutdownMode = Private::Running;
+ emit allPluginsLoaded();
+ }
+ return;
+ }
+
+ QString key = d->pluginsToLoad.pop();
+ loadPluginInternal( key );
+
+ // Schedule the next run unconditionally to avoid code duplication on the
+ // allPluginsLoaded() signal's handling. This has the added benefit that
+ // the signal is delayed one event loop, so the accounts are more likely
+ // to be instantiated.
+ QTimer::singleShot( 0, this, SLOT( slotLoadNextPlugin() ) );
+}
+
+Plugin*
+PluginManager::loadPlugin( const QString &pluginId,
+ PluginLoadMode mode /* = LoadSync */ )
+{
+ if ( mode == LoadSync ) {
+ return loadPluginInternal( pluginId );
+ } else {
+ d->pluginsToLoad.push( pluginId );
+ QTimer::singleShot( 0, this, SLOT( slotLoadNextPlugin() ) );
+ return 0;
+ }
+}
+
+Plugin*
+PluginManager::loadPluginInternal( const QString &pluginId )
+{
+ KPluginInfo* info = infoForPluginId( pluginId );
+ if ( !info ) {
+ kdWarning() << k_funcinfo << "Unable to find a plugin named '"
+ << pluginId << "'!" << endl;
+ return 0;
+ }
+
+ if ( d->loadedPlugins.contains( info ) )
+ return d->loadedPlugins[ info ];
+
+ int error = 0;
+ Plugin *plugin = KParts::ComponentFactory::createInstanceFromQuery<Komposer::Plugin>(
+ QString::fromLatin1( "Komposer/Plugin" ),
+ QString::fromLatin1( "[X-KDE-PluginInfo-Name]=='%1'" ).arg( pluginId ),
+ this, 0, QStringList(), &error );
+
+ if ( plugin ) {
+ d->loadedPlugins.insert( info, plugin );
+ info->setPluginEnabled( true );
+
+ connect( plugin, SIGNAL(destroyed(QObject*)),
+ this, SLOT(slotPluginDestroyed(QObject*)) );
+ connect( plugin, SIGNAL(readyForUnload()),
+ this, SLOT(slotPluginReadyForUnload()) );
+
+ kdDebug() << k_funcinfo << "Successfully loaded plugin '"
+ << pluginId << "'" << endl;
+
+ emit pluginLoaded( plugin );
+ } else {
+ switch ( error ) {
+ case KParts::ComponentFactory::ErrNoServiceFound:
+ kdDebug() << k_funcinfo << "No service implementing the given mimetype "
+ << "and fullfilling the given constraint expression can be found."
+ << endl;
+ break;
+
+ case KParts::ComponentFactory::ErrServiceProvidesNoLibrary:
+ kdDebug() << "the specified service provides no shared library." << endl;
+ break;
+
+ case KParts::ComponentFactory::ErrNoLibrary:
+ kdDebug() << "the specified library could not be loaded." << endl;
+ break;
+
+ case KParts::ComponentFactory::ErrNoFactory:
+ kdDebug() << "the library does not export a factory for creating components."
+ << endl;
+ break;
+
+ case KParts::ComponentFactory::ErrNoComponent:
+ kdDebug() << "the factory does not support creating components "
+ << "of the specified type."
+ << endl;
+ break;
+ }
+
+ kdDebug() << k_funcinfo << "Loading plugin '" << pluginId
+ << "' failed, KLibLoader reported error: '"
+ << KLibLoader::self()->lastErrorMessage()
+ << "'" << endl;
+ }
+
+ return plugin;
+}
+
+bool
+PluginManager::unloadPlugin( const QString &spec )
+{
+ QMap<KPluginInfo*, Plugin*>::ConstIterator it;
+ for ( it = d->loadedPlugins.begin(); it != d->loadedPlugins.end(); ++it )
+ {
+ if ( it.key()->pluginName() == spec )
+ {
+ it.data()->aboutToUnload();
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void
+PluginManager::slotPluginDestroyed( QObject *plugin )
+{
+ QMap<KPluginInfo*, Plugin*>::Iterator it;
+ for ( it = d->loadedPlugins.begin(); it != d->loadedPlugins.end(); ++it )
+ {
+ if ( it.data() == plugin )
+ {
+ d->loadedPlugins.erase( it );
+ break;
+ }
+ }
+
+ if ( d->shutdownMode == Private::ShuttingDown && d->loadedPlugins.isEmpty() )
+ {
+ // Use a timer to make sure any pending deleteLater() calls have
+ // been handled first
+ QTimer::singleShot( 0, this, SLOT(slotShutdownDone()) );
+ }
+}
+
+Plugin*
+PluginManager::plugin( const QString &pluginId ) const
+{
+ KPluginInfo *info = infoForPluginId( pluginId );
+ if ( !info )
+ return 0;
+
+ if ( d->loadedPlugins.contains( info ) )
+ return d->loadedPlugins[ info ];
+ else
+ return 0;
+}
+
+QString
+PluginManager::pluginName( const Plugin *plugin ) const
+{
+ QMap<KPluginInfo*, Plugin*>::ConstIterator it;
+ for ( it = d->loadedPlugins.begin(); it != d->loadedPlugins.end(); ++it )
+ {
+ if ( it.data() == plugin )
+ return it.key()->name();
+ }
+
+ return QString::fromLatin1( "Unknown" );
+}
+
+QString
+PluginManager::pluginId( const Plugin *plugin ) const
+{
+ QMap<KPluginInfo*, Plugin*>::ConstIterator it;
+ for ( it = d->loadedPlugins.begin(); it != d->loadedPlugins.end(); ++it )
+ {
+ if ( it.data() == plugin )
+ return it.key()->pluginName();
+ }
+
+ return QString::fromLatin1( "unknown" );
+}
+
+QString
+PluginManager::pluginIcon( const Plugin *plugin ) const
+{
+ QMap<KPluginInfo*, Plugin*>::ConstIterator it;
+ for ( it = d->loadedPlugins.begin(); it != d->loadedPlugins.end(); ++it )
+ {
+ if ( it.data() == plugin )
+ return it.key()->icon();
+ }
+
+ return QString::fromLatin1( "Unknown" );
+}
+
+KPluginInfo*
+PluginManager::infoForPluginId( const QString &pluginId ) const
+{
+ QValueList<KPluginInfo*>::ConstIterator it;
+ for ( it = d->plugins.begin(); it != d->plugins.end(); ++it )
+ {
+ if ( ( *it )->pluginName() == pluginId )
+ return *it;
+ }
+
+ return 0;
+}
+
+bool
+PluginManager::setPluginEnabled( const QString &pluginId, bool enabled /* = true */ )
+{
+ if ( !d->config )
+ d->config = KSharedConfig::openConfig( "komposerrc" );
+
+ d->config->setGroup( "Plugins" );
+
+
+ if ( !infoForPluginId( pluginId ) )
+ return false;
+
+ d->config->writeEntry( pluginId + QString::fromLatin1( "Enabled" ), enabled );
+ d->config->sync();
+
+ return true;
+}
+
+}
+
+#include "pluginmanager.moc"
diff --git a/libkdepim/komposer/core/pluginmanager.h b/libkdepim/komposer/core/pluginmanager.h
new file mode 100644
index 000000000..b19f8ad27
--- /dev/null
+++ b/libkdepim/komposer/core/pluginmanager.h
@@ -0,0 +1,251 @@
+// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
+/**
+ * pluginmanager.h
+ *
+ * Copyright (C) 2004 Zack Rusin <zack@kde.org>
+ * Copyright (C) 2003 Martijn Klingens <klingens@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#ifndef KOMPOSER_PLUGINMANAGER_H
+#define KOMPOSER_PLUGINMANAGER_H
+
+#include <qmap.h>
+#include <qobject.h>
+#include <qstring.h>
+#include <qstringlist.h>
+#include <qvaluelist.h>
+
+class KPluginInfo;
+
+namespace Komposer
+{
+
+ class Plugin;
+
+ class PluginManager : public QObject
+ {
+ Q_OBJECT
+
+ public:
+ PluginManager( QObject * );
+
+ ~PluginManager();
+
+ /**
+ * Returns a list of all available plugins for the given category.
+ * Currently there are two categories, "Plugins" and "Editors", but
+ * you can add your own categories if you want.
+ *
+ * If you pass an empty string you get the complete list of ALL plugins.
+ *
+ * You can query all information on the plugins through the @ref KPluginInfo
+ * interface.
+ */
+ QValueList<KPluginInfo*> availablePlugins( const QString &category
+ = QString::null ) const;
+
+ /**
+ * Returns a list of all plugins that are actually loaded.
+ * If you omit the category you get all, otherwise it's a filtered list.
+ * See also @ref availablePlugins().
+ */
+ QMap<KPluginInfo*, Plugin*> loadedPlugins( const QString &category
+ = QString::null ) const;
+
+ /**
+ * @brief Search by plugin name. This is the key used as X-KDE-PluginInfo-Name
+ * in the .desktop file, e.g. "komposer_attachment"
+ *
+ * @return The @ref Plugin object found by the search, or a null
+ * pointer if the plugin is not loaded.
+ *
+ * If you want to also load the plugin you can better use @ref loadPlugin,
+ * which returns
+ * the pointer to the plugin if it's already loaded.
+ */
+ Plugin* plugin( const QString &pluginName ) const;
+
+ /**
+ * @brief Return the short user-visible name of the plugin.
+ *
+ * If you want to have the internal name, use @ref pluginId() instead.
+ *
+ * @return The name of the protocol, in the user's locale.
+ */
+ QString pluginName( const Plugin *plugin ) const;
+
+ /**
+ * @brief Return the internal name of the plugin.
+ *
+ * You cannot display this name on the screen, it's used internally for
+ * passing around IDs. Use @ref pluginName() for a string ready for display.
+ *
+ * @return The name of the protocol, in the user's locale.
+ */
+ QString pluginId( const Plugin *plugin ) const;
+
+ /**
+ * @brief Unload the plugin specified by @p pluginName
+ */
+ bool unloadPlugin( const QString &pluginName );
+
+ /**
+ * @brief Retrieve the name of the icon for a @ref Plugin.
+ *
+ * @return An empty string if the given plugin is not loaded
+ * or the filename of the icon to use.
+ */
+ QString pluginIcon( const Plugin *plugin ) const;
+
+ /**
+ * Shuts down the plugin manager on Komposer shutdown, but first
+ * unloads all plugins asynchronously.
+ *
+ * After 3 seconds all plugins should be removed; what's still left
+ * by then is unloaded through a hard delete instead.
+ *
+ * Note that this call also derefs the plugin manager from the event
+ * loop, so do NOT call this method when not terminating Komposer!
+ */
+ void shutdown();
+
+ /**
+ * Enable a plugin.
+ *
+ * This marks a plugin as enabled in the config file, so loadAll()
+ * can pick it up later.
+ *
+ * This method does not actually load a plugin, it only edits the
+ * config file.
+ *
+ * @param name is the name of the plugin as it is listed in the .desktop
+ * file in the X-KDE-Library field.
+ *
+ * Returns false when no appropriate plugin can be found.
+ */
+ bool setPluginEnabled( const QString &name, bool enabled = true );
+
+ /**
+ * Plugin loading mode. Used by @loadPlugin. Code that doesn't want to block
+ * the GUI and/or lot a lot of plugins at once should use Async loading.
+ * The default is sync loading.
+ */
+ enum PluginLoadMode { LoadSync, LoadAsync };
+
+ public slots:
+ /**
+ * @brief Load a single plugin by plugin name. Returns an existing plugin
+ * if one is already loaded in memory.
+ *
+ * If mode is set to Async, the plugin will be queued and loaded in
+ * the background. This method will return a null pointer. To get
+ * the loaded plugin you can track the @ref pluginLoaded() signal.
+ *
+ * See also @ref plugin().
+ */
+ Plugin* loadPlugin( const QString &pluginId, PluginLoadMode mode = LoadSync );
+
+ /**
+ * @brief Loads all the enabled plugins. Also used to reread the
+ * config file when the configuration has changed.
+ */
+ void loadAllPlugins();
+
+ signals:
+ /**
+ * @brief Signals a new plugin has just been loaded.
+ */
+ void pluginLoaded( Plugin *plugin );
+
+ /**
+ * @brief All plugins have been loaded by the plugin manager.
+ *
+ * This signal is emitted exactly ONCE, when the plugin manager has emptied
+ * its plugin queue for the first time. This means that if you call an async
+ * loadPlugin() before loadAllPlugins() this signal is probably emitted after
+ * the initial call completes, unless you are quick enough to fill the queue
+ * before it completes, which is a dangerous race you shouldn't count upon :)
+ *
+ * The signal is delayed one event loop iteration through a singleShot timer,
+ * but that is not guaranteed to be enough for account instantiation. You may
+ * need an additional timer for it in the code if you want to programmatically
+ * act on it.
+ *
+ * If you use the signal for enabling/disabling GUI objects there is little
+ * chance a user is able to activate them in the short while that's remaining,
+ * the slow part of the code is over now and the remaining processing time
+ * is neglectable for the user.
+ */
+ void allPluginsLoaded();
+
+ private slots:
+ /**
+ * @brief Cleans up some references if the plugin is destroyed
+ */
+ void slotPluginDestroyed( QObject *plugin );
+
+ /**
+ * shutdown() starts a timer, when it fires we force all plugins
+ * to be unloaded here by deref()-ing the event loop to trigger the plugin
+ * manager's destruction
+ */
+ void slotShutdownTimeout();
+
+ /**
+ * Common entry point to deref() the KApplication. Used both by the clean
+ * shutdown and the timeout condition of slotShutdownTimeout()
+ */
+ void slotShutdownDone();
+
+ /**
+ * Emitted by a Plugin when it's ready for unload
+ */
+ void slotPluginReadyForUnload();
+
+ /**
+ * Load a plugin from our queue. Does nothing if the queue is empty.
+ * Schedules itself again if more plugins are pending.
+ */
+ void slotLoadNextPlugin();
+
+ private:
+ /**
+ * @internal
+ *
+ * The internal method for loading plugins.
+ * Called by @ref loadPlugin directly or through the queue for async plugin
+ * loading.
+ */
+ Plugin *loadPluginInternal( const QString &pluginId );
+
+ /**
+ * @internal
+ *
+ * Find the KPluginInfo structure by key. Reduces some code duplication.
+ *
+ * Returns a null pointer when no plugin info is found.
+ */
+ KPluginInfo *infoForPluginId( const QString &pluginId ) const;
+ private:
+ class Private;
+ Private *d;
+ };
+
+}
+
+#endif // KOMPOSER_PLUGINMANAGER_H
diff --git a/libkdepim/komposer/core/prefsmodule.cpp b/libkdepim/komposer/core/prefsmodule.cpp
new file mode 100644
index 000000000..b907154c4
--- /dev/null
+++ b/libkdepim/komposer/core/prefsmodule.cpp
@@ -0,0 +1,142 @@
+/**
+ * prefsmodule.cpp
+ *
+ * Copyright (C) 2003-2004 Zack Rusin <zack@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include "prefsmodule.h"
+
+#include <kaboutdata.h>
+#include <kdebug.h>
+#include <kcombobox.h>
+#include <klocale.h>
+#include <ktrader.h>
+
+#include <qlayout.h>
+#include <qlabel.h>
+#include <qbuttongroup.h>
+
+#include <kdepimmacros.h>
+
+extern "C"
+{
+ KDE_EXPORT KCModule *create_komposerconfig( QWidget *parent, const char * ) {
+ return new Komposer::PrefsModule( parent, "komposerprefs" );
+ }
+}
+using namespace Komposer;
+
+PrefsModule::PrefsModule( QWidget *parent, const char *name )
+ : KPrefsModule( Komposer::Prefs::self(), parent, name )
+{
+ QVBoxLayout *topLayout = new QVBoxLayout( this );
+
+ EditorSelection *editors = new EditorSelection( i18n( "Editors" ),
+ Komposer::Prefs::self()->m_activeEditor,
+ this );
+ topLayout->addWidget( editors->groupBox() );
+
+ addWid( editors );
+
+ load();
+}
+
+const KAboutData*
+PrefsModule::aboutData() const
+{
+ KAboutData *about = new KAboutData( I18N_NOOP( "komposerconfig" ),
+ I18N_NOOP( "KDE Komposer" ),
+ 0, 0, KAboutData::License_LGPL,
+ I18N_NOOP( "(c), 2003-2004 Zack Rusin" ) );
+
+ about->addAuthor( "Zack Rusin", 0, "zack@kde.org" );;
+
+ return about;
+}
+
+
+EditorSelection::EditorSelection( const QString &text, QString &reference,
+ QWidget *parent )
+ : m_reference( reference )
+{
+ m_box = new QGroupBox( 0, Qt::Vertical, text, parent );
+ QVBoxLayout *boxLayout = new QVBoxLayout( m_box->layout() );
+ boxLayout->setAlignment( Qt::AlignTop );
+
+ m_editorsCombo = new KComboBox( m_box );
+ boxLayout->addWidget( m_editorsCombo );
+
+ connect( m_editorsCombo, SIGNAL(activated(const QString&)),
+ SLOT(slotActivated(const QString&)) );
+}
+
+EditorSelection::~EditorSelection()
+{
+}
+
+QGroupBox*
+EditorSelection::groupBox() const
+{
+ return m_box;
+}
+
+void
+EditorSelection::readConfig()
+{
+ m_editorsCombo->clear();
+
+ KTrader::OfferList editors = KTrader::self()->query(
+ QString::fromLatin1( "Komposer/Editor" ) );
+ KTrader::OfferList::ConstIterator it;
+ int i = 0;
+ for ( it = editors.begin(); it != editors.end(); ++it, ++i ) {
+ if ( !(*it)->hasServiceType( QString::fromLatin1( "Komposer/Editor" ) ) )
+ continue;
+
+ QString name = (*it)->property( "X-KDE-KomposerIdentifier" ).toString();
+ m_editorsCombo->insertItem( name );
+ if ( m_reference.contains( name ) )
+ m_editorsCombo->setCurrentItem( i );
+ }
+}
+
+void EditorSelection::writeConfig()
+{
+ m_reference = m_services[ m_editorsCombo->currentText()]->
+ property( "X-KDE-KomposerIdentifier" ).toString();
+}
+
+void
+EditorSelection::slotActivated( const QString &editor )
+{
+ if ( !editor.isEmpty() )
+ emit changed();
+}
+
+void
+EditorSelection::setItem( const QString &str )
+{
+ for ( int i = 0; i < m_editorsCombo->count(); ++i ) {
+ if ( m_editorsCombo->text( i ) == str ) {
+ m_editorsCombo->setCurrentItem( i );
+ break;
+ }
+ }
+}
+
+#include "prefsmodule.moc"
diff --git a/libkdepim/komposer/core/prefsmodule.h b/libkdepim/komposer/core/prefsmodule.h
new file mode 100644
index 000000000..95ad3eef4
--- /dev/null
+++ b/libkdepim/komposer/core/prefsmodule.h
@@ -0,0 +1,70 @@
+/*
+ * prefsmodule.h
+ *
+ * Copyright (C) 2003 Zack Rusin <zack@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#ifndef KOMPOSER_PREFSMODULE_H
+#define KOMPOSER_PREFSMODULE_H
+
+#include <kprefsdialog.h>
+#include <kservice.h>
+#include <qmap.h>
+class QGroupBox;
+class QListViewItem;
+
+class KAboutData;
+class KComboBox;
+
+namespace Komposer {
+
+ class PrefsModule : public KPrefsModule
+ {
+ Q_OBJECT
+ public:
+ PrefsModule( QWidget *parent=0, const char *name=0 );
+ virtual const KAboutData *aboutData() const;
+ };
+
+ class EditorSelection : public KPrefsWid
+ {
+ Q_OBJECT
+
+ public:
+ EditorSelection( const QString &text, QString &reference, QWidget *parent );
+ ~EditorSelection();
+
+ void readConfig();
+ void writeConfig();
+
+ QGroupBox *groupBox() const;
+
+ private slots:
+ void slotActivated( const QString & );
+
+ private:
+ void setItem( const QString & );
+ private:
+ QString &m_reference;
+
+ QGroupBox *m_box;
+ KComboBox *m_editorsCombo;
+ QMap<QString, KService::Ptr> m_services;
+ };
+}
+
+#endif
diff --git a/libkdepim/komposer/core/settings.kcfgc b/libkdepim/komposer/core/settings.kcfgc
new file mode 100644
index 000000000..fc98478a9
--- /dev/null
+++ b/libkdepim/komposer/core/settings.kcfgc
@@ -0,0 +1,9 @@
+# Code generation options for kconfig_compiler
+File=komposer.kcfg
+NameSpace=Komposer
+ClassName=Config
+Singleton=true
+Mutators=true
+#MemberVariables=public
+GlobalEnums=true
+#SetUserTexts=true
diff --git a/libkdepim/komposer/core/tests/Makefile.am b/libkdepim/komposer/core/tests/Makefile.am
new file mode 100644
index 000000000..de3a40f90
--- /dev/null
+++ b/libkdepim/komposer/core/tests/Makefile.am
@@ -0,0 +1,20 @@
+INCLUDES = -I$(top_builddir)/libkdepim/komposer/core $(all_includes)
+
+check_PROGRAMS = testfactory testmanager testkomposer
+
+METASOURCES = AUTO
+
+testfactory_SOURCES = main.cpp managertest.cpp
+testfactory_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+testfactory_LDADD = ../libkomposer.la
+
+testmanager_SOURCES = testmanager.cpp
+testmanager_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+testmanager_LDADD = ../libkomposer.la
+
+testkomposer_SOURCES = testkomposer.cpp
+testkomposer_LDFLAGS = $(all_libraries) $(KDE_RPATH)
+testkomposer_LDADD = ../libkomposer.la
+
+check: testfactory
+ @./testfactory 2>&1 | grep "tests:"
diff --git a/libkdepim/komposer/core/tests/main.cpp b/libkdepim/komposer/core/tests/main.cpp
new file mode 100644
index 000000000..4a33a2f13
--- /dev/null
+++ b/libkdepim/komposer/core/tests/main.cpp
@@ -0,0 +1,52 @@
+/**
+ * main.cpp
+ *
+ * Copyright (C) 2004 Zack Rusin <zack@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#include "testfactory.h"
+#include <kaboutdata.h>
+#include <kapplication.h>
+#include <kdebug.h>
+#include <klocale.h>
+#include <kcmdlineargs.h>
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+
+static const KCmdLineOptions options[] =
+{
+ {"verbose", "Verbose output", 0},
+ KCmdLineLastOption
+};
+int main( int argc, char** argv )
+{
+ KAboutData aboutData( "tests","Test","0.1" );
+ KCmdLineArgs::init( argc, argv, &aboutData );
+ KCmdLineArgs::addCmdLineOptions( options );
+
+ KApplication app;
+
+ KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
+ Q_UNUSED( args );
+
+ TestFactory t;
+ return t.runTests();
+}
diff --git a/libkdepim/komposer/core/tests/managertest.cpp b/libkdepim/komposer/core/tests/managertest.cpp
new file mode 100644
index 000000000..feec64599
--- /dev/null
+++ b/libkdepim/komposer/core/tests/managertest.cpp
@@ -0,0 +1,43 @@
+/**
+ * managertest.cpp
+ *
+ * Copyright (C) 2004 Zack Rusin <zack@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#include "managertest.h"
+
+#include "pluginmanager.h"
+using namespace Komposer;
+
+ManagerTest::ManagerTest( QObject* parent )
+ : QObject( parent )
+{
+ m_manager = new PluginManager( this );
+}
+
+
+void ManagerTest::allTests()
+{
+ CHECK( m_manager->availablePlugins().isEmpty(), true );
+ CHECK( m_manager->loadedPlugins().empty(), true );
+ CHECK( m_manager->plugin( "non-existing" ), ( Plugin* )0 );
+ m_manager->loadAllPlugins();
+ CHECK( m_manager->loadedPlugins().empty(), true );
+ m_manager->shutdown();
+}
+
+#include "managertest.moc"
diff --git a/libkdepim/komposer/core/tests/managertest.h b/libkdepim/komposer/core/tests/managertest.h
new file mode 100644
index 000000000..0148b29a8
--- /dev/null
+++ b/libkdepim/komposer/core/tests/managertest.h
@@ -0,0 +1,44 @@
+/*
+ * managertest.h
+ *
+ * Copyright (C) 2004 Zack Rusin <zack@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#ifndef MANAGERTEST_H
+#define MANAGERTEST_H
+
+#include <qobject.h>
+#include "tester.h"
+
+namespace Komposer {
+ class PluginManager;
+}
+
+class ManagerTest : public QObject,
+ public Tester
+{
+ Q_OBJECT
+public:
+ ManagerTest( QObject* parent = 0 );
+
+public slots:
+ void allTests();
+private:
+ Komposer::PluginManager* m_manager;
+};
+
+#endif
diff --git a/libkdepim/komposer/core/tests/tester.cpp b/libkdepim/komposer/core/tests/tester.cpp
new file mode 100644
index 000000000..7fe8a90b2
--- /dev/null
+++ b/libkdepim/komposer/core/tests/tester.cpp
@@ -0,0 +1,30 @@
+/**
+ * tester.cpp
+ *
+ * Copyright (C) 2004 Zack Rusin <zack@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#include "tester.h"
+
+
+Tester::Tester( QObject* parent )
+ : QObject( parent )
+{
+}
+
+
+#include "tester.moc"
diff --git a/libkdepim/komposer/core/tests/tester.h b/libkdepim/komposer/core/tests/tester.h
new file mode 100644
index 000000000..74ebd80d0
--- /dev/null
+++ b/libkdepim/komposer/core/tests/tester.h
@@ -0,0 +1,71 @@
+/*
+ * tester.h
+ *
+ * Copyright (C) 2004 Zack Rusin <zack@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#ifndef TESTER_H
+#define TESTER_H
+
+#include <kdebug.h>
+#include <qstringlist.h>
+
+#define CHECK( x, y ) check( __FILE__, __LINE__, #x, x, y )
+
+class Tester
+{
+public:
+ Tester() : m_tests( 0 ) {}
+ virtual ~Tester() {}
+
+public:
+ virtual void allTests() = 0;
+
+public:
+ int testsFinished() const {
+ return m_tests;
+ }
+ int testsFailed() const {
+ return m_errorList.count();
+ }
+ QStringList errorList() const {
+ return m_errorList;
+ }
+
+protected:
+ template<typename T>
+ void check( const char* file, int line, const char* str,
+ const T& result, const T& expectedResult )
+ {
+ if ( result != expectedResult ) {
+ QString error;
+ QTextStream ts( &error, IO_WriteOnly );
+ ts << file << "["<< line <<"]:"
+ <<" failed on \""<< str <<"\""
+ << "\ntests:\t\t result = "
+ << result
+ << ", expected = "<< expectedResult;
+ m_errorList.append( error );
+ }
+ ++m_tests;
+ }
+private:
+ QStringList m_errorList;
+ int m_tests;
+};
+
+#endif
diff --git a/libkdepim/komposer/core/tests/testfactory.h b/libkdepim/komposer/core/tests/testfactory.h
new file mode 100644
index 000000000..588941d8e
--- /dev/null
+++ b/libkdepim/komposer/core/tests/testfactory.h
@@ -0,0 +1,71 @@
+/*
+ * testfactory.h
+ *
+ * Copyright (C) 2004 Zack Rusin <zack@kde.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+#ifndef TESTFACTORY_H
+#define TESTFACTORY_H
+
+#include "managertest.h"
+
+#include <qasciidict.h>
+
+#define ADD_TEST(x) addTest( #x, new x )
+
+class TestFactory
+{
+public:
+ TestFactory()
+ {
+ ADD_TEST( ManagerTest );
+ m_tests.setAutoDelete( true );
+ }
+
+ int runTests()
+ {
+ int result = 0;
+ kdDebug()<<"Running tests..."<<endl;
+ QAsciiDictIterator<Tester> it( m_tests );
+ for( ; it.current(); ++it ) {
+ Tester* test = it.current();
+ test->allTests();
+ QStringList errorList = test->errorList();
+ if ( !errorList.empty() ) {
+ ++result;
+ kdDebug()<< it.currentKey() <<" errors:" << endl;
+ for ( QStringList::Iterator itr = errorList.begin();
+ itr != errorList.end(); ++itr ) {
+ kdDebug()<< "\t" << (*itr).latin1() <<endl;;
+ }
+ } else {
+ kdDebug()<< it.currentKey()<< " OK "<<endl;
+ }
+ }
+ kdDebug()<< "Done" <<endl;
+ return result;
+ }
+public:
+ void addTest( const char* name, Tester* test )
+ {
+ m_tests.insert( name, test );
+ }
+private:
+ QAsciiDict<Tester> m_tests;
+};
+
+#endif
diff --git a/libkdepim/komposer/core/tests/testkomposer.cpp b/libkdepim/komposer/core/tests/testkomposer.cpp
new file mode 100644
index 000000000..b7997e8c3
--- /dev/null
+++ b/libkdepim/komposer/core/tests/testkomposer.cpp
@@ -0,0 +1,18 @@
+#include "core.h"
+
+#include <kplugininfo.h>
+#include <kcmdlineargs.h>
+#include <kapplication.h>
+#include <kdebug.h>
+
+int main( int argc, char **argv )
+{
+ KCmdLineArgs::init( argc, argv, "test", "test", "test", "0.1" );
+ KApplication app;
+
+ Komposer::Core *core = new Komposer::Core();
+ app.setMainWidget( core );
+ core->show();
+
+ return app.exec();
+}
diff --git a/libkdepim/komposer/core/tests/testmanager.cpp b/libkdepim/komposer/core/tests/testmanager.cpp
new file mode 100644
index 000000000..d73fb6e8c
--- /dev/null
+++ b/libkdepim/komposer/core/tests/testmanager.cpp
@@ -0,0 +1,53 @@
+#include "testmanager.h"
+#include "testmanager.moc"
+
+#include "pluginmanager.h"
+#include "plugin.h"
+
+#include <kplugininfo.h>
+#include <kcmdlineargs.h>
+#include <kapplication.h>
+#include <kdebug.h>
+
+using namespace Komposer;
+
+TestManager::TestManager( QObject *parent )
+ : QObject( parent )
+{
+ m_manager = new PluginManager( this );
+ connect( m_manager, SIGNAL(pluginLoaded(Plugin*)),
+ SLOT(slotPluginLoaded(Plugin*)) );
+ connect( m_manager, SIGNAL(allPluginsLoaded()),
+ SLOT(slotAllPluginsLoaded()) );
+ m_manager->loadAllPlugins();
+
+ QValueList<KPluginInfo*> plugins = m_manager->availablePlugins();
+ kdDebug()<<"Number of available plugins is "<< plugins.count() <<endl;
+ for ( QValueList<KPluginInfo*>::iterator it = plugins.begin(); it != plugins.end(); ++it ) {
+ KPluginInfo *i = ( *it );
+ kdDebug()<<"\tAvailable plugin "<< i->name()
+ <<", comment = "<< i->comment() <<endl;
+ }
+}
+
+void TestManager::slotAllPluginsLoaded()
+{
+ kdDebug()<<"Done"<<endl;
+ m_manager->shutdown();
+ qApp->exit();
+}
+
+void TestManager::slotPluginLoaded( Plugin *plugin )
+{
+ kdDebug()<<"A plugin "<< m_manager->pluginName( plugin ) << " has been loaded"<<endl;
+}
+
+int main( int argc, char **argv )
+{
+ KCmdLineArgs::init( argc, argv, "test", "test", "test", "0.1" );
+ KApplication app;
+
+ TestManager manager( &app );
+
+ return app.exec();
+}
diff --git a/libkdepim/komposer/core/tests/testmanager.h b/libkdepim/komposer/core/tests/testmanager.h
new file mode 100644
index 000000000..3bb805966
--- /dev/null
+++ b/libkdepim/komposer/core/tests/testmanager.h
@@ -0,0 +1,25 @@
+#ifndef TESTMANAGER_H
+#define TESTMANAGER_H
+
+#include <qobject.h>
+
+namespace Komposer {
+ class Plugin;
+ class PluginManager;
+}
+using Komposer::Plugin;
+
+class TestManager : public QObject
+{
+ Q_OBJECT
+public:
+ TestManager( QObject *parent );
+
+public slots:
+ void slotPluginLoaded( Plugin *plugin );
+ void slotAllPluginsLoaded();
+private:
+ Komposer::PluginManager *m_manager;
+};
+
+#endif