diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
commit | 8362bf63dea22bbf6736609b0f49c152f975eb63 (patch) | |
tree | 0eea3928e39e50fae91d4e68b21b1e6cbae25604 /kexi/plugins/macros/lib | |
download | koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.tar.gz koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.zip |
Added old abandoned KDE3 version of koffice
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kexi/plugins/macros/lib')
24 files changed, 3822 insertions, 0 deletions
diff --git a/kexi/plugins/macros/lib/Makefile.am b/kexi/plugins/macros/lib/Makefile.am new file mode 100644 index 000000000..fc7867b8f --- /dev/null +++ b/kexi/plugins/macros/lib/Makefile.am @@ -0,0 +1,23 @@ +noinst_LTLIBRARIES = libkomacro.la + +libkomacro_la_SOURCES = \ + exception.cpp \ + variable.cpp \ + metaparameter.cpp \ + metamethod.cpp \ + metaobject.cpp \ + action.cpp \ + macroitem.cpp \ + macro.cpp \ + context.cpp \ + xmlhandler.cpp \ + manager.cpp + +KDE_CXXFLAGS = $(USE_EXCEPTIONS) + +libkomacro_la_LDFLAGS = $(all_libraries) -Wnounresolved +libkomacro_la_LIBADD = $(LIB_QT) $(LIB_KDECORE) $(LIB_KDEUI) + +libkomacro_la_METASOURCES = AUTO +SUBDIRS = . +INCLUDES = $(all_includes) diff --git a/kexi/plugins/macros/lib/action.cpp b/kexi/plugins/macros/lib/action.cpp new file mode 100644 index 000000000..e2dc0b64a --- /dev/null +++ b/kexi/plugins/macros/lib/action.cpp @@ -0,0 +1,170 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2005 by Tobi Krebs (tobi.krebs@gmail.com) + * copyright (C) 2006 by Sascha Kupper (kusato@kfnv.de) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#include "action.h" + +#include <kdebug.h> + +using namespace KoMacro; + +namespace KoMacro { + + /** + * @internal d-pointer class to be more flexible on future extension of the + * functionality without to much risk to break the binary compatibility. + */ + class Action::Private + { + public: + + /** + * The name this @a Action has. + */ + QString name; + + /** + * The i18n-caption text this @a Action has. + */ + QString text; + + /** + * The comment the user is able to define for each action. + */ + QString comment; + + /** + * A map of @a Variable instances this @a Action + * provides accessible by there QString name. + */ + Variable::Map varmap; + + /** + * List of variablenames. This list provides a + * sorted order for the @a Variable instances + * defined in the map above. + */ + QStringList varnames; + + }; + +} + +Action::Action(const QString& name, const QString& text) + : QObject() + , KShared() + , d( new Private() ) // create the private d-pointer instance. +{ + kdDebug() << "Action::Action() name=" << name << endl; + d->name = name; + setText(text); + + // Publish this action. + KoMacro::Manager::self()->publishAction( KSharedPtr<Action>(this) ); +} + +Action::~Action() +{ + //kdDebug() << QString("Action::~Action() name=\"%1\"").arg(name()) << endl; + + // destroy the private d-pointer instance. + delete d; +} + +const QString Action::toString() const +{ + return QString("Action:%1").arg(name()); +} + +const QString Action::name() const +{ + return d->name; +} + +void Action::setName(const QString& name) +{ + d->name = name; +} + +const QString Action::text() const +{ + return d->text; +} + +void Action::setText(const QString& text) +{ + d->text = text; +} + +const QString Action::comment() const +{ + return d->comment; +} + +void Action::setComment(const QString& comment) +{ + d->comment = comment; +} + +bool Action::hasVariable(const QString& name) const +{ + return d->varmap.contains(name); +} + +KSharedPtr<Variable> Action::variable(const QString& name) const +{ + return d->varmap.contains(name) ? d->varmap[name] : KSharedPtr<Variable>(0); +} + +Variable::Map Action::variables() const +{ + return d->varmap; +} + +QStringList Action::variableNames() const +{ + return d->varnames; +} + +void Action::setVariable(KSharedPtr<Variable> variable) +{ + const QString name = variable->name(); + if(! d->varmap.contains(name)) { + d->varnames.append(name); + } + d->varmap.replace(name, variable); +} + +void Action::setVariable(const QString& name, const QString& text, const QVariant& variant) +{ + Variable* variable = new Variable(variant); + variable->setName(name); + variable->setText(text); + setVariable( KSharedPtr<Variable>(variable) ); +} + +void Action::removeVariable(const QString& name) +{ + if(d->varmap.contains(name)) { + d->varmap.remove(name); + d->varnames.remove(name); + } +} + +#include "action.moc" diff --git a/kexi/plugins/macros/lib/action.h b/kexi/plugins/macros/lib/action.h new file mode 100644 index 000000000..5200c1a49 --- /dev/null +++ b/kexi/plugins/macros/lib/action.h @@ -0,0 +1,187 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2005 by Tobi Krebs (tobi.krebs@gmail.com) + * copyright (C) 2006 by Sascha Kupper (kusato@kfnv.de) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#ifndef KOMACRO_ACTION_H +#define KOMACRO_ACTION_H + +#include "manager.h" +#include "context.h" +#include "variable.h" + +#include <qobject.h> +#include <ksharedptr.h> +#include <qstringlist.h> + +namespace KoMacro { + + /** + * The Action class extendes KAction to implement some additional + * functionality KAction doesn't provide. + */ + class KOMACRO_EXPORT Action + : public QObject // Qt functionality like signals and slots + , public KShared // shared reference-counting + { + Q_OBJECT + + /// Property to get/set the name. + Q_PROPERTY(QString name READ name WRITE setName) + + /// Property to get/set the text. + Q_PROPERTY(QString text READ text WRITE setText) + + /// Property to get/set the comment. + Q_PROPERTY(QString comment READ comment WRITE setComment) + + public: + + /** + * Shared pointer to implement reference-counting. + */ + typedef QMap<QString, KSharedPtr<Action> > Map; + + /** + * Constructor. + * + * @param name The unique name this @a Action has. + * @param text The i18n-caption text this @a Action has. + */ + explicit Action(const QString& name, const QString& text = QString::null); + + /** + * Destructor. + */ + virtual ~Action(); + + /** + * @return a string representation of the functionality + * this action provides. + */ + virtual const QString toString() const; + + /** + * The name this @a Action has. + */ + const QString name() const; + + /** + * Set the name of the @a Action to @p name . + */ + void setName(const QString& name); + + /** + * @return the i18n-caption text this @a Action has. + */ + const QString text() const; + + /** + * Set the i18n-caption text this @a Action has. + */ + void setText(const QString& text); + + /** + * @return the comment associated with this action. + */ + const QString comment() const; + + /** + * Set the @p comment associated with this action. + */ + void setComment(const QString& comment); + + /** + * @return true if there exists a variable with the + * name @p name else false is returned. + */ + bool hasVariable(const QString& name) const; + + /** + * @return the variable @a Variable defined for the + * name @p name . If there exists no @a Variable with + * such a name, NULL is returned. + */ + KSharedPtr<Variable> variable(const QString& name) const; + + /** + * @return the map of variables this @a Action provides. + */ + Variable::Map variables() const; + + /** + * @return a list of variablenames this @a Action provides.s + */ + QStringList variableNames() const; + + /** + * Append the @a Variable @p variable to list of variables + * this @a Action provides. + */ + void setVariable(KSharedPtr<Variable> variable); + + /** + * Set the variable. + * + * @param name The name the variable should have. + * @param text The i18n-caption used for display. + * @param variant The QVariant value. + */ + void setVariable(const QString& name, const QString& text, const QVariant& variant); + + /** + * Remove the variable defined with @p name . If there exists + * no such variable, nothing is done. + */ + void removeVariable(const QString& name); + + /** + * This function is called, when the @a KoMacro::Variable + * with name @p name used within the @a KoMacro::MacroItem + * @p macroitem got changed. + * + * @param macroitem The @a KoMacro::MacroItem instance where + * the variable defined with @p name is located in. + * @param name The name the @a KoMacro::Variable has. + * @return true if the update was successfully else false + * is returned. + */ + virtual bool notifyUpdated(const KSharedPtr<MacroItem> ¯oitem, const QString& name) { + Q_UNUSED(macroitem); + Q_UNUSED(name); + return true; // The default implementation does nothing. + } + + public slots: + + /** + * Called if the @a Action should be executed within the + * defined @p context . + */ + virtual void activate(KSharedPtr<Context> context) = 0; + + private: + /// @internal d-pointer class. + class Private; + /// @internal d-pointer instance. + Private* const d; + }; + +} + +#endif diff --git a/kexi/plugins/macros/lib/context.cpp b/kexi/plugins/macros/lib/context.cpp new file mode 100644 index 000000000..135c10c9a --- /dev/null +++ b/kexi/plugins/macros/lib/context.cpp @@ -0,0 +1,261 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2005 by Tobi Krebs (tobi.krebs@gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#include "context.h" +#include "action.h" +#include "macro.h" +#include "macroitem.h" +#include "exception.h" + +//#include <qtimer.h> +#include <kdebug.h> + +using namespace KoMacro; + +namespace KoMacro { + + /** + * @internal d-pointer class to be more flexible on future extension of the + * functionality without to much risk to break the binary compatibility. + */ + class Context::Private + { + public: + + /** + * The @a Macro instance that owns this @a Context . + */ + KSharedPtr<Macro> macro; + + /** + * List of @a Action instances that are children of the + * macro. + */ + QValueList<KSharedPtr<MacroItem > > items; + + /** + * The currently selected @a MacroItem or NULL if there + * is now @a MacroItem selected yet. + */ + KSharedPtr<MacroItem> macroitem; + + /** + * Map of all @a Variable instance that are defined within + * this context. + */ + QMap<QString, KSharedPtr<Variable > > variables; + + /** + * The @a Exception instance thrown at the last @a activate() + * call or NULL if there was no exception thrown yet. + */ + Exception* exception; + + /// Constructor. + explicit Private(KSharedPtr<Macro> m) + : macro(m) // remember the macro + , items(m->items()) // set d-pointer children to macro children + , exception(0) // no exception yet. + { + } + + /// Destructor. + ~Private() + { + delete exception; + } + }; + +} +//Constructor with initialization of our Private.object (d-pointer) +Context::Context(KSharedPtr<Macro> macro) + : QObject() + , d( new Private(macro) ) // create the private d-pointer instance. +{ +} + +//Destructor. +Context::~Context() +{ + delete d; +} + +//return if we have (d-pointer) variables +bool Context::hasVariable(const QString& name) const +{ + //Use QMap?s contains to check if a variable with name exists + return d->variables.contains(name); +} + +//return variable with name or throw an exception if none is found in variables +KSharedPtr<Variable> Context::variable(const QString& name) const +{ + //Use QMap?s contains to check if a variable with name exists in context + if (d->variables.contains(name)) { + //return it + return d->variables[name]; + } + //if there is a macroitem try to get variable from it + if(d->macroitem.data()) { + KSharedPtr<Variable> v = d->macroitem->variable(name, true); + if(v.data()) { + return v; + } + } + //none found throw exception + throw Exception(QString("Variable name='%1' does not exist.").arg(name)); +} + +//return a map of our (d-pointer) variables +Variable::Map Context::variables() const +{ + return d->variables; +} + +//set a variable +void Context::setVariable(const QString& name, KSharedPtr<Variable> variable) +{ + //debuging infos + kdDebug() << QString("KoMacro::Context::setVariable name='%1' variable='%2'").arg(name).arg(variable->toString()) << endl; + //Use QMap?s replace to set/replace the variable named name + d->variables.replace(name, variable); +} + +//return the associated Macro +KSharedPtr<Macro> Context::macro() const +{ + return d->macro; +} + +//return the currently selected MacroItem +KSharedPtr<MacroItem> Context::macroItem() const +{ + return d->macroitem; +} + +//return if this context had an exception +bool Context::hadException() const +{ + return d->exception != 0; +} + +//return the (d-pointer) exception +Exception* Context::exception() const +{ + return d->exception; +} + +//try to activate all action?s in this context +void Context::activate(QValueList<KSharedPtr<MacroItem > >::ConstIterator it) +{ + //debuging infos + kdDebug() << "Context::activate()" << endl; + //Q_ASSIGN(d->macro); + + //set end to constEnd + QValueList<KSharedPtr<MacroItem > >::ConstIterator end(d->items.constEnd()); + //loop through actions + for(;it != end; ++it) { + // fetch the MacroItem we are currently pointing to. + d->macroitem = KSharedPtr<MacroItem>(*it); + //skip empty macroitems + if(! d->macroitem.data()) { + kdDebug() << "Context::activate() Skipping empty MacroItem" << endl; + continue; + } + + // fetch the Action, the MacroItem points to. + KSharedPtr<Action> action = d->macroitem->action(); + //skip macroitems without an action + if(! action.data()) { + kdDebug() << "Context::activate() Skipping MacroItem with no action" << endl; + continue; + } + + try { + // activate the action + action->activate(this); + } + //catch exceptions + catch(Exception& e) { + //create a new exception from caugth one and set internal exception + d->exception = new Exception(e); + //add new tracemessages + //the macro name + d->exception->addTraceMessage( QString("macro=%1").arg(d->macro->name()) ); + //the action name + d->exception->addTraceMessage( QString("action=%1").arg(action->name()) ); + //and all variables wich belong to the action/macro + QStringList variables = action->variableNames(); + for(QStringList::Iterator vit = variables.begin(); vit != variables.end(); ++vit) { + KSharedPtr<Variable> v = d->macroitem->variable(*vit, true); + d->exception->addTraceMessage( QString("%1=%2").arg(*vit).arg(v->toString()) ); + } + return; // abort execution + } + } + + // The run is done. So, let's remove the currently selected item to + // outline, that we did the job and there stays no dangling item. + d->macroitem = KSharedPtr<MacroItem>(0); +} + +//try to activated an context +void Context::activate(KSharedPtr<Context> context) +{ + //setup context + delete d->exception; d->exception = 0; + + if(context->hadException()) { + // if the context in which this context should run in already had an exception, + // we adopt this exception and abort the execution. + d->exception = new Exception( *context->exception() ); + return; + } + + // Merge the passed context into this context + Variable::Map variables = context->variables(); + //copy variables + Variable::Map::ConstIterator it, end( variables.constEnd() ); + for( it = variables.constBegin(); it != end; ++it) + setVariable(it.key(), it.data()); + + //activate copied context. + activate(d->items.constBegin()); +} + +//try to continue activation of a context +void Context::activateNext() +{ + //setup/clear context, + //allows us to continue activation even when an exception happend before + delete d->exception; d->exception = 0; + + if(! d->macroitem) { // if no MacroItem is defined, we don't need to try to continue execution + return; + } + + //find the macroitem from which to continue + QValueList<KSharedPtr<MacroItem > >::ConstIterator it = d->items.find(d->macroitem); + if (it != d->items.constEnd()) { + activate(++it); // try to continue the execution. + } +} + +#include "context.moc" diff --git a/kexi/plugins/macros/lib/context.h b/kexi/plugins/macros/lib/context.h new file mode 100644 index 000000000..dd467dad4 --- /dev/null +++ b/kexi/plugins/macros/lib/context.h @@ -0,0 +1,141 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2005 by Tobi Krebs (tobi.krebs@gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#ifndef KOMACRO_CONTEXT_H +#define KOMACRO_CONTEXT_H + +#include <qobject.h> +#include <ksharedptr.h> + +#include "variable.h" + +namespace KoMacro { + + // Forward declaration. + class Macro; + class MacroItem; + class Action; + class Exception; + + /** + * The context of an execution. If a @a Macro got executed it creates + * an instance of this class and passes it around all it's children + * as local execution context. + */ + class KOMACRO_EXPORT Context + : public QObject + , public KShared + { + Q_OBJECT + public: + + /** + * Constructor. + * + * @param macro The @a Macro this @a Context belongs to. + */ + explicit Context(KSharedPtr<Macro> macro); + + /** + * Destructor. + */ + ~Context(); + + /** + * @return true if there exists a variable with name @p name + * else false got returned. + */ + bool hasVariable(const QString& name) const; + + /** + * @return the @a Variable defined with name @p name or + * NULL if there exists no such variable. + */ + KSharedPtr<Variable> variable(const QString& name) const; + + /** + * @return a map of all @a Variable instance that are defined + * within this context. + */ + Variable::Map variables() const; + + /** + * Set the variable @p variable defined with name @p name . If + * there exists already a variable with that name replace it. + */ + void setVariable(const QString& name, KSharedPtr<Variable> variable); + + /** + * @return the associated macro + */ + KSharedPtr<Macro> macro() const; + + /** + * @return the currently selected @a MacroItem instance + * or NULL if there is no @a MacroItem selected yet. + */ + KSharedPtr<MacroItem> macroItem() const; + + /** + * @return true if the last @a activate() stopped with an + * exception else false is returned. + */ + bool hadException() const; + + /** + * @return the @a Exception instance that was thrown on + * the last call of @a activate() . If there was no + * exception NULL is returned. + */ + Exception* exception() const; + + private slots: + + /** + * A @a Context does take care of an execution-chain which + * should be activated one after another. The @a Context + * remembers what @a Action should be executed next and + * calling this slot just activates those @a Action . + */ + virtual void activate(QValueList<KSharedPtr <MacroItem> >::ConstIterator it); + + public slots: + + /** + * This slot extends the slot above with the passed + * @a Context @p context which will be used as + * parent context for this context. + */ + virtual void activate(KSharedPtr<Context> context); + + /** + * This slot continues execution. + */ + virtual void activateNext(); + + private: + /// @internal d-pointer class. + class Private; + /// @internal d-pointer instance. + Private* const d; + }; + +} + +#endif diff --git a/kexi/plugins/macros/lib/exception.cpp b/kexi/plugins/macros/lib/exception.cpp new file mode 100644 index 000000000..7cfc7d717 --- /dev/null +++ b/kexi/plugins/macros/lib/exception.cpp @@ -0,0 +1,97 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2005 by Tobi Krebs (tobi.krebs@gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#include "exception.h" + +#include <kdebug.h> + +using namespace KoMacro; + +namespace KoMacro { + + /** + * @internal d-pointer class to be more flexible on future extension of the + * functionality without to much risk to break the binary compatibility. + */ + class Exception::Private + { + public: + + /// A describing errormessage. + const QString errormessage; + + /// A more detailed list of tracemessages. + QString tracemessages; + + /** + * Constructor. + */ + Private(const QString& errormessage) + : errormessage(errormessage) + { + } + + }; + +} + +//constructor +Exception::Exception(const QString& errormessage) + : d( new Private(errormessage) ) // create the private d-pointer instance. +{ + //debuging infos + kdDebug() << QString("Exception errormessage=\"%1\"").arg(errormessage) << endl; +} + +//copy constructor +Exception::Exception (const Exception& e) + : d( new Private( e.errorMessage() ) ) +{ + d->tracemessages = e.traceMessages(); +} + +//deconstructor +Exception::~Exception() +{ + delete d; +} + +//get d-pointer errormessage +const QString Exception::errorMessage() const +{ + return d->errormessage; +} + +//get d-pointer tracemessages +const QString Exception::traceMessages() const +{ + return d->tracemessages; +} + +//add a Qstring to d-pointer tracemessages +void Exception::addTraceMessage(const QString& tracemessage) +{ + //no tracemessages till now + if(d->tracemessages.isEmpty()) + d->tracemessages = tracemessage; + //append to existing ones + else + d->tracemessages += "\n" + tracemessage; +} + diff --git a/kexi/plugins/macros/lib/exception.h b/kexi/plugins/macros/lib/exception.h new file mode 100644 index 000000000..73504de04 --- /dev/null +++ b/kexi/plugins/macros/lib/exception.h @@ -0,0 +1,84 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2005 by Tobi Krebs (tobi.krebs@gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#ifndef KOMACRO_EXCEPTION_H +#define KOMACRO_EXCEPTION_H + +#include <qstring.h> +#include <qstringlist.h> + +#include "komacro_export.h" + +namespace KoMacro { + + /** + * Base Exception class. All exceptions we like to use within KoMacro + * need to inheritate from this exception. + */ + class KOMACRO_EXPORT Exception + { + public: + + /** + * Constructor. + * + * @param errormessage A describing errormessage why the + * exception got thrown. + */ + explicit Exception(const QString& errormessage); + + /** + * Copy-constructor. + */ + Exception(const Exception&); + + /** + * Destructor. + */ + virtual ~Exception(); + + /** + * @return a describing errormessage. + */ + const QString errorMessage() const; + + /** + * @return a stringlist of traces. This are normaly just + * simple strings to show the way the exception was gone + * from bottom-up where the error was thrown till where + * we finally catched the error to display it to the + * user. + */ + const QString traceMessages() const; + + /** + * Add the message @p tracemessage to the list of traces. + */ + void addTraceMessage(const QString& tracemessage); + + private: + /// @internal d-pointer class. + class Private; + /// @internal d-pointer instance. + Private* const d; + }; + +} + +#endif diff --git a/kexi/plugins/macros/lib/komacro_export.h b/kexi/plugins/macros/lib/komacro_export.h new file mode 100644 index 000000000..cc4b41a80 --- /dev/null +++ b/kexi/plugins/macros/lib/komacro_export.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2006 by Tobi Krebs (tobi.krebs@gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#ifndef KOMACRO_EXPORT_H_ +#define KOMACRO_EXPORT_H_ + +#ifdef __cplusplus +# include <kdeversion.h> /* this will also include <kdelibs_export.h>, if available */ +#endif + +/* KDE_EXPORT will be defined multiple times without this on kdelibs 3.3 (tested on 3.3.1) */ +#include <kdemacros.h> + +/* workaround for KDElibs < 3.2 on !win32 */ +#ifndef KDE_EXPORT +# define KDE_EXPORT +#endif + +#ifndef KOMACRO_EXPORT +# define KOMACRO_EXPORT KDE_EXPORT +#endif + +#endif diff --git a/kexi/plugins/macros/lib/macro.cpp b/kexi/plugins/macros/lib/macro.cpp new file mode 100644 index 000000000..688cc7b07 --- /dev/null +++ b/kexi/plugins/macros/lib/macro.cpp @@ -0,0 +1,126 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2005 by Tobi Krebs (tobi.krebs@gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#include "macro.h" +#include "macroitem.h" +#include "manager.h" +#include "context.h" +#include "variable.h" + +#include <qdom.h> +#include <kdebug.h> + +using namespace KoMacro; + +namespace KoMacro { + + /** + * @internal d-pointer class to be more flexible on future extension of the + * functionality without to much risk to break the binary compatibility. + */ + class Macro::Private + { + public: + + /** + * A list of @a MacroItem instances. + */ + QValueList<KSharedPtr<MacroItem > > itemlist; + + /** + * The name the @a Macro has. + */ + QString name; + + }; + +} + +//constructor, initalize internal (d-pointer) name +Macro::Macro(const QString& name) + : QObject() + , KShared() + , XMLHandler(this) + , d( new Private() ) // create the private d-pointer instance. +{ + d->name = name; +} + +//destructor +Macro::~Macro() +{ + // destroy the private d-pointer instance. + delete d; +} + +//get internal (d-pointer) name +const QString Macro::name() const +{ + return d->name; +} + +//set internal (d-pointer) name +void Macro::setName(const QString& name) +{ + d->name = name; +} + +//get an "extended" name +const QString Macro::toString() const +{ + return QString("Macro:%1").arg(name()); +} + +//get (d-pointer) itemlist +QValueList<KSharedPtr<MacroItem > >& Macro::items() const +{ + return d->itemlist; +} + +//add a macroitem to internal (d-pointer) itemlist +void Macro::addItem(KSharedPtr<MacroItem> item) +{ + d->itemlist.append(item); +} +//clear internal (d-pointer) itemlist +void Macro::clearItems() +{ + d->itemlist.clear(); +} + +//run our macro +KSharedPtr<Context> Macro::execute(QObject* sender) +{ + kdDebug() << "Macro::execute(KSharedPtr<Context>)" << endl; + + //create context in which macro can/should run + KSharedPtr<Context> c = KSharedPtr<Context>( new Context(this) ); + if(sender) { + // set the sender-variable if we got a sender QObject. + c->setVariable("[sender]", KSharedPtr<Variable>( new Variable(sender) )); + } + //connect(context, SIGNAL(activated()), this, SIGNAL(activated())); + + //call activate in the context of the macro + c->activate( c ); + + return c; +} + +#include "macro.moc" diff --git a/kexi/plugins/macros/lib/macro.h b/kexi/plugins/macros/lib/macro.h new file mode 100644 index 000000000..da38e05bc --- /dev/null +++ b/kexi/plugins/macros/lib/macro.h @@ -0,0 +1,130 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2005 by Tobi Krebs (tobi.krebs@gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#ifndef KOMACRO_MACRO_H +#define KOMACRO_MACRO_H + +#include <qobject.h> +#include <ksharedptr.h> + +#include "action.h" +#include "xmlhandler.h" + +namespace KoMacro { + + // Forward declarations. + class Manager; + class MacroItem; + class Context; + + /** + * The Macro class implements all the action-handling. Internaly the + * Macro provides a collection of @a MacroItem instances which each + * of them points to an @a Action instance. + */ + class KOMACRO_EXPORT Macro + : public QObject // Qt functionality like signals and slots + , public KShared // shared reference-counting + , public XMLHandler // to (un-)serialize from/to XML + { + Q_OBJECT + + public: + + /** + * A QMap of @a Macro instances accessible by there unique name. Each + * class should use this typemap rather then the QMap direct. That + * way we are more flexible on future changes. + */ + typedef QMap<QString, KSharedPtr<Macro > > Map; + + /** + * Constructor. + * + * @param name The internal name this @a Macro has. This + * name will be used as unique identifier. + */ + explicit Macro(const QString& name); + + /** + * Destructor. + */ + virtual ~Macro(); + + /** + * @return the name this @a Macro instance has. + */ + const QString name() const; + + /** + * Set the @p name this @a Macro instance has. + */ + void setName(const QString& name); + + /** + * @return a string-representation of the macro. + */ + virtual const QString toString() const; + + /** + * @return a list of @a MacroItem instances which + * are children of this @a Macro . + */ + QValueList< KSharedPtr<MacroItem> >& items() const; + + /** + * Add the @a MacroItem @p item to the list of items + * this @a Macro has. + */ + void addItem(KSharedPtr<MacroItem> item); + + /** + * Removes all @a MacroItem instances this @a Macro has. + */ + void clearItems(); + + /** + * Connect the Qt signal @p signal of the QObject @p sender + * with this @a Macro . If the signal got emitted this + * @a Macro instance will be activated and the in the + * signal passed arguments are transfered into the + * activation @a Context . + */ + //void connectSignal(const QObject* sender, const char* signal); + + public slots: + + /** + * Called if the @a Macro should be executed. + * + * @param context The @a Context this @a Macro should + * be executed in. + */ + virtual KSharedPtr<Context> execute(QObject* sender); + + private: + /// @internal d-pointer class. + class Private; + /// @internal d-pointer instance. + Private* const d; + }; + +} + +#endif diff --git a/kexi/plugins/macros/lib/macroitem.cpp b/kexi/plugins/macros/lib/macroitem.cpp new file mode 100644 index 000000000..4027f2ccc --- /dev/null +++ b/kexi/plugins/macros/lib/macroitem.cpp @@ -0,0 +1,217 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2006 by Sascha Kupper (kusato@kfnv.de) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#include "macroitem.h" + +#include <kdebug.h> + +using namespace KoMacro; + +namespace KoMacro { + + /** + * @internal d-pointer class to be more flexible on future extension of the + * functionality without to much risk to break the binary compatibility. + */ + class MacroItem::Private + { + public: + /** + * The @a Action this @a MacroItem has. + */ + KSharedPtr<Action> action; + + /** + * The comment this @a MacroItem has. + */ + QString comment; + + /** + * The @a QMap of @a Variable this @a MacroItem has. + */ + Variable::Map variables; + + /** + * define a @a QVariant -cast as inline for better performance + * @return the casted @a QVariant by passing a @param variant and its + * expected QVariant::Type @param type. + */ + inline const QVariant cast(const QVariant& variant, QVariant::Type type) const + { + // If ok is true the QVariant v holds our new and to the correct type + // casted variant value. If ok is false the as argument passed variant + // QVariant contains the (maybe uncasted string to prevent data-loosing + // what would happen if we e.g. would expect an integer and cast it to + // an incompatible non-int string) value. + bool ok = false; + QVariant v; + + // Try to cast the passed variant to the expected variant-type. + switch(type) { + case QVariant::Bool: { + const QString s = variant.toString(); + ok = (s == "true" || s == "false" || s == "0" || s == "1" || s == "-1"); + v = QVariant( variant.toBool(), 0 ); + } break; + case QVariant::Int: { + v = variant.toInt(&ok); + // Check if the cast is correct. + Q_ASSERT(!ok || v.toString() == variant.toString()); + } break; + case QVariant::UInt: { + v = variant.toUInt(&ok); + Q_ASSERT(!ok || v.toString() == variant.toString()); + } break; + case QVariant::LongLong: { + v = variant.toLongLong(&ok); + Q_ASSERT(!ok || v.toString() == variant.toString()); + } break; + case QVariant::ULongLong: { + v = variant.toULongLong(&ok); + Q_ASSERT(!ok || v.toString() == variant.toString()); + } break; + case QVariant::Double: { + v = variant.toDouble(&ok); + Q_ASSERT(!ok || v.toString() == variant.toString()); + } break; + case QVariant::String: { + ok = true; // cast will always be successfully + v = variant.toString(); + } break; + default: { + // If we got another type we try to let Qt handle it... + ok = v.cast(type); + kdWarning()<<"MacroItem::Private::cast() Unhandled ok="<<ok<<" type="<<type<<" value="<<v<<endl; + } break; + } + + return ok ? v : variant; + } + + }; + +} + +MacroItem::MacroItem() + : KShared() + , d( new Private() ) +{ +} + +MacroItem::~MacroItem() +{ + delete d; +} + +QString MacroItem::comment() const +{ + return d->comment; +} + +void MacroItem::setComment(const QString& comment) +{ + d->comment = comment; +} + +KSharedPtr<Action> MacroItem::action() const +{ + return d->action; +} + +void MacroItem::setAction(KSharedPtr<Action> action) +{ + d->action = action; +} + +QVariant MacroItem::variant(const QString& name, bool checkaction) const +{ + KSharedPtr<Variable> v = variable(name, checkaction); + return v.data() ? v->variant() : QVariant(); +} + +KSharedPtr<Variable> MacroItem::variable(const QString& name, bool checkaction) const +{ + if(d->variables.contains(name)) + return d->variables[name]; + if(checkaction && d->action.data()) + return d->action->variable(name); + return KSharedPtr<Variable>(0); +} + +Variable::Map MacroItem::variables() const +{ + return d->variables; +} + +bool MacroItem::setVariant(const QString& name, const QVariant& variant) +{ + // Let's look if there is an action defined for the variable. If that's + // the case, we try to use that action to preserve the type of the variant. + KSharedPtr<Variable> actionvariable = d->action ? d->action->variable(name) : KSharedPtr<Variable>(0); + + // If we know the expected type, we try to cast the variant to the expected + // type else the variant stays untouched (so, it will stay a string). + const QVariant v = actionvariable.data() + ? d->cast(variant, actionvariable->variant().type()) // try to cast the variant + : variant; // don't cast anything, just leave the string-type... + + // Now let's try to determinate the variable which should be changed. + KSharedPtr<Variable> variable = d->variables[name]; + if(! variable.data()) { + // if there exists no such variable yet, create one. + kdDebug() << "MacroItem::setVariable() Creating new variable name=" << name << endl; + + variable = KSharedPtr<Variable>( new Variable() ); + variable->setName(name); + d->variables.replace(name, variable); + } + + // Remember the previous value for the case we like to restore it. + const QVariant oldvar = variable->variant(); + + // Set the variable. + variable->setVariant(v); + + // Now we inform the referenced action that a variable changed. If + // notifyUpdated() returns false, the action rejects the new variable + // and we need to restore the previous value. + if(d->action && ! d->action->notifyUpdated(this, name)) { + kdWarning() << "MacroItem::setVariable() Notify failed for variable name=" << name << endl; + variable->setVariant(oldvar); + return false; // the action rejected the changed variable whyever... + } + + // Job done successfully. The variable is changed to the new value. + return true; +} + +KSharedPtr<Variable> MacroItem::addVariable(const QString& name, const QVariant& variant) +{ + Q_ASSERT(! d->variables.contains(name) ); + // Create a new Variable. + KSharedPtr<Variable> variable = KSharedPtr<Variable>( new Variable() ); + variable->setName(name); + + // Put it into the Variable-map. + d->variables.replace(name, variable); + + // Set the variant of the Variable. + this->setVariant(name, variant); + return variable; +} diff --git a/kexi/plugins/macros/lib/macroitem.h b/kexi/plugins/macros/lib/macroitem.h new file mode 100644 index 000000000..8f3e15022 --- /dev/null +++ b/kexi/plugins/macros/lib/macroitem.h @@ -0,0 +1,142 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2006 by Sascha Kupper (kusato@kfnv.de) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#ifndef KOMACRO_MACROITEM_H +#define KOMACRO_MACROITEM_H + +#include <qobject.h> + +#include <ksharedptr.h> + +// Forward declarations. +class QDomElement; + +#include "action.h" +#include "context.h" + +namespace KoMacro { + + // Forward-declarations. + //class Action; + + /** + * The MacroItem class is an item in a @a Macro and represents one + * single execution step. Each MacroItem points to 0..1 @a Action + * instances which implement the execution. So, the MacroItem provides + * a simple state-pattern on the one hand (depending on the for this + * MacroItem choosen @a Action implementation) and holds the by the + * user defined modifications like e.g. the comment on the other hand. + */ + class KOMACRO_EXPORT MacroItem : public KShared + { + + public: + + /** + * A list of \a MacroItem instances. + */ + typedef QValueList<KSharedPtr<MacroItem > > List; + + /** + * Constructor. + */ + explicit MacroItem(); + + /** + * Destructor. + */ + ~MacroItem(); + + /** + * @return the comment defined by the user for + * this @a MacroItem . + */ + QString comment() const; + + /** + * Set the comment @param comment defined by the user for this + * @a MacroItem . + */ + void setComment(const QString& comment); + + /** + * @return the @a Action this @a MacroItem points + * to. This method will return NULL if there is + * no @a Action defined yet else the returned + * @a Action will be used to implement the execution. + */ + KSharedPtr<Action> action() const; + + /** + * Set the @a Action @param action this @a MacroItem points to. + */ + void setAction(KSharedPtr<Action> action); + + /** + * @return @a Variant from the @a Variable identified with + * the name @param name . If this @a MacroItem doesn't + * have a @a Variable with that name NULL is + * returned. + * If the boolean value @param checkaction is true, we + * also look if our @a Action may know about + * such a @param name in the case this @a MacroItem + * doesn't have such a name. + */ + QVariant variant(const QString& name, bool checkaction = false) const; + + /** + * @return the @a Variable instance identified with + * the name @param name . If this @a MacroItem doesn't + * have a @a Variable with that name NULL is + * returned. + * If the boolean value @param checkaction is true, we + * also look if our @a Action may know about + * such a @param name in the case this @a MacroItem + * doesn't have such a name. + */ + KSharedPtr<Variable> variable(const QString& name, bool checkaction = false) const; + + /** + * @return a map of @a Variable instances. + */ + QMap<QString, KSharedPtr<Variable> > variables() const; + + /** + * Set the @a QVariant @param variant as variable with the variablename + * @param name . + * @return a bool for successfull setting. + */ + bool setVariant(const QString& name, const QVariant& variant); + + /** + * Add a new variable with the vaiablename @param name and the given + * @a QVariant @param variant to our @a MacroItem instance. + */ + KSharedPtr<Variable> addVariable(const QString& name, const QVariant& variant); + + private: + /// @internal d-pointer class. + class Private; + /// @internal d-pointer instance. + Private* const d; + }; + +} + +#endif diff --git a/kexi/plugins/macros/lib/manager.cpp b/kexi/plugins/macros/lib/manager.cpp new file mode 100644 index 000000000..77ad98b16 --- /dev/null +++ b/kexi/plugins/macros/lib/manager.cpp @@ -0,0 +1,170 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2005 by Tobi Krebs (tobi.krebs@gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#include "manager.h" +#include "action.h" +#include "function.h" +#include "macro.h" +#include "exception.h" + +#include <qobject.h> +#include <qwidget.h> +#include <qdom.h> +#include <kxmlguibuilder.h> +#include <kdebug.h> + +using namespace KoMacro; + +namespace KoMacro { + + /** + * @internal d-pointer class to be more flexible on future extension of the + * functionality without to much risk to break the binary compatibility. + */ + class Manager::Private + { + public: + KXMLGUIClient* const xmlguiclient; + QMap<QString, KSharedPtr<Macro > > macros; + + QStringList actionnames; + QMap<QString, KSharedPtr<Action> > actions; + + QMap<QString, QGuardedPtr<QObject> > objects; + + Private(KXMLGUIClient* const xmlguiclient) + : xmlguiclient(xmlguiclient) + { + } + }; + + /// Pointer to our static singleton. + static ::KoMacro::Manager* _self = 0; + + /// Automatically deletes our singleton on termination. + static KStaticDeleter< ::KoMacro::Manager > _manager; + +} + +void Manager::init(KXMLGUIClient* xmlguiclient) +{ + if(! _self) { + ::KoMacro::Manager* manager = new ::KoMacro::Manager(xmlguiclient); + _manager.setObject(_self, manager); + } + else { + throw Exception("Already initialized."); + } +} + +Manager* Manager::self() +{ + //Q_ASSERT(_self); + return _self; +} + +Manager::Manager(KXMLGUIClient* const xmlguiclient) + : d( new Private(xmlguiclient) ) // create the private d-pointer instance. +{ + kdDebug() << "Manager::Manager() Ctor" << endl; + QObject* obj = dynamic_cast<QObject*>(xmlguiclient); + if(obj) { + d->objects.replace(obj->name(), obj); + } + + //TESTCASE + d->objects.replace("TestCase", new QWidget()); +} + +Manager::~Manager() +{ + // destroy the private d-pointer instance. + delete d; +} + +KXMLGUIClient* Manager::guiClient() const +{ + return d->xmlguiclient; +} + +bool Manager::hasMacro(const QString& macroname) +{ + return d->macros.contains(macroname); +} + +KSharedPtr<Macro> Manager::getMacro(const QString& macroname) +{ + return d->macros[macroname]; +} + +void Manager::addMacro(const QString& macroname, KSharedPtr<Macro> macro) +{ + d->macros.replace(macroname, macro); +} + +void Manager::removeMacro(const QString& macroname) +{ + d->macros.remove(macroname); +} + +KSharedPtr<Macro> Manager::createMacro(const QString& macroname) +{ + KSharedPtr<Macro> macro = KSharedPtr<Macro>( new Macro(macroname) ); + return macro; +} + +KSharedPtr<Action> Manager::action(const QString& name) const +{ + return d->actions[name]; +} + +Action::Map Manager::actions() const +{ + return d->actions; +} + +QStringList Manager::actionNames() const +{ + return d->actionnames; +} + +void Manager::publishAction(KSharedPtr<Action> action) +{ + const QString name = action->name(); + if(! d->actions.contains(name)) { + d->actionnames.append(name); + } + d->actions.replace(name, action); +} + +void Manager::publishObject(const QString& name, QObject* object) +{ + Q_ASSERT(! d->objects.contains(name)); + d->objects.replace(name, object); +} + +QGuardedPtr<QObject> Manager::object(const QString& name) const +{ + return d->objects[name]; +} + +QMap<QString, QGuardedPtr<QObject> > Manager::objects() const +{ + return d->objects; +} diff --git a/kexi/plugins/macros/lib/manager.h b/kexi/plugins/macros/lib/manager.h new file mode 100644 index 000000000..964f9d7c9 --- /dev/null +++ b/kexi/plugins/macros/lib/manager.h @@ -0,0 +1,219 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2005 by Tobi Krebs (tobi.krebs@gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#ifndef KOMACRO_MANAGER_H +#define KOMACRO_MANAGER_H + +#include <qmap.h> +#include <qguardedptr.h> +#include <ksharedptr.h> +#include <kxmlguiclient.h> +#include <kstaticdeleter.h> + +#include "komacro_export.h" + +class QObject; +class QDomElement; + +namespace KoMacro { + + // Forward declarations. + class Action; + class Macro; + + /** + * The Manager class acts as window-wide manager for macros. + * + * Example how KoMacro could be used. + * @code + * // We have a class that inheritates from QObject and + * // implements some public signals and slots that will + * // be accessible by Macros once a class-instance + * // got published. + * class PublishedObject : public QObject {}; + * + * // Somewhere we have our KMainWindow. + * KMainWindow* mainwindow = new KMainWindow(); + * + * // Create a new KoMacro::Manager instance to access the + * // Macro-framework. + * KoMacro::Manager* manager = new KoMacro::Manager( mainwindow ); + * + * // Now we like to publish a QObject + * PublishedObject* publishedobject = new PublishedObject(); + * manager->publishObject(publishedobject); + * + * // ... here we are able to use manager->createAction() to + * // create Action instances on the fly and work with them. + * + * // Finally free the publishedobject instance we created. We + * // need to free it manualy cause PublishedObject doesn't + * // got a QObject parent as argument. + * delete publishedobject; + * + * // Finally free the manager-instance. It's always needed + * // to free the instance by yourself! + * delete manager; + * @endcode + */ + class KOMACRO_EXPORT Manager + { + friend class KStaticDeleter< ::KoMacro::Manager >; + private: + + /** + * Constructor. + * + * @param xmlguiclient The KXMLGUIClient instance this + * @a Manager is associated with. + */ + explicit Manager(KXMLGUIClient* const xmlguiclient); + + /** + * Destructor. + */ + virtual ~Manager(); + + public: + + /** + * Initialize this \a Manager singleton. This function + * needs to be called exactly once to initialize the + * \a Manager singleton before \a self() got used. + */ + static void init(KXMLGUIClient* xmlguiclient); + + /** + * @return a pointer to a Manager singleton-instance. The + * static method \a init() needs to be called exactly once + * before calling this method else we may return NULL . + */ + static Manager* self(); + + /** + * @return the KXMLGUIClient instance this @a Manager is + * associated with. + */ + KXMLGUIClient* guiClient() const; + + /** + * \return true if we carry a \a Macro with the + * defined \p macroname . + */ + bool hasMacro(const QString& macroname); + + /** + * \return the \a Macro defined with \p macroname + * or NULL if we don't have such a \a Macro. + */ + KSharedPtr<Macro> getMacro(const QString& macroname); + + /** + * Add a new \a Macro to the list of known macros. If + * there exists already a \a Macro instance with the + * defined \p macroname then the already existing one + * will be replace. + * + * \param macroname The name the \a Macro will be + * accessible as. + * \param macro The \a Macro instance. + */ + void addMacro(const QString& macroname, KSharedPtr<Macro> macro); + + /** + * Remove the \a Macro defined with \p macroname . If + * we don't know about a \a Macro with that \p macroname + * nothing happens. + */ + void removeMacro(const QString& macroname); + + /** + * Factory function to create a new \a Macro instances. + * The returned new \a Macro instance will not be added + * to the list of known macros. Use \a addMacro if you + * like to attach the returned new \a Macro to this + * \a Manager instance. + */ + KSharedPtr<Macro> createMacro(const QString& macroname); + +#if 0 + /** + * Factory method to create @a Action instances from the + * defined @p element . + * + * @param element The serialized QDomElement that should + * be used to create the @a Action instance. + * @return A new @a Action instance or NULL if the + * defined @p element is not valid. + * + * @deprecated Moved to common XMLReader/XMLWriter classes. Use Macro::xmlHandler() ! + */ + KSharedPtr<Action> createAction(const QDomElement& element); +#endif + + /** + * @return the @a Action which was published under the + * name @p name or returns an empty @a KSharedPtr<Action> object + * if there was no such @a Action published. + */ + KSharedPtr<Action> action(const QString& name) const; + + /** + * @return a map of all published actions. + */ + QMap<QString, KSharedPtr<Action> > actions() const; + + /** + * @return a list of all published actions. + */ + QStringList actionNames() const; + + /** + * Publish the @a Action @p action . The published @a Action + * will be accessible via it's unique name. + */ + void publishAction(KSharedPtr<Action> action); + + /** + * Publish the passed QObject @p object. Those object will + * provide it's slots as callable functions. + */ + void publishObject(const QString& name, QObject* object); + + /** + * @return the publish QObject defined with name @p name + * or NULL if there exists no such object. + */ + QGuardedPtr<QObject> object(const QString& name) const; + + /** + * @return a map of the published QObject instances. + */ + QMap<QString, QGuardedPtr<QObject> > objects() const; + + private: + /// @internal d-pointer class. + class Private; + /// @internal d-pointer instance. + Private* const d; + }; + +} + +#endif diff --git a/kexi/plugins/macros/lib/metamethod.cpp b/kexi/plugins/macros/lib/metamethod.cpp new file mode 100644 index 000000000..8aa4dc54c --- /dev/null +++ b/kexi/plugins/macros/lib/metamethod.cpp @@ -0,0 +1,344 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2005 by Tobi Krebs (tobi.krebs@gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#include "metamethod.h" +#include "metaobject.h" +#include "metaparameter.h" +#include "variable.h" +#include "exception.h" + +#include <qobject.h> +#include <qmetaobject.h> + +// to access the Qt3 QUObject API. +#include <private/qucom_p.h> +#include <private/qucomextra_p.h> + +#include <kdebug.h> + +using namespace KoMacro; + +namespace KoMacro { + + /** + * @internal d-pointer class to be more flexible on future extension of the + * functionality without to much risk to break the binary compatibility. + */ + class MetaMethod::Private + { + public: + + /** + * The signature this @a MetaMethod has. + */ + QString signature; + + /** + * The signature tagname this @a MetaMethod has. + */ + QString signaturetag; + + /** + * The signature arguments this @a MetaMethod has. + */ + QString signaturearguments; + + /** + * Cached signature arguments parsed into a list + * of @a MetaParameter instances. + */ + MetaParameter::List arguments; + + /** + * The @a MetaObject this @a MetaMethod belongs to or is NULL + * if this @a MetaMethod doesn't belong to any @a MetaObject + * yet. + */ + KSharedPtr<MetaObject> object; + + /** + * The @a MetaMethod::Type this method provides access + * to. + */ + MetaMethod::Type type; + }; + +} + +MetaMethod::MetaMethod(const QString& signature, Type type, KSharedPtr<MetaObject> object) + : KShared() + , d( new Private() ) // create the private d-pointer instance. +{ + d->signature = signature; + d->object = object; + d->type = type; + + int startpos = d->signature.find("("); + int endpos = d->signature.findRev(")"); + if(startpos < 0 || startpos > endpos) { + throw Exception(QString("Invalid signature \"%1\"").arg(d->signature)); + } + + d->signaturetag = d->signature.left(startpos).stripWhiteSpace(); + if(d->signaturetag.isEmpty()) { + throw Exception(QString("Invalid tagname in signature \"%1\"").arg(d->signature)); + } + + d->signaturearguments = d->signature.mid(startpos + 1, endpos - startpos - 1).stripWhiteSpace(); + + do { + int commapos = d->signaturearguments.find(","); + int starttemplatepos = d->signaturearguments.find("<"); + if(starttemplatepos >= 0 && (commapos < 0 || starttemplatepos < commapos)) { + int endtemplatepos = d->signaturearguments.find(">", starttemplatepos); + if(endtemplatepos <= 0) { + throw Exception(QString("No closing template-definiton in signature \"%1\"").arg(d->signature)); + } + commapos = d->signaturearguments.find(",", endtemplatepos); + } + + if(commapos > 0) { + QString s = d->signaturearguments.left(commapos).stripWhiteSpace(); + if(! s.isEmpty()) { + d->arguments.append( new MetaParameter(s) ); + } + d->signaturearguments = d->signaturearguments.right(d->signaturearguments.length() - commapos - 1); + } + else { + QString s = d->signaturearguments.stripWhiteSpace(); + if(! s.isEmpty()) { + d->arguments.append( new MetaParameter(s) ); + } + break; + } + } while(true); +} + +MetaMethod::~MetaMethod() +{ + delete d; +} + +KSharedPtr<MetaObject> const MetaMethod::object() const +{ + return d->object; +} + +const QString MetaMethod::signature() const +{ + return d->signature; +} + +const QString MetaMethod::signatureTag() const +{ + return d->signaturetag; +} + +const QString MetaMethod::signatureArguments() const +{ + return d->signaturearguments; +} + +MetaMethod::Type MetaMethod::type() const +{ + return d->type; +} + +MetaParameter::List MetaMethod::arguments() const +{ + return d->arguments; +} + +QUObject* MetaMethod::toQUObject(Variable::List arguments) +{ + uint argsize = d->arguments.size(); + + if(arguments.size() <= argsize) { + throw Exception(QString("To less arguments for slot with siganture \"%1\"").arg(d->signature)); + } + + // The first item in the QUObject-array is for the returnvalue + // while everything >=1 are the passed parameters. + QUObject* uo = new QUObject[ argsize + 1 ]; + + uo[0] = QUObject(); // empty placeholder for the returnvalue. + + for(uint i = 0; i < argsize; i++) { + KSharedPtr<MetaParameter> metaargument = d->arguments[i]; + KSharedPtr<Variable> variable = arguments[i + 1]; + + if ( !variable ) { + throw Exception(QString("Variable is undefined !")); + } + + if(metaargument->type() != variable->type()) { + throw Exception(QString("Wrong variable type in method \"%1\". Expected \"%2\" but got \"%3\"").arg(d->signature).arg(metaargument->type()).arg(variable->type())); + } + + switch(metaargument->type()) { + + case Variable::TypeNone: { + kdDebug() << "Variable::TypeNone" << endl; + uo[i + 1] = QUObject(); + } break; + + case Variable::TypeVariant: { + kdDebug() << "Variable::TypeVariant" << endl; + + const QVariant variant = variable->variant(); + switch(metaargument->variantType()) { + case QVariant::String: { + const QString s = variant.toString(); + static_QUType_QString.set( &(uo[i + 1]), s ); + } break; + case QVariant::Int: { + const int j = variant.toInt(); + static_QUType_int.set( &(uo[i + 1]), j ); + } break; + case QVariant::Bool: { + const bool b = variant.toBool(); + static_QUType_bool.set( &(uo[i + 1]), b ); + } break; + case QVariant::Double: { + const double d = variant.toDouble(); + static_QUType_double.set( &(uo[i + 1]), d ); + } break; + case QVariant::Invalid: { + static_QUType_QVariant.set( &(uo[i + 1]), variant ); + } + + /*FIXME + static_QUType_charstar + static_QUType_ptr.get(uo); QObject *qobj = (QObject *)(ptr); + */ + + default: { + throw Exception(QString("Invalid parameter !!!!!!!!!!!!!!!!!!!!!!!")); + } break; + } + } break; + + case Variable::TypeObject: { + kdDebug() << "Variable::TypeObject" << endl; + + const QObject* obj = arguments[i + 1]->object(); + if(! obj) { //FIXME: move check to MetaParameter?! + throw Exception(QString("No QObject !")); + } + static_QUType_ptr.set( &(uo[i + 1]), obj ); + } break; + + default: { + throw Exception(QString("Invalid variable type")); + } break; + } + + } + + return uo; +} + +KSharedPtr<Variable> MetaMethod::toVariable(QUObject* uo) +{ + const QString desc( uo->type->desc() ); + + if(desc == "null") { + return new Variable(); + } + + if(desc == "QString") { + const QString s = static_QUType_QString.get(uo); + return new Variable(s); + } + + if(desc == "int") { + const int j = static_QUType_int.get(uo); + return new Variable(j); + } + + if(desc == "bool") { + const bool b = static_QUType_bool.get(uo); + return new Variable(b); + } + + if(desc == "double") { + const double d = static_QUType_double.get(uo); + return new Variable(d); + } + + if(desc == "QVariant") { + QVariant v = static_QUType_QVariant.get(uo); + return new Variable(v); + } + + throw Exception(QString("Invalid parameter '%1'").arg(desc)); +} + +Variable::List MetaMethod::toVariableList(QUObject* uo) +{ + Variable::List list; + + MetaParameter::List::ConstIterator it, end( d->arguments.constEnd() ); + for( it = d->arguments.constBegin(); it != end; ++it) { + list.append( toVariable(uo) ); + uo++; + } + + return list; +} + +KSharedPtr<Variable> MetaMethod::invoke(Variable::List arguments) +{ + kdDebug() << "KSharedPtr<Variable> MetaMethod::invoke(Variable::List arguments)" << endl; + + if(! d->object) { + throw Exception("MetaObject is undefined."); + } + + QObject* obj = d->object->object(); + KSharedPtr<Variable> returnvalue; + QUObject* qu = 0; + + try { + qu = toQUObject(arguments); + + switch( d->type ) { + case Signal: { + int index = d->object->indexOfSignal( d->signature.latin1() ); + obj->qt_emit(index, qu); + } break; + case Slot: { + int index = d->object->indexOfSlot( d->signature.latin1() ); + obj->qt_invoke(index, qu); + } break; + default: { + throw Exception("Unknown type."); + } break; + } + returnvalue = toVariable( &qu[0] ); + } + catch(Exception& e) { + delete [] qu; // free the QUObject array and + kdDebug() << "EXCEPTION in KoMacro::MetaMethod::invoke(Variable::List)" << endl; + throw Exception(e); // re-throw exception + } + + delete [] qu; + return returnvalue; +} diff --git a/kexi/plugins/macros/lib/metamethod.h b/kexi/plugins/macros/lib/metamethod.h new file mode 100644 index 000000000..df53ac60c --- /dev/null +++ b/kexi/plugins/macros/lib/metamethod.h @@ -0,0 +1,150 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2005 by Tobi Krebs (tobi.krebs@gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#ifndef KOMACRO_METAMETHOD_H +#define KOMACRO_METAMETHOD_H + +#include <qstring.h> +#include <qvaluelist.h> +#include <ksharedptr.h> + +#include "komacro_export.h" + +struct QUObject; + +namespace KoMacro { + + // forward declarations. + class Variable; + class MetaObject; + class MetaParameter; + class MetaProxy; + + /** + * Class to provide abstract methods for the undocumented + * Qt3 QUObject-API functionality. + * + * The design tried to limit future porting to Qt4 by providing a + * somewhat similar API to the Qt4 QMeta* stuff. + */ + class KOMACRO_EXPORT MetaMethod : public KShared + { + public: + + /** + * The type of method this @a MetaMethod provides + * access to. + */ + enum Type { + Signal, /// The @a MetaMethod points to a Qt signal. + Slot, /// The @a MetaMethod points to a Qt slot. + Unknown /// The @a MetaMethod is not known. + }; + + /** + * Constructor. + * + * @param signature The signature this @a MetaMethod has. This + * includes the tagname and the arguments and could look like + * "myslot(const QString&, int)". + * @param type The @a MetaMethod::Type the @a MethodMethod + * has. + * @param object The @a MetaObject this @a MethodMethod + * belongs to. Each @a MethodMethod is associated with + * exactly one @a MetaObject . + */ + explicit MetaMethod(const QString& signature, Type type = Unknown, KSharedPtr<MetaObject> object = 0); + + /** + * Destructor. + */ + ~MetaMethod(); + + /** + * @return the @a MetaObject instance this @a MethodMethod + * belongs to. + */ + KSharedPtr<MetaObject> const object() const; + + /** + * @return the signature this @a MetaMethod has. It could + * be something like "mySlot(const QString&,int)". + */ + const QString signature() const; + + /** + * @return the signatures tagname this @a MetaMethod has. + * At the signature "mySlot(const QString&,int)" the + * tagname would be "mySlot". + */ + const QString signatureTag() const; + + /** + * @return the signatures arguments this @a MetaMethod has. + * At the signature "mySlot(const QString&,int)" the + * arguments are "const QString&,int". + */ + const QString signatureArguments() const; + + /** + * @return the @a Type of method this @a MetaMethod provides + * access to. + */ + Type type() const; + + /** + * @return the signature arguments as parsed list of + * @a MetaParameter instances. + */ + QValueList< KSharedPtr<MetaParameter> > arguments() const; + + /** + * Translate the passed @p arguments list of @a Variable instances + * into a Qt3 QUObject* array. + */ + QUObject* toQUObject(QValueList< KSharedPtr<Variable> > arguments); + + /** + * Translate the passed @p uo QUObject reference into an internal used + * @a Variable instances. + */ + KSharedPtr<Variable> toVariable(QUObject* uo); + + /** + * Translate the passed @p uo QUObject array into an internal used + * list of @a Variable instances. + */ + QValueList< KSharedPtr<Variable> > toVariableList(QUObject* uo); + + /** + * Invoke the @a MetaMethod with the optional arguments + * @p arguments and return a variable. + */ + KSharedPtr<Variable> invoke(QValueList< KSharedPtr<Variable> > arguments); + + private: + /// @internal d-pointer class. + class Private; + /// @internal d-pointer instance. + Private* const d; + }; + +} + +#endif diff --git a/kexi/plugins/macros/lib/metaobject.cpp b/kexi/plugins/macros/lib/metaobject.cpp new file mode 100644 index 000000000..000f4181a --- /dev/null +++ b/kexi/plugins/macros/lib/metaobject.cpp @@ -0,0 +1,151 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2005 by Tobi Krebs (tobi.krebs@gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#include "metaobject.h" +#include "metamethod.h" +#include "variable.h" +#include "exception.h" + +#include <qguardedptr.h> +#include <qmetaobject.h> + +#include <kdebug.h> + +using namespace KoMacro; + +namespace KoMacro { + + /** + * @internal d-pointer class to be more flexible on future extension of the + * functionality without to much risk to break the binary compatibility. + */ + class MetaObject::Private + { + public: + + /** + * The QObject instance this @a MetaObject belongs to. + */ + QGuardedPtr<QObject> const object; + + /** + * Constructor. + */ + Private(QObject* const object) + : object(object) + { + } + }; + +} + +MetaObject::MetaObject(QObject* const object) + : KShared() + , d( new Private(object) ) // create the private d-pointer instance. +{ +} + +MetaObject::~MetaObject() +{ + delete d; +} + +QObject* const MetaObject::object() const +{ + if(! d->object) { + throw Exception(QString("Object is undefined.")); + } + return d->object; +} + +/* +QStrList MetaObject::signalNames() const +{ + return object()->metaObject()->signalNames(); +} + +QStrList MetaObject::slotNames() const +{ + return object()->metaObject()->slotNames(); +} +*/ + +int MetaObject::indexOfSignal(const char* signal) const +{ + QMetaObject* metaobject = object()->metaObject(); + int signalid = metaobject->findSignal(signal, false); + if(signalid < 0) { + throw Exception(QString("Invalid signal \"%1\"").arg(signal)); + } + return signalid; +} + +int MetaObject::indexOfSlot(const char* slot) const +{ + QMetaObject* metaobject = object()->metaObject(); + int slotid = metaobject->findSlot(slot, false); + if(slotid < 0) { + throw Exception(QString("Invalid slot \"%1\"").arg(slot)); + } + return slotid; +} + +KSharedPtr<MetaMethod> MetaObject::method(int index) +{ + QObject* obj = object(); + MetaMethod::Type type = MetaMethod::Slot; + QMetaObject* metaobject = obj->metaObject(); + + const QMetaData* metadata = metaobject->slot(index, true); + if(! metadata) { + // Try to get a signal with that index iff we failed to determinate + // a matching slot. + + metadata = metaobject->signal(index, true); + if(! metadata) { + throw Exception(QString("Invalid method index \"%1\" in object \"%2\"").arg(index).arg(obj->name())); + } + type = MetaMethod::Signal; + } + + if(metadata->access != QMetaData::Public) { + throw Exception(QString("Not allowed to access method \"%1\" in object \"%2\"").arg(metadata->name).arg(obj->name())); + } + + return new MetaMethod(metadata->name, type, this); +} + +KSharedPtr<MetaMethod> MetaObject::signal(const char* signal) +{ + return method( indexOfSignal(signal) ); +} + +KSharedPtr<MetaMethod> MetaObject::slot(const char* slot) +{ + return method( indexOfSlot(slot) ); +} + +KSharedPtr<Variable> MetaObject::invokeMethod(int index, Variable::List arguments) +{ + // kdDebug() << "MetaObject::invokeMethod(int index, Variable::List arguments)" << endl; + KSharedPtr<MetaMethod> m = method(index); + // kdDebug() << "MetaObject::invokeMethod(int index, Variable::List arguments) return" << endl; + return m->invoke(arguments); +} + diff --git a/kexi/plugins/macros/lib/metaobject.h b/kexi/plugins/macros/lib/metaobject.h new file mode 100644 index 000000000..8b6115742 --- /dev/null +++ b/kexi/plugins/macros/lib/metaobject.h @@ -0,0 +1,118 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2005 by Tobi Krebs (tobi.krebs@gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#ifndef KOMACRO_METAOBJECT_H +#define KOMACRO_METAOBJECT_H + +#include <qobject.h> +#include <ksharedptr.h> + +#include "komacro_export.h" + +namespace KoMacro { + + // forward declarations. + class Variable; + class MetaMethod; + + /** + * Class to provide abstract access to extended QObject functionality + * like the undocumented QUObject-API in Qt3. + * + * The design tried to limit future porting to Qt4 by providing a + * somewhat similar API to the Qt4 QMeta* stuff. + */ + class KOMACRO_EXPORT MetaObject : public KShared + { + public: + + /** + * Constructor. + * + * @param object The QObject instance this @a MetaObject provides + * abstract access to. + */ + explicit MetaObject(QObject* const object); + + /** + * Destructor. + */ + ~MetaObject(); + + /** + * @return the QObject this @a MetaObject provides abstract + * access to. + */ + QObject* const object() const; + + //QStrList signalNames() const; + //QStrList slotNames() const; + + /** + * @return the index of the signal @p signal . + */ + int indexOfSignal(const char* signal) const; + + /** + * @return the index of the slot @p slot . + */ + int indexOfSlot(const char* slot) const; + + /** + * @return the @a MetaMethod that matches to the + * index @p index . + */ + KSharedPtr<MetaMethod> method(int index); + + /** + * @return a @a MetaMethod for the signal @p signal . + */ + KSharedPtr<MetaMethod> signal(const char* signal); + + /** + * @return a @a MetaMethod for the slot @p slot . + */ + KSharedPtr<MetaMethod> slot(const char* slot); + +//KSharedPtr<MetaMethod> addSlot(const char* slot); +//void connectSignal(QObject* obj, const char* signal); + + /** + * Invoke the @a MetaMethod that has the index @p index . + * + * @param index The index the signal or slot has. Use + * @a indexOfSignal() and @a indexOfSlot() to determinate + * those index. + * @param arguments The optional arguments passed to the + * method. + * @return The returnvalue the method provides and that got + * returned if the execution is done. + */ + KSharedPtr<Variable> invokeMethod(int index, QValueList< KSharedPtr<Variable> > arguments); + + private: + /// @internal d-pointer class. + class Private; + /// @internal d-pointer instance. + Private* const d; + }; + +} + +#endif diff --git a/kexi/plugins/macros/lib/metaparameter.cpp b/kexi/plugins/macros/lib/metaparameter.cpp new file mode 100644 index 000000000..7f072b2bc --- /dev/null +++ b/kexi/plugins/macros/lib/metaparameter.cpp @@ -0,0 +1,146 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2005 by Tobi Krebs (tobi.krebs@gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#include "metaparameter.h" +#include "exception.h" +#include "variable.h" + +#include <kdebug.h> + +using namespace KoMacro; + +namespace KoMacro { + + /** + * @internal d-pointer class to be more flexible on future extension of the + * functionality without to much risk to break the binary compatibility. + */ + class MetaParameter::Private + { + public: + + /** + * The signatures argument that represents this MetaParameter. + * This could be something like "const QString&", "int" or + * "QMap < QString, QVariant > ". + */ + QString signatureargument; + + /** + * The type of the @a Variable . + */ + MetaParameter::Type type; + + /** + * If the @a MetaParameter::Type is a Variant this QVariant::Type + * is used to defined what kind of Variant it is. + */ + QVariant::Type varianttype; + + }; + +} + +MetaParameter::MetaParameter(const QString& signatureargument) + : KShared() + , d( new Private() ) // create the private d-pointer instance. +{ + d->type = TypeNone; + + if(! signatureargument.isNull()) { + setSignatureArgument( signatureargument ); + } +} + +MetaParameter::~MetaParameter() +{ + delete d; +} + +MetaParameter::Type MetaParameter::type() const +{ + return d->type; +} + +const QString MetaParameter::typeName() const +{ + switch( d->type ) { + case TypeNone: + return "None"; + case TypeVariant: + return "Variant"; + case TypeObject: + return "Object"; + } + return QString::null; +} + +void MetaParameter::setType(MetaParameter::Type type) +{ + d->type = type; + d->varianttype = QVariant::Invalid; +} + +QVariant::Type MetaParameter::variantType() const +{ + return d->varianttype; +} + +void MetaParameter::setVariantType(QVariant::Type varianttype) +{ + d->type = TypeVariant; + d->varianttype = varianttype; +} + +void MetaParameter::setSignatureArgument(const QString& signatureargument) +{ + d->signatureargument = signatureargument; + + QString argument = signatureargument; + if(argument.startsWith("const")) { + argument = argument.mid(5).stripWhiteSpace(); + } + + if(argument.endsWith("&")) { + argument = argument.left( argument.length() - 1 ).stripWhiteSpace(); + } + + if(argument.isEmpty()) { + throw Exception(QString("Empty signature argument passed.")); + } + if(argument == "QVariant") { + setVariantType( QVariant::Invalid ); + } + + QVariant::Type type = argument.isNull() ? QVariant::Invalid : QVariant::nameToType(argument.latin1()); + if (type != QVariant::Invalid) { + setVariantType( type ); + } + else { + setType( TypeObject ); + } +} + +bool MetaParameter::validVariable(KSharedPtr<Variable> variable) const +{ + if( type() != variable->type() ) { + return false; + } + return true; +} diff --git a/kexi/plugins/macros/lib/metaparameter.h b/kexi/plugins/macros/lib/metaparameter.h new file mode 100644 index 000000000..ab2a4004e --- /dev/null +++ b/kexi/plugins/macros/lib/metaparameter.h @@ -0,0 +1,136 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2005 by Tobi Krebs (tobi.krebs@gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#ifndef KOMACRO_METAPARAMETER_H +#define KOMACRO_METAPARAMETER_H + +#include <qstring.h> +#include <qvariant.h> +#include <qobject.h> +#include <ksharedptr.h> + +#include "komacro_export.h" + +namespace KoMacro { + + // Forward declarations. + class Variable; + + /** + * Class to provide abstract methods for the undocumented + * Qt3 QUObject-API functionality. + * + * The design tried to limit future porting to Qt4 by providing a + * somewhat similar API to the Qt4 QMeta* stuff. + */ + class KOMACRO_EXPORT MetaParameter : public KShared + { + + /** + * Property to get the type of the variable. + */ + Q_PROPERTY(Type type READ type) + + /** + * Property to get the type of the variable as string. + */ + Q_PROPERTY(QString typeName READ typeName) + + public: + + /** + * List of @a MetaParameter instances. + */ + typedef QValueList<KSharedPtr <MetaParameter > > List; + + /** + * Constructor. + * + * @param signatureargument The signatures argument + * that will be used to determinate the arguments + * type. This could be something like "const QString&", + * "int" or "QMap < QString, QVariant > ". + */ + explicit MetaParameter(const QString& signatureargument = QString::null); + + /** + * Destructor. + */ + ~MetaParameter(); + + /** + * Possible types the @a MetaParameter could provide. + */ + enum Type { + TypeNone = 0, /// None type, the @a MetaParameter is empty. + TypeVariant, /// The @a MetaParameter is a QVariant. + TypeObject /// The @a MetaParameter is a QObject. + }; + + /** + * @return the @a MetaParameter::Type this variable has. + */ + Type type() const; + + /** + * @return the @a MetaParameter::Type as string. The typename + * could be "None", "Variant" or "Object". + */ + const QString typeName() const; + + /** + * Set the @a MetaParameter::Type this variable is. + */ + void setType(Type type); + + /** + * @return the @a MetaParameter::Type this variable is. + */ + QVariant::Type variantType() const; + + /** + * Set the @a MetaParameter::Type this variable is. + */ + void setVariantType(QVariant::Type varianttype); + + /** + * @return true if the passed @a Variable @p variable is + * valid for this @a MetaParameter . Valid means, that + * the variable has a castable type. + */ + bool validVariable(KSharedPtr<Variable> variable) const; + + protected: + + /** + * @internal used method to set the signature argument. Those + * argument will be used to determinate the arguments type. + */ + void setSignatureArgument(const QString& signatureargument); + + private: + /// @internal d-pointer class. + class Private; + /// @internal d-pointer instance. + Private* const d; + }; + +} + +#endif diff --git a/kexi/plugins/macros/lib/variable.cpp b/kexi/plugins/macros/lib/variable.cpp new file mode 100644 index 000000000..598b8b46f --- /dev/null +++ b/kexi/plugins/macros/lib/variable.cpp @@ -0,0 +1,246 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2005 by Tobi Krebs (tobi.krebs@gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#include "variable.h" +#include "exception.h" + +#include <kdebug.h> + +using namespace KoMacro; + +namespace KoMacro { + + /** + * @internal d-pointer class to be more flexible on future extension of the + * functionality without to much risk to break the binary compatibility. + */ + class Variable::Private + { + public: + + /** + * The name this @a Variable has. + */ + QString name; + + /** + * The i18n-caption used for display purposes only + * this @a Variable has. + */ + QString text; + + /** + * If @a Variable::Type is @a Variable::TypeVariant this QVariant + * holds the value else it's invalid. + */ + QVariant variant; + + /** + * If @a Variable::Type is @a Variable::TypeObject this QObject is + * the value else it's NULL. + */ + const QObject* object; + + /** + * Optional list of children this @a Variable has. + */ + // TODO Dow we use this or is it for the future?? + Variable::List children; + + /** + * Defines if the variable is enabled or disabled. + */ + bool enabled; + + explicit Private() + : enabled(true) + { + } + }; + +} + +Variable::Variable() + : MetaParameter() + , d( new Private() ) // create the private d-pointer instance. +{ + setType(TypeNone); + d->object = 0; +} + +Variable::Variable(const QVariant& variant, const QString& name, const QString& text) + : MetaParameter() + , d( new Private() ) // create the private d-pointer instance. +{ + setVariantType(variant.type()); + d->variant = variant; + d->object = 0; + d->name = name; + d->text = text; +} + +Variable::Variable(const QObject* object) + : MetaParameter() + , d( new Private() ) // create the private d-pointer instance. +{ + setType(TypeObject); + d->object = object; +} + +Variable::Variable(const QDomElement& element) + : MetaParameter() + , d( new Private() ) // create the private d-pointer instance. +{ + + QString typesignature = element.attribute("type", "const QString&"); + QString value = element.text(); + + setSignatureArgument( typesignature ); + + switch( type() ) { + case KoMacro::MetaParameter::TypeVariant: { + //kdDebug() << QString("KoMacro::Variable(QDomElement) KoMacro::MetaParameter::TypeVariant") << endl; + // Set the variant without overwritting the previously detected varianttype. + setVariant( QVariant(value), false ); + } break; + case KoMacro::MetaParameter::TypeObject: { + //kdDebug() << QString("KoMacro::Variable(QDomElement) KoMacro::MetaParameter::TypeObject") << endl; + //TODO setObject(); + } break; + default: { + kdWarning() << QString("KoMacro::Variable(QDomElement) KoMacro::MetaParameter::TypeNone") << endl; + } break; + } +} + +Variable::~Variable() +{ + delete d; +} + +QString Variable::name() const +{ + return d->name; +} + +void Variable::setName(const QString& name) +{ + d->name = name; +} + +QString Variable::text() const +{ + return d->text; +} + +void Variable::setText(const QString& text) +{ + d->text = text; +} + +const QVariant Variable::variant() const +{ + //Q_ASSERT( type() == MetaParameter::TypeVariant ); + //Q_ASSERT( variantType() != QVariant::Invalid ); + //if(variantType() == QVariant::Invalid) return QVariant(); + return d->variant; +} + +void Variable::setVariant(const QVariant& variant, bool detecttype) +{ + if(detecttype) { + setVariantType( variant.type() ); + } + d->variant = variant; +} + +const QObject* Variable::object() const +{ + Q_ASSERT( ! d->object ); + return d->object; +} + +void Variable::setObject(const QObject* object) +{ + setType(TypeObject); + d->object = object; +} + +Variable::operator QVariant () const +{ + return variant(); +} + +Variable::operator const QObject* () const +{ + return object(); +} + +const QString Variable::toString() const +{ + switch( type() ) { + case KoMacro::MetaParameter::TypeVariant: { + return variant().toString(); + } break; + case KoMacro::MetaParameter::TypeObject: { + return QString("[%1]").arg( object()->name() ); + } break; + default: { + throw Exception("Type is undefined."); + } break; + } + return QString::null; +} + +int Variable::toInt() const +{ + return variant().toInt(); +} + +Variable::List Variable::children() const +{ + return d->children; +} + +void Variable::appendChild(KSharedPtr<Variable> variable) +{ + d->children.append(variable); +} + +void Variable::clearChildren() +{ + d->children.clear(); +} + +void Variable::setChildren(const Variable::List& children) +{ + d->children = children; +} + +/* +bool Variable::isEnabled() const +{ + return d->enabled; +} + +void Variable::setEnabled(const bool enabled) +{ + d->enabled = enabled; +} +*/ diff --git a/kexi/plugins/macros/lib/variable.h b/kexi/plugins/macros/lib/variable.h new file mode 100644 index 000000000..26e9619ee --- /dev/null +++ b/kexi/plugins/macros/lib/variable.h @@ -0,0 +1,222 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2005 by Tobi Krebs (tobi.krebs@gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#ifndef KOMACRO_VARIABLE_H +#define KOMACRO_VARIABLE_H + +#include <qobject.h> +#include <qdom.h> +#include <qvariant.h> +#include <ksharedptr.h> + +#include "metaparameter.h" + +namespace KoMacro { + + /** + * A variable value used to provide abstract access to variables. The + * class handles QVariant and QObject and provides access to them. + * Variable inherits KShared and implements reference couting. So, it's + * not needed to take care of memory-managment. + */ + class KOMACRO_EXPORT Variable : public MetaParameter + { + + /** + * Property to get and set a QVariant as variable. + */ + Q_PROPERTY(QVariant variant READ variant WRITE setVariant) + + /** + * Property to get and set a QObject as variable. + */ + Q_PROPERTY(QObject* object READ object WRITE setObject) + + /** + * Property to get a string-representation of the variable. + */ + Q_PROPERTY(QString string READ toString) + + public: + + /** + * A list of variables. + */ + typedef QValueList<KSharedPtr<Variable > > List; + + /** + * A map of variables. + */ + typedef QMap<QString, KSharedPtr<Variable > > Map; + + /** + * Default constructor. + */ + explicit Variable(); + + /** + * Constructor from the QVariant @p variant . + * + * @param variant The value this variable has. + * @param name The unique @a name() this variable has. + * @param text The describing @a text() this variable has. + */ + Variable(const QVariant& variant, const QString& name = QString::null, const QString& text = QString::null); + + /** + * Constructor from the QObject @p object . + * + * @param object The value this variable has. + */ + Variable(const QObject* object); + + /** + * Constructor from the QDomElement @p element . + * @deprecated replaced with methods of @a XMLHandler. + * @param element The QDomElement that may optional contains the + * variable content or other additional informations. + */ + Variable(const QDomElement& element); + + /** + * Destructor. + */ + virtual ~Variable(); + + /** + * @return the name this @a Variable has. + */ + QString name() const; + + /** + * Set the name @param name this @a Variable has. + */ + void setName(const QString& name); + + /** + * @return the caption this @a Variable has. + */ + QString text() const; + + /** + * Set the caption @param text this @a Variable has. + */ + void setText(const QString& text); + + /** + * Set the QObject @param object this variable has. A + * previously remembered value will be overwritten and + * the new type is a @a TypeObject . + */ + void setObject(const QObject* object); + + /** + * @return the QVariant this variable has. If this + * variable isn't a @a TypeVariant an invalid QVariant + * got returned. + */ + const QVariant variant() const; + + /** + * Set the QVariant @param variant this variable has. A + * previously remembered value will be overwritten and + * the new type is a @a TypeVariant . If @param detecttype is + * true the method tries to set the @a variantType according + * to the passed QVariant. If false the variantType won't + * be changed. + */ + void setVariant(const QVariant& variant, bool detecttype = true); + + /** + * @return the QObject this variable has. If this + * variable isn't a @a TypeObject NULL got returned. + */ + const QObject* object() const; + + /** + * Implicit conversion to QVariant operator. This method + * calls @a variant() internaly. + */ + operator QVariant () const; + + /** + * Implicit conversion to QObject operator. This method + * calls @a object() internaly. + */ + operator const QObject* () const; + + /** + * @return a string-represenation of the variable. + */ + const QString toString() const; + + /** + * @return a integer-represenation of the variable. + */ + int toInt() const; + + /** + * @return the optional list of @a Variable instances + * that are children of this @a Variable . + * + * @note that the list is returned call-by-reference. The + * list is accessed as getter/setter (read/write). So, + * don't set this method to const! + */ + List children() const; + + /** + * Append a @a Variable to the list of children this + * @a Variable has. + */ + void appendChild(KSharedPtr<Variable> variable); + + /** + * Clear the list of children this @a Variable has. + */ + void clearChildren(); + + /** + * Set the children this @a Variable has. + */ + void setChildren(const List& children); + +#if 0 + /** + * @return true if this @a Variable is enabled else + * false is returned. + */ + bool isEnabled() const; + + /** + * Set this @a Variable to be enabled if @param enabled is + * true else the variable is disabled. + */ + void setEnabled(const bool enabled); +#endif + private: + /// @internal d-pointer class. + class Private; + /// @internal d-pointer instance. + Private* const d; + }; + +} + +#endif diff --git a/kexi/plugins/macros/lib/xmlhandler.cpp b/kexi/plugins/macros/lib/xmlhandler.cpp new file mode 100644 index 000000000..b35759e1d --- /dev/null +++ b/kexi/plugins/macros/lib/xmlhandler.cpp @@ -0,0 +1,226 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2006 by Bernd Steindorff (bernd@itii.de) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#include "xmlhandler.h" +#include "macro.h" +#include "macroitem.h" +#include "action.h" + +#include <qdom.h> +#include <kdebug.h> + +using namespace KoMacro; + +namespace KoMacro { + + /** + * @internal d-pointer class to be more flexible on future extension of the + * functionality without to much risk to break the binary compatibility. + */ + class XMLHandler::Private + { + public: + + /** + * The @a Macro instance this @a XMLHandler + * manages. + */ + Macro* const macro; + + /** + * Constructor. + * + * @param macro The @a Macro instance this + * @a XMLHandler manages. + */ + Private(Macro* const macro) + : macro(macro) + { + } + }; + +} + +XMLHandler::XMLHandler(Macro* const macro) + : d( new Private(macro) ) +{ +} + +XMLHandler::~XMLHandler() +{ + delete d; +} + +bool XMLHandler::parseXML(const QDomElement& element) +{ + // Remove old items. We should clear first. + d->macro->clearItems(); + + // We expect a <macro> element. Do we really need to be such strict or + // would it be more wise to trust the application in that case? + if(element.tagName() != "macro") { + kdDebug() << QString("XMLHandler::parseXML() Invalid tagname \"%1\"").arg(element.tagName()) << endl; + return false; + } + + // To be flexible with the xml-scheme, we need a version-number for xml. + // If there is more than one version, parsing should update old macro-data, so that it + // could write out in the newer version in toXML(). + if( element.attribute("xmlversion") != "1"){ + kdDebug() << QString("XMLHandler::parseXML() Invalid xml-version \"%1\"").arg(element.attribute("xmlversion")) << endl; + return false; + } + + // Do we need to load the macro's name? + // d->macro->setName(element.attribute("name")); + + // Iterate through the child nodes the passed QDomElement has and + // build the MacroItem elements. + for(QDomNode itemnode = element.firstChild(); ! itemnode.isNull(); itemnode = itemnode.nextSibling()) { + // The tagname should be "item" + if(itemnode.nodeName() == "item") { + // The node is an element. + const QDomElement itemelem = itemnode.toElement(); + + // Create a new MacroItem + KSharedPtr<MacroItem> item = new MacroItem(); + + // Add the new item to our Macro. + d->macro->addItem( item ); + + // Each MacroItem may point to an Action instance. We + // try to determinate this action now and if it's defined + // and available, we set it. + KSharedPtr<Action> action = Manager::self()->action( itemelem.attribute("action") ); + if(action.data()) { + item->setAction(action); + } + + // Set the comment + item->setComment( itemelem.attribute("comment") ); + + // Iterate through the children this item has and try + // to fill the list of variables our new MacroItem has. + for(QDomNode childnode = itemnode.firstChild(); ! childnode.isNull(); childnode = childnode.nextSibling()) { + // The tagname should be "variable" + if(childnode.nodeName() == "variable") { + // The node is an element. + const QDomElement childelem = childnode.toElement(); + + // The name the variable has. + const QString name = childelem.attribute("name"); + // The value the variable has. + const QString value = childelem.text(); + + // Store the new variable in our macroitem. + item->addVariable(name, value); + } + } + } + } + + // Job was done successfully. + return true; +} + +QDomElement XMLHandler::toXML() +{ + // The QDomDocument provides us the functionality to create new QDomElement instances. + QDomDocument document; + + // Create the Macro-QDomElement. This element will be returned. + QDomElement macroelem = document.createElement("macro"); + + // Set the Macro-XML-Version, it should be the newest Version. + macroelem.setAttribute("xmlversion","1"); + + // Do we need to store the macro's name? Normaly the application + // could/should take care of it cause we don't know how the app + // may store the XML and cause we don't like to introduce + // redundancy at this point. + //macroelem.setAttribute("name",d->macro->name()); + + // The list of MacroItem-children a Macro provides. + QValueList<KSharedPtr<MacroItem > > items = d->macro->items(); + + // Create an iterator... + QValueList<KSharedPtr<MacroItem > >::ConstIterator it(items.constBegin()), end(items.constEnd()); + // ...and iterate over the list of children the Macro provides. + for(;it != end; ++it) { + // We are iterating over MacroItem instances. + KSharedPtr<MacroItem> item = *it; + + // Flag to determinate if we really need to remember this item what + // is only the case if comment or action is defined. + bool append = false; + + // Each MacroItem will have an own node. + QDomElement itemelem = document.createElement("item"); + + // Each MacroItem could point to an Action provided by the Manager. + const KSharedPtr<Action> action = item->action(); + if( action ) { + append = true; + + // Remember the name of the action. + itemelem.setAttribute("action", action->name()); + + // Each MacroItem could have a list of variables. We + // iterate through that list and build a element + // for each single variable. + QMap<QString, KSharedPtr<Variable > > varmap = item->variables(); + + for(QMap<QString, KSharedPtr<Variable > >::ConstIterator vit = varmap.constBegin(); vit != varmap.constEnd(); ++vit) { + const KSharedPtr<Variable> v = vit.data(); + if(! v.data()) { + // skip if the variable is NULL. + continue; + } + // Create an own element for the variable. The tagname will be + // the name of the variable. + QDomElement varelement = document.createElement("variable"); + + // Remember the name the value has. + varelement.setAttribute("name", vit.key()); + + // Remember the value as textnode. + varelement.appendChild(document.createTextNode(v->toString())); + + // Add the new variable-element to our MacroItem. + itemelem.appendChild(varelement); + } + } + + // Each MacroItem could have an optional comment. + const QString comment = item->comment(); + if(! comment.isEmpty()) { + append = true; + itemelem.setAttribute("comment", item->comment()); + } + + // Check if we really need to remember the item. + if(append) { + macroelem.appendChild(itemelem); + } + + } + + // Job done. Return the macro's element. + return macroelem; +} diff --git a/kexi/plugins/macros/lib/xmlhandler.h b/kexi/plugins/macros/lib/xmlhandler.h new file mode 100644 index 000000000..b6978d0fd --- /dev/null +++ b/kexi/plugins/macros/lib/xmlhandler.h @@ -0,0 +1,77 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2006 by Bernd Steindorff (bernd@itii.de) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#ifndef KOMACRO_XMLHANDLER_H +#define KOMACRO_XMLHANDLER_H + +#include "komacro_export.h" + +class QObject; +class QDomElement; + +namespace KoMacro { + + // Forward declarations. + class Macro; + + /** + * The XMLHandler class manages the (un-)serialization of + * a @a Macro instance to/from XML. + */ + class KOMACRO_EXPORT XMLHandler + { + public: + + /** + * Constructor to init a @a XMLHandler . + * @param macro The @a Macro instance which will + * be managed. + */ + XMLHandler(Macro* const macro); + + /** + * Destructor to @a XMLHandler . + */ + ~XMLHandler(); + + /** + * Reads a given @a QDomElement, extracts given + * Actions into the managed Macro-Instance. + * @param element The @a QDomElement within + * the @a Macro. + * @return Return true when parsing is successfull. + */ + bool parseXML(const QDomElement& element); + + /** + * Converts the macro to a @a QDomElement. + * @return The resulten @a QDomElement from + * the @a Macro. + */ + QDomElement toXML(); + + private: + /// @internal d-pointer class. + class Private; + /// @internal d-pointer instance. + Private* const d; + }; +} + +#endif |