diff options
Diffstat (limited to 'libkdepim/komposer/core')
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 <[email protected]> + * + * 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 ¶mAttr, + const QString ¶mValue, + 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 <[email protected]> + * + * 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 ¶mAttr, + const QString ¶mValue, + 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 <[email protected]> + * + * 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 ¶mAttr, + const QString ¶mValue, + 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 <[email protected]> + * + * 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 ¶mAttr, + const QString ¶mValue, + 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 <[email protected]> + * + * 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 <[email protected]> + * + * 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 <[email protected]> + * + * 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 <[email protected]> + * + * 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 <[email protected]> + * + * 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 ¶mAttr, + const QString ¶mValue, + 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>&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>&Attach</text> + <Merge/> + <Separator/> + <Action name="attach_file"/> + <Action name="remove_attachment"/> + <Action name="attachment_properties"/> + </Menu> + <Menu noMerge="1" name="Tools"> + <text>&Tools</text> + <Merge/> + <Action name="addressbook"/> + </Menu> + <Menu noMerge="1" name="settings"> + <text>&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 <[email protected]> + * + * 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 <[email protected]> + * + * 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 <[email protected]> + * + * 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 <[email protected]> + * Copyright (C) 2003 Martijn Klingens <[email protected]> + * + * 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 <[email protected]> + * + * 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, "[email protected]" );; + + 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 <[email protected]> + * + * 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 <[email protected]> + * + * 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 <[email protected]> + * + * 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 <[email protected]> + * + * 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 <[email protected]> + * + * 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 <[email protected]> + * + * 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 <[email protected]> + * + * 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 |