summaryrefslogtreecommitdiffstats
path: root/kexi/plugins/macros/lib
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-20 01:29:50 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-01-20 01:29:50 +0000
commit8362bf63dea22bbf6736609b0f49c152f975eb63 (patch)
tree0eea3928e39e50fae91d4e68b21b1e6cbae25604 /kexi/plugins/macros/lib
downloadkoffice-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')
-rw-r--r--kexi/plugins/macros/lib/Makefile.am23
-rw-r--r--kexi/plugins/macros/lib/action.cpp170
-rw-r--r--kexi/plugins/macros/lib/action.h187
-rw-r--r--kexi/plugins/macros/lib/context.cpp261
-rw-r--r--kexi/plugins/macros/lib/context.h141
-rw-r--r--kexi/plugins/macros/lib/exception.cpp97
-rw-r--r--kexi/plugins/macros/lib/exception.h84
-rw-r--r--kexi/plugins/macros/lib/komacro_export.h39
-rw-r--r--kexi/plugins/macros/lib/macro.cpp126
-rw-r--r--kexi/plugins/macros/lib/macro.h130
-rw-r--r--kexi/plugins/macros/lib/macroitem.cpp217
-rw-r--r--kexi/plugins/macros/lib/macroitem.h142
-rw-r--r--kexi/plugins/macros/lib/manager.cpp170
-rw-r--r--kexi/plugins/macros/lib/manager.h219
-rw-r--r--kexi/plugins/macros/lib/metamethod.cpp344
-rw-r--r--kexi/plugins/macros/lib/metamethod.h150
-rw-r--r--kexi/plugins/macros/lib/metaobject.cpp151
-rw-r--r--kexi/plugins/macros/lib/metaobject.h118
-rw-r--r--kexi/plugins/macros/lib/metaparameter.cpp146
-rw-r--r--kexi/plugins/macros/lib/metaparameter.h136
-rw-r--r--kexi/plugins/macros/lib/variable.cpp246
-rw-r--r--kexi/plugins/macros/lib/variable.h222
-rw-r--r--kexi/plugins/macros/lib/xmlhandler.cpp226
-rw-r--r--kexi/plugins/macros/lib/xmlhandler.h77
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> &macroitem, 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 &lt; QString, QVariant &gt; ".
+ */
+ 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 &lt; QString, QVariant &gt; ".
+ */
+ 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