diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
commit | 8362bf63dea22bbf6736609b0f49c152f975eb63 (patch) | |
tree | 0eea3928e39e50fae91d4e68b21b1e6cbae25604 /kexi/plugins/macros | |
download | koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.tar.gz koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.zip |
Added old abandoned KDE3 version of koffice
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'kexi/plugins/macros')
79 files changed, 12840 insertions, 0 deletions
diff --git a/kexi/plugins/macros/Makefile.am b/kexi/plugins/macros/Makefile.am new file mode 100644 index 00000000..cf5fb0d4 --- /dev/null +++ b/kexi/plugins/macros/Makefile.am @@ -0,0 +1,9 @@ +if include_kunittest + + # Unittest is disabled per default. + # TESTSDIR = tests + +endif + +METASOURCES = AUTO +SUBDIRS = lib kexiactions kexipart diff --git a/kexi/plugins/macros/configure.in.in b/kexi/plugins/macros/configure.in.in new file mode 100644 index 00000000..52fb9f5a --- /dev/null +++ b/kexi/plugins/macros/configure.in.in @@ -0,0 +1,13 @@ +# Check for kunittest +AC_MSG_CHECKING([for kunittest]) + +# First we check if the console unittester could be compiled +have_kunittest_header="no" +KDE_CHECK_HEADER(kunittest/tester.h, have_kunittest_header="yes", , ) +AM_CONDITIONAL(include_kunittest, test "$have_kunittest_header" = "yes") + +# Second we check if the GUI-unittester could be compiled +have_kunittestgui_header="no" +KDE_CHECK_HEADER(kunittest/runnergui.h, have_kunittestgui_header="yes", , ) +AM_CONDITIONAL(include_kunittestgui, test "$have_kunittestgui_header" = "yes") + diff --git a/kexi/plugins/macros/kexiactions/Makefile.am b/kexi/plugins/macros/kexiactions/Makefile.am new file mode 100644 index 00000000..4f42e5e9 --- /dev/null +++ b/kexi/plugins/macros/kexiactions/Makefile.am @@ -0,0 +1,27 @@ +include $(top_srcdir)/kexi/Makefile.global + +noinst_LTLIBRARIES = libkeximacroactions.la + +libkeximacroactions_la_SOURCES = \ + kexiaction.cpp \ + openaction.cpp \ + executeaction.cpp \ + navigateaction.cpp \ + messageaction.cpp \ + datatableaction.cpp + +libkeximacroactions_la_CXXFLAGS = $(USE_EXCEPTIONS) + +libkeximacroactions_la_LDFLAGS = $(all_libraries) +libkeximacroactions_la_LIBADD = \ + $(top_builddir)/kexi/plugins/macros/lib/libkomacro.la \ + $(top_builddir)/kexi/core/libkexicore.la \ + $(LIB_QT) $(LIB_KDECORE) $(LIB_KDEUI) + +libkeximacroactions_la_METASOURCES = AUTO +SUBDIRS = . + +INCLUDES = \ + -I$(top_srcdir)/kexi/core \ + -I$(top_srcdir)/kexi \ + $(all_includes) diff --git a/kexi/plugins/macros/kexiactions/datatableaction.cpp b/kexi/plugins/macros/kexiactions/datatableaction.cpp new file mode 100644 index 00000000..90b13e4f --- /dev/null +++ b/kexi/plugins/macros/kexiactions/datatableaction.cpp @@ -0,0 +1,185 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * + * 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 "datatableaction.h" +//#include "objectvariable.h" + +#include <core/kexi.h> +#include <core/kexiproject.h> +#include <core/kexipartmanager.h> +#include <core/kexipartinfo.h> +#include <core/kexipart.h> +#include <core/keximainwindow.h> +#include <core/kexiinternalpart.h> + +#include <klocale.h> + +using namespace KexiMacro; + +namespace KexiMacro { + + //static const QString OBJECT = "method"; + //static const QString OBJECT = "type"; + //static const QString OBJECT = "partitem"; + + template<class ACTIONIMPL> + class MethodVariable : public KexiVariable<ACTIONIMPL> + { + public: + MethodVariable(ACTIONIMPL* actionimpl) + : KexiVariable<ACTIONIMPL>(actionimpl, "method", i18n("Method")) + { + QStringList list; + list << "import" << "export"; + this->appendChild( KSharedPtr<KoMacro::Variable>( new KoMacro::Variable(list, "@list") ) ); + + this->setVariant( list[0] ); + } + }; + + template<class ACTIONIMPL> + class TypeVariable : public KexiVariable<ACTIONIMPL> + { + public: + TypeVariable(ACTIONIMPL* actionimpl) + : KexiVariable<ACTIONIMPL>(actionimpl, "type", i18n("Type")) + { + QStringList list; + list << "file" << "clipboard"; + this->appendChild( KSharedPtr<KoMacro::Variable>( new KoMacro::Variable(list, "@list") ) ); + + this->setVariant( list[0] ); + } + }; + + template<class ACTIONIMPL> + class PartItemVariable : public KexiVariable<ACTIONIMPL> + { + public: + PartItemVariable(ACTIONIMPL* actionimpl, const QString& partitem = QString::null) + : KexiVariable<ACTIONIMPL>(actionimpl, "partitem", i18n("Item")) + { + QStringList namelist; + if(actionimpl->mainWin()->project()) { + KexiPart::PartInfoList* parts = Kexi::partManager().partInfoList(); + for(KexiPart::PartInfoListIterator it(*parts); it.current(); ++it) { + KexiPart::Info* info = it.current(); + if(! info->isDataExportSupported()) + continue; + KexiPart::ItemDict* items = actionimpl->mainWin()->project()->items(info); + if(items) + for(KexiPart::ItemDictIterator item_it = *items; item_it.current(); ++item_it) + namelist << info->objectName() + "." + item_it.current()->name(); + } + for(QStringList::Iterator it = namelist.begin(); it != namelist.end(); ++it) + this->appendChild( KSharedPtr<KoMacro::Variable>(new KoMacro::Variable(*it)) ); + + //const QString name = info->objectName(); //info->groupName(); + //this->appendChild( KSharedPtr<KoMacro::Variable>(new KoMacro::Variable(name)) ); + } + const QString n = + namelist.contains(partitem) + ? partitem + : namelist.count() > 0 ? namelist[0] : ""; + this->setVariant(n); + kdDebug()<<"##################### KexiActions::ObjectVariable() variant="<<this->variant()<<endl; + } + }; + +} + +DataTableAction::DataTableAction() + : KexiAction("datatable", i18n("Data Table")) +{ + setVariable(KSharedPtr<KoMacro::Variable>( new MethodVariable<DataTableAction>(this) )); + setVariable(KSharedPtr<KoMacro::Variable>( new TypeVariable<DataTableAction>(this) )); + setVariable(KSharedPtr<KoMacro::Variable>( new PartItemVariable<DataTableAction>(this) )); +} + +DataTableAction::~DataTableAction() +{ +} + +bool DataTableAction::notifyUpdated(KSharedPtr<KoMacro::MacroItem> macroitem, const QString& name) +{ + kdDebug()<<"DataTableAction::notifyUpdated() name="<<name<<" macroitem.action="<<(macroitem->action() ? macroitem->action()->name() : "NOACTION")<<endl; + /* + KSharedPtr<KoMacro::Variable> variable = macroitem->variable(name, false); + if(! variable) { + kdWarning()<<"DataTableAction::notifyUpdated() No such variable="<<name<<" in macroitem."<<endl; + return false; + } + variable->clearChildren(); + if(name == "method") { + const int partitem = macroitem->variant(OBJECT, true).toString(); + macroitem->variable(OBJECT, true)->setChildren( + KoMacro::Variable::List() << KSharedPtr<KoMacro::Variable>(new ObjectVariable<ExecuteAction>(this, partitem)) ); + } + */ + return true; +} + +void DataTableAction::activate(KSharedPtr<KoMacro::Context> context) +{ + if(! mainWin()->project()) { + kdWarning() << "ExecuteAction::activate(KSharedPtr<KoMacro::Context>) Invalid project" << endl; + return; + } + + const QString method = context->variable("method")->variant().toString(); + const QString type = context->variable("type")->variant().toString(); + + const QString partitem = context->variable("partitem")->variant().toString(); + QString identifier; + if(! partitem.isEmpty()) { + QStringList parts = QStringList::split(".", partitem); + KexiPart::Part* part = Kexi::partManager().partForMimeType( QString("kexi/%1").arg(parts[0]) ); + KexiPart::Item* item = part ? mainWin()->project()->item(part->info(), parts[1]) : 0; + if(! item) + throw KoMacro::Exception(i18n("No such item \"%1\"").arg(partitem)); + identifier = QString::number(item->identifier()); + } + + QMap<QString,QString> args; + if(! identifier.isNull()) + args.insert("itemId", identifier); + + if(method == "import") { + args.insert("sourceType", type); + QDialog *dlg = KexiInternalPart::createModalDialogInstance( + "csv_importexport", "KexiCSVImportDialog", 0, mainWin(), 0, &args); + if (!dlg) + return; //error msg has been shown by KexiInternalPart + dlg->exec(); + delete dlg; + } + else if(method == "export") { + args.insert("destinationType", type); + QDialog *dlg = KexiInternalPart::createModalDialogInstance( + "csv_importexport", "KexiCSVExportWizard", 0, mainWin(), 0, &args); + if (!dlg) + return; //error msg has been shown by KexiInternalPart + dlg->exec(); + delete dlg; + } + else { + throw KoMacro::Exception(i18n("No such method \"%1\"").arg(method)); + } +} + +//#include "executeaction.moc" diff --git a/kexi/plugins/macros/kexiactions/datatableaction.h b/kexi/plugins/macros/kexiactions/datatableaction.h new file mode 100644 index 00000000..3b5b32c0 --- /dev/null +++ b/kexi/plugins/macros/kexiactions/datatableaction.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * + * 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 KEXIMACRO_DATATABLEACTION_H +#define KEXIMACRO_DATATABLEACTION_H + +#include "kexiaction.h" + +class KexiMainWindow; + +namespace KoMacro { + class Context; +} + +namespace KexiMacro { + + /** + * The DataTableAction class implements a @a KoMacro::Action + * to provide functionality to import or export a datatable. + * The datatable is used to deal with comma separated values. + */ + class DataTableAction : public KexiAction + { + Q_OBJECT + public: + + /** + * Constructor. + */ + DataTableAction(); + + /** + * Destructor. + */ + virtual ~DataTableAction(); + + /** + * 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(KSharedPtr<KoMacro::MacroItem> macroitem, const QString& name); + + public slots: + + /** + * Called if the @a Action should be executed within the + * defined @p context . + */ + virtual void activate(KSharedPtr<KoMacro::Context> context); + + }; +} + +#endif diff --git a/kexi/plugins/macros/kexiactions/executeaction.cpp b/kexi/plugins/macros/kexiactions/executeaction.cpp new file mode 100644 index 00000000..1e7f24a2 --- /dev/null +++ b/kexi/plugins/macros/kexiactions/executeaction.cpp @@ -0,0 +1,96 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2006 by Bernd Steindorff (bernd@itii.de) + * 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 "executeaction.h" + +#include <core/kexi.h> +#include <core/kexiproject.h> +#include <core/kexipartmanager.h> +#include <core/kexipartinfo.h> +#include <core/kexipart.h> +#include <core/keximainwindow.h> + +#include <klocale.h> + +using namespace KexiMacro; + +namespace KexiMacro { + static const QString OBJECT = "object"; + static const QString NAME = "name"; +} + +ExecuteAction::ExecuteAction() + : KexiAction("execute", i18n("Execute")) +{ + int conditions = ObjectVariable<ExecuteAction>::VisibleInNav | ObjectVariable<ExecuteAction>::Executable; + KSharedPtr<KoMacro::Variable> objvar = new ObjectVariable<ExecuteAction>(this, conditions); + setVariable(objvar); + + setVariable(KSharedPtr<KoMacro::Variable>( new ObjectNameVariable<ExecuteAction>(this, objvar->variant().toString()) )); +} + +ExecuteAction::~ExecuteAction() +{ +} + +bool ExecuteAction::notifyUpdated(KSharedPtr<KoMacro::MacroItem> macroitem, const QString& name) +{ + kdDebug()<<"ExecuteAction::notifyUpdated() name="<<name<<" macroitem.action="<<(macroitem->action() ? macroitem->action()->name() : "NOACTION")<<endl; + KSharedPtr<KoMacro::Variable> variable = macroitem->variable(name, false); + if(! variable) { + kdWarning()<<"ExecuteAction::notifyUpdated() No such variable="<<name<<" in macroitem."<<endl; + return false; + } + + variable->clearChildren(); + if(name == OBJECT) { + const QString objectvalue = macroitem->variant(OBJECT, true).toString(); // e.g. "macro" or "script" + const QString objectname = macroitem->variant(NAME, true).toString(); // e.g. "macro1" or "macro2" if objectvalue above is "macro" + macroitem->variable(NAME, true)->setChildren( + KoMacro::Variable::List() << KSharedPtr<KoMacro::Variable>(new ObjectNameVariable<ExecuteAction>(this, objectvalue, objectname)) ); + } + + return true; +} + +void ExecuteAction::activate(KSharedPtr<KoMacro::Context> context) +{ + if(! mainWin()->project()) { + kdWarning() << "ExecuteAction::activate(KSharedPtr<KoMacro::Context>) Invalid project" << endl; + return; + } + + const QString mimetype = QString("kexi/%1").arg( context->variable("object")->variant().toString() ); + const QString name = context->variable("name")->variant().toString(); + + KexiPart::Part* part = Kexi::partManager().partForMimeType(mimetype); + if(! part) { + throw KoMacro::Exception(i18n("No such mimetype \"%1\"").arg(mimetype)); + } + + KexiPart::Item* item = mainWin()->project()->item(part->info(), name); + if(! item) { + throw KoMacro::Exception(i18n("Failed to open part \"%1\" for mimetype \"%2\"").arg(name).arg(mimetype)); + } + + part->execute(item); +} + +//#include "executeaction.moc" diff --git a/kexi/plugins/macros/kexiactions/executeaction.h b/kexi/plugins/macros/kexiactions/executeaction.h new file mode 100644 index 00000000..17a8ca88 --- /dev/null +++ b/kexi/plugins/macros/kexiactions/executeaction.h @@ -0,0 +1,78 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2006 by Bernd Steindorff (bernd@itii.de) + * 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 KEXIMACRO_EXECUTEACTION_H +#define KEXIMACRO_EXECUTEACTION_H + +#include "kexiaction.h" + +class KexiMainWindow; + +namespace KoMacro { + class Context; +} + +namespace KexiMacro { + + /** + * The ExecuteAction class implements a @a KoMacro::Action + * to provide functionality to execute an object like + * e.g. a script or a macro. + */ + class ExecuteAction : public KexiAction + { + Q_OBJECT + public: + + /** + * Constructor. + */ + ExecuteAction(); + + /** + * Destructor. + */ + virtual ~ExecuteAction(); + + /** + * 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(KSharedPtr<KoMacro::MacroItem> macroitem, const QString& name); + + public slots: + + /** + * Called if the @a Action should be executed within the + * defined @p context . + */ + virtual void activate(KSharedPtr<KoMacro::Context> context); + + }; +} + +#endif diff --git a/kexi/plugins/macros/kexiactions/kexiaction.cpp b/kexi/plugins/macros/kexiactions/kexiaction.cpp new file mode 100644 index 00000000..521f8cfc --- /dev/null +++ b/kexi/plugins/macros/kexiactions/kexiaction.cpp @@ -0,0 +1,48 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2006 by Bernd Steindorff (bernd@itii.de) + * 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 "kexiaction.h" +#include "../lib/exception.h" + +#include <ksharedptr.h> + +using namespace KexiMacro; + +KexiAction::KexiAction(const QString& name, const QString& text) + : KoMacro::Action(name) +{ + m_mainwin = dynamic_cast< KexiMainWindow* >( KoMacro::Manager::self()->guiClient() ); + + if(! m_mainwin) { + throw KoMacro::Exception("Invalid KexiMainWindow instance."); + } + + // Set the caption this action has. + setText(text); +} + +KexiAction::~KexiAction() +{ +} + +KexiMainWindow* KexiAction::mainWin() const +{ + return m_mainwin; +} diff --git a/kexi/plugins/macros/kexiactions/kexiaction.h b/kexi/plugins/macros/kexiactions/kexiaction.h new file mode 100644 index 00000000..a61e2bc1 --- /dev/null +++ b/kexi/plugins/macros/kexiactions/kexiaction.h @@ -0,0 +1,75 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2006 by Bernd Steindorff (bernd@itii.de) + * 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 KEXIMACRO_KEXIACTION_H +#define KEXIMACRO_KEXIACTION_H + +#include "../lib/action.h" +#include "../lib/variable.h" +#include "../lib/macroitem.h" +#include "../lib/context.h" + +#include "objectvariable.h" +#include "objectnamevariable.h" + +#include <core/keximainwindow.h> + +namespace KexiMacro { + + /** + * Template class to offer common functionality needed by all + * @a KoMacro::Action implementations Kexi provides. + * + * All the actions Kexi provides are inherited from this + * template class. + */ + class KexiAction : public KoMacro::Action + { + public: + + /** + * Constructor. + * + * @param name The unique name the @a KoMacro::Action has. This + * name will be used to identify the action. + * @param text The i18n-caption text used for display purposes. + */ + KexiAction(const QString& name, const QString& text); + + /** + * Destructor. + */ + virtual ~KexiAction(); + + /** + * @return the @a KexiMainWindow instance we are + * running in. + */ + KexiMainWindow* mainWin() const; + + private: + + /// The @a KexiMainWindow instance. + KexiMainWindow* m_mainwin; + + }; +} + +#endif diff --git a/kexi/plugins/macros/kexiactions/kexivariable.h b/kexi/plugins/macros/kexiactions/kexivariable.h new file mode 100644 index 00000000..27dcc0ef --- /dev/null +++ b/kexi/plugins/macros/kexiactions/kexivariable.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2006 by Bernd Steindorff (bernd@itii.de) + * 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 KEXIMACRO_KEXIVARIABLE_H +#define KEXIMACRO_KEXIVARIABLE_H + +#include "../lib/manager.h" +#include "../lib/exception.h" +#include "../lib/action.h" +#include "../lib/variable.h" + +#include <ksharedptr.h> + +class KexiMainWindow; + +namespace KoMacro { + class Context; +} + +namespace KexiMacro { + + /** + * Template class to offer common functionality needed by all + * @a KoMacro::Variable implementations Kexi provides. + */ + template<class ACTIONIMPL> + class KexiVariable : public KoMacro::Variable + { + public: + + /** + * Constructor. + */ + KexiVariable(ACTIONIMPL* actionimpl, const QString& name, const QString& caption) + : KoMacro::Variable() + , m_actionimpl(actionimpl) + { + setName(name); + setText(caption); + } + + protected: + + /** + * @return the @a KexiAction implementation this @a KexiVariable + * is a child of. + */ + ACTIONIMPL* actionImpl() const + { + return m_actionimpl; + } + + private: + /// The parent @a KexiAction implementation. + ACTIONIMPL* m_actionimpl; + }; +} + +#endif diff --git a/kexi/plugins/macros/kexiactions/messageaction.cpp b/kexi/plugins/macros/kexiactions/messageaction.cpp new file mode 100644 index 00000000..1a4605cb --- /dev/null +++ b/kexi/plugins/macros/kexiactions/messageaction.cpp @@ -0,0 +1,50 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2006 by Bernd Steindorff (bernd@itii.de) + * 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 "messageaction.h" + +#include <core/keximainwindow.h> + +#include <klocale.h> +#include <kmessagebox.h> +#include <kdebug.h> + +using namespace KexiMacro; + +MessageAction::MessageAction() + : KexiAction("message", i18n("Message")) +{ + setVariable("caption", i18n("Caption"), QString("")); + setVariable("message", i18n("Message"), QString("")); +} + +MessageAction::~MessageAction() +{ +} + +void MessageAction::activate(KSharedPtr<KoMacro::Context> context) +{ + kdDebug() << "MessageAction::activate(KSharedPtr<Context>)" << endl; + const QString caption = context->variable("caption")->variant().toString(); + const QString message = context->variable("message")->variant().toString(); + KMessageBox::information(mainWin(), message, caption); +} + +//#include "messageaction.moc" diff --git a/kexi/plugins/macros/kexiactions/messageaction.h b/kexi/plugins/macros/kexiactions/messageaction.h new file mode 100644 index 00000000..543674bd --- /dev/null +++ b/kexi/plugins/macros/kexiactions/messageaction.h @@ -0,0 +1,66 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2006 by Bernd Steindorff (bernd@itii.de) + * 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 KEXIMACRO_MESSAGEACTION_H +#define KEXIMACRO_MESSAGEACTION_H + + +#include "kexiaction.h" + +class KexiMainWindow; + +namespace KoMacro { + class Context; +} + +namespace KexiMacro { + + /** + * The ExecuteObject class implements a @a KoMacro::Action + * to provide functionality to execute an object like + * e.g. a script or a macro. + */ + class MessageAction : public KexiAction + { + Q_OBJECT + public: + + /** + * Constructor. + */ + MessageAction(); + + /** + * Destructor. + */ + virtual ~MessageAction(); + + public slots: + + /** + * Called if the @a Action should be executed within the + * defined @param context . + */ + virtual void activate(KSharedPtr<KoMacro::Context> context); + + }; +} + +#endif diff --git a/kexi/plugins/macros/kexiactions/navigateaction.cpp b/kexi/plugins/macros/kexiactions/navigateaction.cpp new file mode 100644 index 00000000..d3fe551c --- /dev/null +++ b/kexi/plugins/macros/kexiactions/navigateaction.cpp @@ -0,0 +1,158 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2006 by Bernd Steindorff (bernd@itii.de) + * 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 "navigateaction.h" + +#include <core/kexi.h> +#include <core/kexiproject.h> +#include <core/kexipartmanager.h> +#include <core/kexipartinfo.h> +#include <core/kexipart.h> +#include <core/keximainwindow.h> +#include <core/kexidialogbase.h> + +#include <widget/kexidataawareview.h> +#include <widget/tableview/kexidataawareobjectiface.h> + +#include <klocale.h> +#include <kdebug.h> + +using namespace KexiMacro; + +namespace KexiMacro { + + template<class ACTIONIMPL> + class NavigateVariable : public KexiVariable<ACTIONIMPL> + { + public: + NavigateVariable(ACTIONIMPL* actionimpl) + : KexiVariable<ACTIONIMPL>(actionimpl, "record", i18n("Record")) + { + QStringList list; + list << "first" << "previous" << "next" << "last" << "goto"; + this->appendChild( KSharedPtr<KoMacro::Variable>( new KoMacro::Variable(list, "@list") ) ); + + /*TODO should this actions belong to navigate? maybe it would be more wise to have + such kind of functionality in an own e.g. "Modify" action to outline, that + we are manipulating the database that way... */ + //"add" << "save" << "delete" << "query" << "execute" << "cancel" << "reload" + + this->setVariant( list[0] ); + } + }; + +} + +NavigateAction::NavigateAction() + : KexiAction("navigate", i18n("Navigate")) +{ + KoMacro::Variable* navvar = new NavigateVariable<NavigateAction>(this); + setVariable(KSharedPtr<KoMacro::Variable>( navvar )); + + KoMacro::Variable* rowvar = new KexiVariable<NavigateAction>(this, "rownr", i18n("Row")); + rowvar->setVariant(0); + setVariable(KSharedPtr<KoMacro::Variable>(rowvar)); + + KoMacro::Variable* colvar = new KexiVariable<NavigateAction>(this, "colnr", i18n("Column")); + colvar->setVariant(0); + setVariable(KSharedPtr<KoMacro::Variable>(colvar)); +} + +NavigateAction::~NavigateAction() +{ +} + +bool NavigateAction::notifyUpdated(KSharedPtr<KoMacro::MacroItem> macroitem, const QString& name) +{ + kdDebug()<<"NavigateAction::notifyUpdated() name="<<name<<" macroitem.action="<<(macroitem->action() ? macroitem->action()->name() : "NOACTION")<<endl; + KSharedPtr<KoMacro::Variable> variable = macroitem->variable(name, false); + if(! variable) { + kdWarning()<<"NavigateAction::notifyUpdated() No such variable="<<name<<" in macroitem."<<endl; + return false; + } + + variable->clearChildren(); + if(name == "goto") { + const int rownr = macroitem->variant("rownr", true).toInt(); // e.g. "macro" or "script" + const int colnr = macroitem->variant("colnr", true).toInt(); // e.g. "macro1" or "macro2" if objectvalue above is "macro" + + macroitem->variable("rownr", true)->setChildren( + KoMacro::Variable::List() << KSharedPtr<KoMacro::Variable>(new KoMacro::Variable(rownr)) ); + macroitem->variable("colnr", true)->setChildren( + KoMacro::Variable::List() << KSharedPtr<KoMacro::Variable>(new KoMacro::Variable(colnr)) ); + } + + return true; +} + +void NavigateAction::activate(KSharedPtr<KoMacro::Context> context) +{ + KexiDialogBase* dialog = dynamic_cast<KexiDialogBase*>( mainWin()->activeWindow() ); + if(! dialog) { + throw KoMacro::Exception(i18n("No window active.")); + } + + KexiViewBase* view = dialog->selectedView(); + if(! view) { + throw KoMacro::Exception(i18n("No view selected for \"%1\".").arg(dialog->caption())); + } + + KexiDataAwareView* dbview = dynamic_cast<KexiDataAwareView*>( view ); + KexiDataAwareObjectInterface* dbobj = dbview ? dbview->dataAwareObject() : 0; + if(! dbview) { + throw KoMacro::Exception(i18n("The view for \"%1\" could not handle data.").arg(dialog->caption())); + } + + const QString record = context->variable("record")->variant().toString(); + if(record == "previous") { + dbobj->selectPrevRow(); + } + else if(record == "next") { + dbobj->selectNextRow(); + } + else if(record == "first") { + dbobj->selectFirstRow(); + } + else if(record == "last") { + dbobj->selectLastRow(); + } + else if(record == "goto") { + int rownr = context->variable("rownr")->variant().toInt() - 1; + int colnr = context->variable("colnr")->variant().toInt() - 1; + dbobj->setCursorPosition(rownr >= 0 ? rownr : dbobj->currentRow(), colnr >= 0 ? colnr : dbobj->currentColumn()); + } + else { + /* + virtual void selectNextPage(); //!< page down action + virtual void selectPrevPage(); //!< page up action + void deleteAllRows(); + void deleteCurrentRow(); + void deleteAndStartEditCurrentCell(); + void startEditOrToggleValue(); + bool acceptRowEdit(); + void cancelRowEdit(); + void sortAscending(); + void sortDescending(); + */ + throw KoMacro::Exception(i18n("Unknown record \"%1\" in view for \"%2\".").arg(record).arg(dialog->caption())); + } +} + +//#include "navigateaction.moc" diff --git a/kexi/plugins/macros/kexiactions/navigateaction.h b/kexi/plugins/macros/kexiactions/navigateaction.h new file mode 100644 index 00000000..f7f74f86 --- /dev/null +++ b/kexi/plugins/macros/kexiactions/navigateaction.h @@ -0,0 +1,78 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2006 by Bernd Steindorff (bernd@itii.de) + * 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 KEXIMACRO_NAVIGATEACTION_H +#define KEXIMACRO_NAVIGATEACTION_H + +#include "kexiaction.h" + +class KexiMainWindow; + +namespace KoMacro { + class Context; +} + +namespace KexiMacro { + + /** + * The NavigateAction class implements a @a KoMacro::Action + * to provide functionality to execute an object like + * e.g. a script or a macro. + */ + class NavigateAction : public KexiAction + { + Q_OBJECT + public: + + /** + * Constructor. + */ + NavigateAction(); + + /** + * Destructor. + */ + virtual ~NavigateAction(); + + /** + * 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(KSharedPtr<KoMacro::MacroItem> macroitem, const QString& name); + + public slots: + + /** + * Called if the @a Action should be executed within the + * defined @p context . + */ + virtual void activate(KSharedPtr<KoMacro::Context> context); + + }; +} + +#endif diff --git a/kexi/plugins/macros/kexiactions/objectnamevariable.h b/kexi/plugins/macros/kexiactions/objectnamevariable.h new file mode 100644 index 00000000..eeaabe04 --- /dev/null +++ b/kexi/plugins/macros/kexiactions/objectnamevariable.h @@ -0,0 +1,76 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2006 by Bernd Steindorff (bernd@itii.de) + * 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 KEXIMACRO_OBJECTNAMEVARIABLE_H +#define KEXIMACRO_OBJECTNAMEVARIABLE_H + +#include "../lib/variable.h" + +#include "kexivariable.h" + +#include <core/kexi.h> +#include <core/kexiproject.h> +#include <core/kexipartmanager.h> +#include <core/kexipartinfo.h> + +#include <klocale.h> + +namespace KexiMacro { + + /** + * The ViewVariable class provide a list of KexiPart::PartItem's + * supported by a KexiPart::Part as @a KoMacro::Variable . + */ + template<class ACTIONIMPL> + class ObjectNameVariable : public KexiVariable<ACTIONIMPL> + { + public: + ObjectNameVariable(ACTIONIMPL* actionimpl, const QString& objectname = QString::null, const QString& name = QString::null) + : KexiVariable<ACTIONIMPL>(actionimpl, "name", i18n("Name")) + { + if(! actionimpl->mainWin()->project()) + return; + + QStringList namelist; + KexiPart::Info* info = Kexi::partManager().infoForMimeType( QString("kexi/%1").arg(objectname) ); + if(info) { + KexiPart::ItemDict* items = actionimpl->mainWin()->project()->items(info); + if(items) + for(KexiPart::ItemDictIterator item_it = *items; item_it.current(); ++item_it) + namelist << item_it.current()->name(); + } + + if(namelist.count() <= 0) + namelist << ""; + + for(QStringList::Iterator it = namelist.begin(); it != namelist.end(); ++it) + this->appendChild( KSharedPtr<KoMacro::Variable>(new KoMacro::Variable(*it)) ); + + this->setVariant( (name.isNull() || ! namelist.contains(name)) ? namelist[0] : name ); + + kdDebug()<<"##################### KexiActions::ObjectNameVariable() objectname="<<objectname<<" name="<<name<<" value="<<this->variant()<<" children="<<namelist<<endl; + } + + virtual ~ObjectNameVariable() {} + }; + +} + +#endif diff --git a/kexi/plugins/macros/kexiactions/objectvariable.h b/kexi/plugins/macros/kexiactions/objectvariable.h new file mode 100644 index 00000000..b61f24e3 --- /dev/null +++ b/kexi/plugins/macros/kexiactions/objectvariable.h @@ -0,0 +1,87 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2006 by Bernd Steindorff (bernd@itii.de) + * 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 KEXIMACRO_OBJECTVARIABLE_H +#define KEXIMACRO_OBJECTVARIABLE_H + +#include "../lib/action.h" +#include "../lib/variable.h" + +#include "kexivariable.h" + +#include <core/kexi.h> +#include <core/kexiproject.h> +#include <core/kexipartmanager.h> +#include <core/kexipartinfo.h> + +#include <klocale.h> +#include <kdebug.h> + +namespace KexiMacro { + + /** + * The ObjectVariable class implements @a KoMacro::Variable to + * provide a variable list of Kexi-objects. Those Kexi-objects + * are KexiPart's like e.g. table, query, form or script. + */ + template<class ACTIONIMPL> + class ObjectVariable : public KexiVariable<ACTIONIMPL> + { + public: + + enum Conditions { + VisibleInNav = 1, + Executable = 2, + DataExport = 4 + }; + + ObjectVariable(ACTIONIMPL* actionimpl, int conditions = VisibleInNav, const QString& objectname = QString::null) + : KexiVariable<ACTIONIMPL>(actionimpl, "object", i18n("Object")) + { + KexiPart::PartInfoList* parts = Kexi::partManager().partInfoList(); + for(KexiPart::PartInfoListIterator it(*parts); it.current(); ++it) { + KexiPart::Info* info = it.current(); + + if(conditions & VisibleInNav && ! info->isVisibleInNavigator()) + continue; + if(conditions & Executable && ! info->isExecuteSupported()) + continue; + if(conditions & DataExport && ! info->isDataExportSupported()) + continue; + + const QString name = info->objectName(); //info->groupName(); + this->appendChild( KSharedPtr<KoMacro::Variable>(new KoMacro::Variable(name)) ); + } + + if(! objectname.isNull()) + this->setVariant( objectname ); + else if(this->children().count() > 0) + this->setVariant( this->children()[0]->variant() ); + else + this->setVariant( QString::null ); + + kdDebug()<<"##################### KexiActions::ObjectVariable() variant="<<this->variant()<<endl; + } + + }; + +} + +#endif diff --git a/kexi/plugins/macros/kexiactions/openaction.cpp b/kexi/plugins/macros/kexiactions/openaction.cpp new file mode 100644 index 00000000..b67041bb --- /dev/null +++ b/kexi/plugins/macros/kexiactions/openaction.cpp @@ -0,0 +1,154 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2006 by Bernd Steindorff (bernd@itii.de) + * 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 "openaction.h" + +#include <core/kexi.h> +#include <core/kexiproject.h> +#include <core/kexipartmanager.h> +#include <core/kexipartinfo.h> +#include <core/kexipart.h> +#include <core/keximainwindow.h> + +#include <klocale.h> + +using namespace KexiMacro; + +namespace KexiMacro { + + static const QString DATAVIEW = "data"; + static const QString DESIGNVIEW = "design"; + static const QString TEXTVIEW = "text"; + + static const QString OBJECT = "object"; + static const QString NAME = "name"; + static const QString VIEW = "view"; + + /** + * The ViewVariable class provide a list of viewmodes supported + * by a KexiPart::Part as @a KoMacro::Variable . + */ + template<class ACTIONIMPL> + class ViewVariable : public KexiVariable<ACTIONIMPL> + { + public: + ViewVariable(ACTIONIMPL* actionimpl, const QString& objectname = QString::null, const QString& viewname = QString::null) + : KexiVariable<ACTIONIMPL>(actionimpl, VIEW, i18n("View")) + { + QStringList namelist; + KexiPart::Part* part = Kexi::partManager().partForMimeType( QString("kexi/%1").arg(objectname) ); + if(part) { + int viewmodes = part->supportedViewModes(); + if(viewmodes & Kexi::DataViewMode) + namelist << DATAVIEW; + if(viewmodes & Kexi::DesignViewMode) + namelist << DESIGNVIEW; + if(viewmodes & Kexi::TextViewMode) + namelist << TEXTVIEW; + for(QStringList::Iterator it = namelist.begin(); it != namelist.end(); ++it) + this->children().append( KSharedPtr<KoMacro::Variable>(new KoMacro::Variable(*it)) ); + } + const QString n = + namelist.contains(viewname) + ? viewname + : namelist.count() > 0 ? namelist[0] : ""; + + this->setVariant(n); + } + }; + +} + +OpenAction::OpenAction() + : KexiAction("open", i18n("Open")) +{ + const int conditions = ObjectVariable<OpenAction>::VisibleInNav; + + KSharedPtr<KoMacro::Variable> objvar = new ObjectVariable<OpenAction>(this, conditions); + setVariable(objvar); + + setVariable(KSharedPtr<KoMacro::Variable>( new ObjectNameVariable<OpenAction>(this, objvar->variant().toString()) )); + setVariable(KSharedPtr<KoMacro::Variable>( new ViewVariable<OpenAction>(this, objvar->variant().toString()) )); +} + +OpenAction::~OpenAction() +{ +} + +bool OpenAction::notifyUpdated(KSharedPtr<KoMacro::MacroItem> macroitem, const QString& name) +{ + kdDebug()<<"OpenAction::notifyUpdated() name="<<name<<" macroitem.action="<<(macroitem->action() ? macroitem->action()->name() : "NOACTION")<<endl; + KSharedPtr<KoMacro::Variable> variable = macroitem->variable(name, false); + if(! variable) { + kdWarning()<<"OpenAction::notifyUpdated() No such variable="<<name<<" in macroitem."<<endl; + return false; + } + + variable->clearChildren(); + if(name == OBJECT) { + const QString objectvalue = macroitem->variant(OBJECT, true).toString(); // e.g. "table" or "query" + const QString objectname = macroitem->variant(NAME, true).toString(); // e.g. "table1" or "table2" if objectvalue above is "table" + const QString viewname = macroitem->variant(VIEW, true).toString(); // "data", "design" or "text" + + macroitem->variable(NAME, true)->setChildren( + KoMacro::Variable::List() << KSharedPtr<KoMacro::Variable>(new ObjectNameVariable<OpenAction>(this, objectvalue, objectname)) ); + macroitem->variable(VIEW, true)->setChildren( + KoMacro::Variable::List() << KSharedPtr<KoMacro::Variable>(new ViewVariable<OpenAction>(this, objectvalue, viewname)) ); + } + + return true; +} + +void OpenAction::activate(KSharedPtr<KoMacro::Context> context) +{ + if(! mainWin()->project()) { + throw KoMacro::Exception(i18n("No project loaded.")); + } + + const QString objectname = context->variable(OBJECT)->variant().toString(); + const QString name = context->variable(NAME)->variant().toString(); + KexiPart::Item* item = mainWin()->project()->itemForMimeType( QString("kexi/%1").arg(objectname).latin1(), name ); + if(! item) { + throw KoMacro::Exception(i18n("No such object \"%1.%2\".").arg(objectname).arg(name)); + } + + // Determinate the viewmode. + const QString view = context->variable(VIEW)->variant().toString(); + int viewmode; + if(view == DATAVIEW) + viewmode = Kexi::DataViewMode; + else if(view == DESIGNVIEW) + viewmode = Kexi::DesignViewMode; + else if(view == TEXTVIEW) + viewmode = Kexi::TextViewMode; + else { + throw KoMacro::Exception(i18n("No such viewmode \"%1\" in object \"%2.%3\".").arg(view).arg(objectname).arg(name)); + } + + // Try to open the object now. + bool openingCancelled; + if(! mainWin()->openObject(item, viewmode, openingCancelled)) { + if(! openingCancelled) { + throw KoMacro::Exception(i18n("Failed to open object \"%1.%2\".").arg(objectname).arg(name)); + } + } +} + +//#include "openaction.moc" diff --git a/kexi/plugins/macros/kexiactions/openaction.h b/kexi/plugins/macros/kexiactions/openaction.h new file mode 100644 index 00000000..b49f1238 --- /dev/null +++ b/kexi/plugins/macros/kexiactions/openaction.h @@ -0,0 +1,79 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2006 by Bernd Steindorff (bernd@itii.de) + * 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 KEXIMACRO_OPENACTION_H +#define KEXIMACRO_OPENACTION_H + +#include "kexiaction.h" + +class KexiMainWindow; + +namespace KoMacro { + class Context; +} + +namespace KexiMacro { + + /** + * The OpenAction class implements a @a KoMacro::Action + * to provide functionality to open any kind of Kexi + * object (e.g. table, query, form, script, ...). + */ + class OpenAction : public KexiAction + { + Q_OBJECT + + public: + + /** + * Constructor. + */ + OpenAction(); + + /** + * Destructor. + */ + virtual ~OpenAction(); + + /** + * 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(KSharedPtr<KoMacro::MacroItem> macroitem, const QString& name); + + public slots: + + /** + * Called if the @a Action should be executed within the + * defined @p context . + */ + virtual void activate(KSharedPtr<KoMacro::Context> context); + + }; +} + +#endif diff --git a/kexi/plugins/macros/kexipart/Makefile.am b/kexi/plugins/macros/kexipart/Makefile.am new file mode 100644 index 00000000..51cff0ea --- /dev/null +++ b/kexi/plugins/macros/kexipart/Makefile.am @@ -0,0 +1,32 @@ +include $(top_srcdir)/kexi/Makefile.global + +kde_module_LTLIBRARIES = kexihandler_macro.la + +kexihandler_macro_la_SOURCES = \ + keximacropart.cpp keximacroview.cpp keximacroproperty.cpp keximacrodesignview.cpp keximacrotextview.cpp keximacroerrorbase.ui keximacroerror.cpp + +kexihandler_macro_la_LDFLAGS = \ + $(KDE_PLUGIN) -module -no-undefined -Wnounresolved $(all_libraries) $(VER_INFO) + +kexihandler_macro_la_LIBADD = \ + ../kexiactions/libkeximacroactions.la \ + $(top_builddir)/kexi/core/libkexicore.la \ + $(top_builddir)/kexi/widget/libkexiextendedwidgets.la \ + $(top_builddir)/lib/koproperty/libkoproperty.la + +INCLUDES = \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/lib/kofficecore/ \ + -I$(top_srcdir)/kexi/core \ + -I$(top_srcdir)/kexi \ + -I$(top_srcdir)/kexi/widget \ + $(all_includes) + +servicesdir=$(kde_servicesdir)/kexi +services_DATA=keximacrohandler.desktop + +SUBDIRS = . +METASOURCES = AUTO + +noinst_HEADERS = \ + keximacropart.h keximacroview.h keximacrodesignview.h keximacrotextview.h keximacroerror.h diff --git a/kexi/plugins/macros/kexipart/keximacrodesignview.cpp b/kexi/plugins/macros/kexipart/keximacrodesignview.cpp new file mode 100644 index 00000000..030be0cb --- /dev/null +++ b/kexi/plugins/macros/kexipart/keximacrodesignview.cpp @@ -0,0 +1,497 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Sebastian Sauer <mail@dipe.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "keximacrodesignview.h" +#include "keximacroproperty.h" + +#include <qtimer.h> +#include <qdom.h> +#include <kdebug.h> + +#include <kexidialogbase.h> +#include <kexidb/connection.h> +#include <kexidb/error.h> + +#include <core/kexi.h> +#include <core/kexiproject.h> +#include <core/kexipartmanager.h> +#include <core/kexipartinfo.h> + +#include <widget/kexidatatable.h> +#include <widget/tableview/kexitableview.h> +#include <widget/tableview/kexitableviewdata.h> +#include <widget/tableview/kexitableitem.h> +#include <widget/tableview/kexidataawarepropertyset.h> + +#include <koproperty/set.h> +#include <koproperty/property.h> + +#include "../lib/macro.h" +#include "../lib/macroitem.h" +#include "../lib/xmlhandler.h" + +/// constants used to name columns instead of hardcoding indices +#define COLUMN_ID_ACTION 0 +#define COLUMN_ID_COMMENT 1 + +/** +* \internal d-pointer class to be more flexible on future extension of the +* functionality without to much risk to break the binary compatibility. +*/ +class KexiMacroDesignView::Private +{ + public: + + /** + * The view used to display the actions + * a \a Macro has. + */ + KexiDataTable* datatable; + + /** + * For convenience. The table view ( datatable->tableView() ). + */ + KexiTableView* tableview; + + /** + * The \a KexiTableViewData data-model for the + * \a KexiTableView above. + */ + KexiTableViewData* tabledata; + + /** + * The \a KexiDataAwarePropertySet is used to display + * properties an action provides in the propertyview. + */ + KexiDataAwarePropertySet* propertyset; + + /// Boolean flag to avoid infinite recursion. + bool reloadsProperties; + /// Boolean flag to avoid infinite recursion. + bool updatesProperties; + + /** + * Constructor. + * + * \param m The passed \a KoMacro::Manager instance our + * \a manager points to. + */ + Private() + : propertyset(0) + , reloadsProperties(false) + , updatesProperties(false) + { + } + + /** + * Destructor. + */ + ~Private() + { + delete propertyset; + } + +}; + +KexiMacroDesignView::KexiMacroDesignView(KexiMainWindow *mainwin, QWidget *parent, ::KoMacro::Macro* const macro) + : KexiMacroView(mainwin, parent, macro, "KexiMacroDesignView") + , d( new Private() ) +{ + // The table's data-model. + d->tabledata = new KexiTableViewData(); + d->tabledata->setSorting(-1); // disable sorting + + // Add the "Action" column. + KexiTableViewColumn* actioncol = new KexiTableViewColumn( + "action", // name/identifier + KexiDB::Field::Enum, // fieldtype + KexiDB::Field::NoConstraints, // constraints + KexiDB::Field::NoOptions, // options + 0, // length + 0, // precision + QVariant(), // default value + i18n("Action"), // caption + QString::null, // description + 0 // width + ); + d->tabledata->addColumn(actioncol); + + QValueVector<QString> items; + items.append(""); // empty means no action + + // Append the list of actions provided by Kexi. + QStringList actionnames = KoMacro::Manager::self()->actionNames(); + QStringList::ConstIterator it, end( actionnames.constEnd() ); + for( it = actionnames.constBegin(); it != end; ++it) { + KSharedPtr<KoMacro::Action> action = KoMacro::Manager::self()->action(*it); + items.append( action->text() ); + } + + actioncol->field()->setEnumHints(items); + + // Add the "Comment" column. + d->tabledata->addColumn( new KexiTableViewColumn( + "comment", // name/identifier + KexiDB::Field::Text, // fieldtype + KexiDB::Field::NoConstraints, // constraints + KexiDB::Field::NoOptions, // options + 0, // length + 0, // precision + QVariant(), // default value + i18n("Comment"), // caption + QString::null, // description + 0 // width + ) ); + + // Create the tableview. + QHBoxLayout* layout = new QHBoxLayout(this); + d->datatable = new KexiDataTable(mainWin(), this, "Macro KexiDataTable", false /*not db aware*/); + layout->addWidget(d->datatable); + d->tableview = d->datatable->tableView(); + d->tableview->setSpreadSheetMode(); + d->tableview->setColumnStretchEnabled( true, COLUMN_ID_COMMENT ); //last column occupies the rest of the area + + // We need to register our KexiMacroPropertyFactory to use our own + // KoProperty::Property implementation. + KexiMacroPropertyFactory::initFactory(); + + // Create the propertyset. + d->propertyset = new KexiDataAwarePropertySet(this, d->tableview); + + // Connect signals the KexiDataTable provides to local slots. + connect(d->tabledata, SIGNAL(aboutToChangeCell(KexiTableItem*,int,QVariant&,KexiDB::ResultInfo*)), + this, SLOT(beforeCellChanged(KexiTableItem*,int,QVariant&,KexiDB::ResultInfo*))); + connect(d->tabledata, SIGNAL(rowUpdated(KexiTableItem*)), + this, SLOT(rowUpdated(KexiTableItem*))); + connect(d->tabledata, SIGNAL(rowInserted(KexiTableItem*,uint,bool)), + this, SLOT(rowInserted(KexiTableItem*,uint,bool))); + connect(d->tabledata, SIGNAL(rowDeleted()), + this, SLOT(rowDeleted())); + + // Everything is ready. So, update the data now. + updateData(); + setDirty(false); +} + +KexiMacroDesignView::~KexiMacroDesignView() +{ + delete d; +} + +void KexiMacroDesignView::updateData() +{ + kdDebug() << "KexiMacroDesignView::updateData()" << endl; + + // Remove previous content of tabledata. + d->tabledata->deleteAllRows(); + // Remove old property sets. + d->propertyset->clear(); + + // Add some empty rows + for (int i=0; i<50; i++) { + d->tabledata->append( d->tabledata->createItem() ); + } + + // Set the MacroItem's + QStringList actionnames = KoMacro::Manager::self()->actionNames(); + KoMacro::MacroItem::List macroitems = macro()->items(); + KoMacro::MacroItem::List::ConstIterator it(macroitems.constBegin()), end(macroitems.constEnd()); + for(uint idx = 0; it != end; ++it, idx++) { + KexiTableItem* tableitem = d->tabledata->at(idx); + if(! tableitem) { + // If there exists no such item, add it. + tableitem = d->tabledata->createItem(); + d->tabledata->append(tableitem); + } + // Set the action-column. + KSharedPtr<KoMacro::Action> action = (*it)->action(); + if(action.data()) { + int i = actionnames.findIndex( action->name() ); + if(i >= 0) { + tableitem->at(COLUMN_ID_ACTION) = i + 1; + //setAction(tableitem, action->name()); + } + } + // Set the comment-column. + tableitem->at(COLUMN_ID_COMMENT) = (*it)->comment(); + } + + // set data for our spreadsheet: this will clear our sets + d->tableview->setData(d->tabledata); + + // Add the property sets. + it = macroitems.constBegin(); + for(uint idx = 0; it != end; ++it, idx++) { + updateProperties(idx, 0, *it); + } + + // work around a bug in the KexiTableView where we lose the stretch-setting... + d->tableview->setColumnStretchEnabled( true, COLUMN_ID_COMMENT ); //last column occupies the rest of the area + + propertySetReloaded(true); +} + +bool KexiMacroDesignView::loadData() +{ + if(! KexiMacroView::loadData()) { + return false; + } + updateData(); // update the tableview's data. + return true; +} + +KoProperty::Set* KexiMacroDesignView::propertySet() +{ + return d->propertyset->currentPropertySet(); +} + +void KexiMacroDesignView::beforeCellChanged(KexiTableItem* item, int colnum, QVariant& newvalue, KexiDB::ResultInfo* result) +{ + Q_UNUSED(result); + kdDebug() << "KexiMacroDesignView::beforeCellChanged() colnum=" << colnum << " newvalue=" << newvalue.toString() << endl; + + int rowindex = d->tabledata->findRef(item); + if(rowindex < 0) { + kdWarning() << "KexiMacroDesignView::beforeCellChanged() No such item" << endl; + return; + } + + // If the rowindex doesn't exists yet, we need to append new + // items till we are able to access the item we like to use. + for(int i = macro()->items().count(); i <= rowindex; i++) { + macro()->addItem( KSharedPtr<KoMacro::MacroItem>( new KoMacro::MacroItem() ) ); + } + + // Get the matching MacroItem. + KSharedPtr<KoMacro::MacroItem> macroitem = macro()->items()[rowindex]; + if(! macroitem.data()) { + kdWarning() << "KexiMacroDesignView::beforeCellChanged() Invalid item for rowindex=" << rowindex << endl; + return; + } + + // Handle the column that should be changed + switch(colnum) { + case COLUMN_ID_ACTION: { // The "Action" column + QString actionname; + bool ok; + int selectedindex = newvalue.toInt(&ok); + if(ok && selectedindex > 0) { + QStringList actionnames = KoMacro::Manager::self()->actionNames(); + actionname = actionnames[ selectedindex - 1 ]; // first item is empty + } + KSharedPtr<KoMacro::Action> action = KoMacro::Manager::self()->action(actionname); + macroitem->setAction(action); + updateProperties(d->propertyset->currentRow(), d->propertyset->currentPropertySet(), macroitem); + propertySetReloaded(true); + } break; + case COLUMN_ID_COMMENT: { // The "Comment" column + macroitem->setComment( newvalue.toString() ); + } break; + default: + kdWarning() << "KexiMacroDesignView::beforeCellChanged() No such column number " << colnum << endl; + return; + } + + setDirty(); +} + +void KexiMacroDesignView::rowUpdated(KexiTableItem* item) +{ + int rowindex = d->tabledata->findRef(item); + kdDebug() << "KexiMacroDesignView::rowUpdated() rowindex=" << rowindex << endl; + //propertySetSwitched(); + //propertySetReloaded(true); + //setDirty(); +} + +void KexiMacroDesignView::rowInserted(KexiTableItem*, uint row, bool) +{ + kdDebug() << "KexiMacroDesignView::rowInserted() rowindex=" << row << endl; + KoMacro::MacroItem::List& macroitems = macro()->items(); + + if(row < macroitems.count()) { + // If a new item was inserted, we need to insert a new item to our + // list of MacroItems too. If the new item was appended, we don't + // need to do anything yet cause the new item will be handled on + // beforeCellChanged() anyway. + kdDebug() << "KexiMacroDesignView::rowInserted() Inserting new MacroItem" << endl; + KSharedPtr<KoMacro::MacroItem> macroitem = KSharedPtr<KoMacro::MacroItem>( new KoMacro::MacroItem() ); + KoMacro::MacroItem::List::Iterator it = macroitems.at(row); + macroitems.insert(it, macroitem); + } +} + +void KexiMacroDesignView::rowDeleted() +{ + int rowindex = d->propertyset->currentRow(); + if(rowindex < 0) { + kdWarning() << "KexiMacroDesignView::rowDeleted() No such item" << endl; + return; + } + kdDebug() << "KexiMacroDesignView::rowDeleted() rowindex=" << rowindex << endl; + KoMacro::MacroItem::List& macroitems = macro()->items(); + macroitems.remove( macroitems.at(rowindex) ); +} + +bool KexiMacroDesignView::updateSet(KoProperty::Set* set, KSharedPtr<KoMacro::MacroItem> macroitem, const QString& variablename) +{ + kdDebug() << "KexiMacroDesignView::updateSet() variablename=" << variablename << endl; + KoProperty::Property* property = KexiMacroProperty::createProperty(macroitem, variablename); + if(! property) + return false; + set->addProperty(property); + return true; +} + +void KexiMacroDesignView::updateProperties(int row, KoProperty::Set* set, KSharedPtr<KoMacro::MacroItem> macroitem) +{ + kdDebug() << "KexiMacroDesignView::updateProperties() row=" << row << endl; + + if(row < 0 || d->updatesProperties) { + return; // ignore invalid rows and avoid infinite recursion. + } + + KSharedPtr<KoMacro::Action> action = macroitem->action(); + if(! action.data()) { + // don't display a propertyset if there is no action defined. + d->propertyset->remove(row); + return; // job done. + } + + d->updatesProperties = true; + + if(set) { + // we need to clear old data before adding the new content. + set->clear(); + } + else { + // if there exists no such propertyset yet, create one. + set = new KoProperty::Set(d->propertyset, action->name()); + d->propertyset->insert(row, set, true); + connect(set, SIGNAL(propertyChanged(KoProperty::Set&, KoProperty::Property&)), + this, SLOT(propertyChanged(KoProperty::Set&, KoProperty::Property&))); + } + + // The caption. + KoProperty::Property* prop = new KoProperty::Property("this:classString", action->text()); + prop->setVisible(false); + set->addProperty(prop); + + // Display the list of variables. + QStringList varnames = action->variableNames(); + for(QStringList::Iterator it = varnames.begin(); it != varnames.end(); ++it) { + if(updateSet(set, macroitem, *it)) { + KSharedPtr<KoMacro::Variable> variable = macroitem->variable(*it, true); + kdDebug()<<"KexiMacroDesignView::updateProperties() name=" << *it << " variable=" << variable->variant().toString() << endl; +#if 0 + macroitem->setVariable(*it, variable); +#endif + } + } + + d->updatesProperties = false; +} + +void KexiMacroDesignView::propertyChanged(KoProperty::Set& set, KoProperty::Property& property) +{ + Q_UNUSED(set); + kdDebug() << "!!!!! KexiMacroDesignView::propertyChanged() propertyname=" << property.name() << endl; + setDirty(); + + /* + if(d->reloadsProperties) // be sure to don't update properties if we are still on reloading. + return; + d->reloadsProperties = true; + + const int row = d->propertyset->currentRow(); + const QCString name = property.name(); + kdDebug() << "KexiMacroDesignView::propertyChanged() name=" << name << " row=" << row << endl; + + //TODO reload is only needed if something changed! + bool dirty = true; bool reload = true;//dirtyvarnames.count()>0; + + if(dirty || reload) { // Only reload properties if it's really needed. + setDirty(); + if(reload) { + // The MacroItem which should be changed. + KSharedPtr<KoMacro::MacroItem> macroitem = macro()->items()[row]; + // Update the properties. + updateProperties(row, &set, macroitem); + } + // It's needed to call the reload delayed cause in KoProperty::Editor + // QTimer::singleShot(10, this, SLOT(selectItemLater())); may lead + // to crashes if we are to fast. + QTimer::singleShot(50, this, SLOT(reloadPropertyLater())); + } + + d->reloadsProperties = false; + */ + + /* + QStringList dirtyvarnames = macroitem->setVariable(name, KSharedPtr<KoMacro::Variable>(pv)); + bool dirty = false; + bool reload = false; + for(QStringList::Iterator it = dirtyvarnames.begin(); it != dirtyvarnames.end(); ++it) { + KSharedPtr<KoMacro::Variable> variable = macroitem->variable(*it); + if(! variable.data()) { + kdDebug() << "KexiMacroDesignView::propertyChanged() name=" << name << " it=" << *it << " skipped cause such a variable is not known." << endl; + continue; + } + + if(! set.contains( (*it).latin1() )) { + // If there exist no such property yet, we need to add it. + if(updateSet(&set, macroitem, *it)) + reload = true; // we like to reload the whole set + continue; + } + + kdDebug() << "KexiMacroDesignView::propertyChanged() set existing property=" << *it << endl; + KoProperty::Property& p = set.property((*it).latin1()); + KoMacro::Variable::List children = variable->children(); + if(children.count() > 0) { + QStringList keys, names; + KoMacro::Variable::List::Iterator childit(children.begin()), childend(children.end()); + for(; childit != childend; ++childit) { + const QString s = (*childit)->variant().toString(); + keys << s; + names << s; + } + p.setListData( new KoProperty::Property::ListData(keys, names) ); + } + p.setValue(variable->variant()); + dirty = true; + } + + // If there are expired aka not any longer needed properties around, we + // need to reload the whole set. + for(KoProperty::Set::Iterator setit = set; setit.current(); ++setit) { + if(setit.currentKey() == name) continue; // don't remove ourself + if(setit.currentKey().left(5) == QCString("this:")) continue; // don't remove internal properties + if(setit.currentKey() == QCString("newrow")) continue; // also an internal used property + if(action.data() && action->hasVariable(setit.currentKey())) continue; // the property is still valid + reload = true; // we like to reload the whole set + } + */ +} + +void KexiMacroDesignView::reloadPropertyLater() +{ + propertySetReloaded(true); +} + +#include "keximacrodesignview.moc" + diff --git a/kexi/plugins/macros/kexipart/keximacrodesignview.h b/kexi/plugins/macros/kexipart/keximacrodesignview.h new file mode 100644 index 00000000..c3eca2d2 --- /dev/null +++ b/kexi/plugins/macros/kexipart/keximacrodesignview.h @@ -0,0 +1,129 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Sebastian Sauer <mail@dipe.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KEXIMACRODESIGNVIEW_H +#define KEXIMACRODESIGNVIEW_H + +#include "keximacroview.h" + +// Forward declarations. +namespace KoMacro { + class Action; + class Macro; + class MacroItem; +} +namespace KoProperty { + class Property; +} +namespace KexiDB { + class ResultInfo; +} +class KexiTableItem; + +/** + * The KexiScriptDesignView implements \a KexiMacroView to provide + * a GUI-Editor to edit a Macro. + */ +class KexiMacroDesignView : public KexiMacroView +{ + Q_OBJECT + public: + + /** + * Constructor. + * + * \param mainwin The \a KexiMainWindow instance this \a KexiViewBase + * belongs to. + * \param parent The parent widget this widget should be displayed in. + * \param macro The \a KoMacro::Macro instance this view is for. + */ + KexiMacroDesignView(KexiMainWindow *mainwin, QWidget *parent, ::KoMacro::Macro* const macro); + + /** + * Destructor. + */ + virtual ~KexiMacroDesignView(); + + /** + * Load the data from XML source and fill the internally + * used \a KoMacro::Macro instance. + */ + virtual bool loadData(); + + /** + * \return the \a KoProperty::Set properties this view provides. + */ + virtual KoProperty::Set* propertySet(); + + private slots: + + /** + * Called before a cell changed in the internaly used + * \a KexiTableView . + */ + void beforeCellChanged(KexiTableItem*, int, QVariant&, KexiDB::ResultInfo*); + + /** + * Called if the passed \p item got updated. + */ + void rowUpdated(KexiTableItem* item); + + /** + * Called if a row got deleted. + */ + void rowDeleted(); + + /** + * Called if a row got inserted. + */ + void rowInserted(KexiTableItem* item, uint row, bool repaint); + + /** + * Called if a property in the \a KoProperty got changed. + */ + void propertyChanged(KoProperty::Set&, KoProperty::Property&); + + /** + * Reloads the propertyset delayed. + */ + void reloadPropertyLater(); + + private: + /// \internal d-pointer class. + class Private; + /// \internal d-pointer instance. + Private* const d; + + /** + * Update the table's data. + */ + void updateData(); + + /** + * Update the \a KoProperty::Set set with the passed \a KoMacro::MacroItem + * \p item and the variablename \p variablename . + */ + bool updateSet(KoProperty::Set* set, KSharedPtr<KoMacro::MacroItem> item, const QString& variablename); + + /** + * Update the properties of the \a KoProperty::Set \p set at + * row-number \p row with the \a KoMacro::MacroItem \p macroitem . + */ + void updateProperties(int row, KoProperty::Set* set, KSharedPtr<KoMacro::MacroItem> macroitem); +}; + +#endif diff --git a/kexi/plugins/macros/kexipart/keximacroerror.cpp b/kexi/plugins/macros/kexipart/keximacroerror.cpp new file mode 100644 index 00000000..15f4df3f --- /dev/null +++ b/kexi/plugins/macros/kexipart/keximacroerror.cpp @@ -0,0 +1,130 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Tobi Krebs (tobi.krebs@gmail.com) + * copyright (C) 2006 by Bernd Steindorff (bernd@itii.de) + * copyright (C) 2006 by Sascha Kupper (kusato@kfnv.de) + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * + * 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 "keximacroerror.h" + +#include <core/kexiproject.h> +#include <core/keximainwindow.h> + +#include <qtimer.h> + +/** +* \internal d-pointer class to be more flexible on future extension of the +* functionality without to much risk to break the binary compatibility. +*/ +class KexiMacroError::Private +{ + public: + KexiMainWindow* const mainwin; + KSharedPtr<KoMacro::Context> context; + + Private(KexiMainWindow* const m, KoMacro::Context* const c) + : mainwin(m) + , context(c) + { + } +}; + +KexiMacroError::KexiMacroError(KexiMainWindow* mainwin, KSharedPtr<KoMacro::Context> context) + : KexiMacroErrorBase(mainwin, "KexiMacroError" , /*WFlags*/ Qt::WDestructiveClose) + , d(new Private(mainwin, context)) +{ + //setText(i18n("Execution failed")); //caption + //errortext, errorlist, continuebtn,cancelbtn, designerbtn + + KoMacro::Exception* exception = context->exception(); + + iconlbl->setPixmap(KGlobal::instance()->iconLoader()->loadIcon("messagebox_critical", KIcon::Small, 32)); + errorlbl->setText(i18n("<qt>Failed to execute the macro \"%1\".<br>%2</qt>").arg( context->macro()->name() ).arg( exception->errorMessage() )); + + int i = 1; + KoMacro::MacroItem::List items = context->macro()->items(); + for (KoMacro::MacroItem::List::ConstIterator mit = items.begin(); mit != items.end(); mit++) + { + KListViewItem* listviewitem = new KListViewItem(errorlist); + listviewitem->setText(0,QString("%1").arg(i++)); + listviewitem->setText(1,i18n("Action")); + KSharedPtr<KoMacro::MacroItem> macroitem = *mit; + + if (macroitem != 0 && macroitem->action() != 0) + { + listviewitem->setText(2,macroitem->action()->name()); + } + + if(macroitem == context->macroItem()) + { + listviewitem->setOpen(true); + listviewitem->setSelected(true); + errorlist->setSelected(listviewitem, true); + errorlist->ensureItemVisible(listviewitem); + } + + KoMacro::Variable::Map variables = macroitem->variables(); + KoMacro::Variable::Map::ConstIterator vit; + for ( vit = variables.begin(); vit != variables.end(); ++vit ) { + KListViewItem* child = new KListViewItem(listviewitem); + child->setText(1,vit.key()); + child->setText(2,vit.data()->toString()); + } + } + + connect(designerbtn, SIGNAL(clicked()), this, SLOT(designbtnClicked())); + connect(continuebtn, SIGNAL(clicked()), this, SLOT(continuebtnClicked())); +} + +KexiMacroError::~KexiMacroError() +{ + delete d; +} + +void KexiMacroError::designbtnClicked() +{ + if(! d->mainwin->project()) { + kdWarning() << QString("KexiMacroError::designbtnClicked(): No project open.") << endl; + return; + } + + // We need to determinate the KexiPart::Item which should be opened. + KSharedPtr<KoMacro::Macro> macro = d->context->macro(); + const QString name = macro->name(); + KexiPart::Item* item = d->mainwin->project()->itemForMimeType("kexi/macro", name); + if(! item) { + kdWarning() << QString("KexiMacroError::designbtnClicked(): No such macro \"%1\"").arg(name) << endl; + return; + } + + // Try to open the KexiPart::Item now. + bool openingCancelled; + if(! d->mainwin->openObject(item, Kexi::DesignViewMode, openingCancelled)) { + if(! openingCancelled) { + kdWarning() << QString("KexiMacroError::designbtnClicked(): Open macro \"%1\" in designview failed.").arg(name) << endl; + return; + } + } + + close(); +} + +void KexiMacroError::continuebtnClicked() +{ + QTimer::singleShot(200, d->context, SLOT(activateNext())); + close(); +} diff --git a/kexi/plugins/macros/kexipart/keximacroerror.h b/kexi/plugins/macros/kexipart/keximacroerror.h new file mode 100644 index 00000000..641859b7 --- /dev/null +++ b/kexi/plugins/macros/kexipart/keximacroerror.h @@ -0,0 +1,89 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Tobi Krebs (tobi.krebs@gmail.com) + * copyright (C) 2006 by Bernd Steindorff (bernd@itii.de) + * copyright (C) 2006 by Sascha Kupper (kusato@kfnv.de) + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * + * 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 KEXIMACROERROR_H +#define KEXIMACROERROR_H + +#include <qwidget.h> +#include <qlabel.h> +#include <qpushbutton.h> + +#include <klistview.h> +#include <klocale.h> +#include <kiconloader.h> +#include <kglobal.h> +#include <kdebug.h> + +#include "../lib/context.h" +#include "../lib/exception.h" +#include "../lib/macro.h" +#include "../lib/macroitem.h" + +#include "keximacroerrorbase.h" + +// Forward-declarations. +class KexiMainWindow; + +/** +* An error dialog used to displayed more detailed informations about +* a @a KoMacro::Exception that got thrown within a @a KoMacro::Context +* during execution. +*/ +class KexiMacroError : public KexiMacroErrorBase +{ + Q_OBJECT + + public: + + /** + * Constructor. + * + * @param mainwin The parent @a KexiMainWindow instance. + * @param context The @a KoMacro::Context where the error happened. + */ + KexiMacroError(KexiMainWindow* mainwin, KSharedPtr<KoMacro::Context> context); + + /** + * Destructor. + */ + virtual ~KexiMacroError(); + + private slots: + + /** + * Called if the "Open Macrodesigner"-Button is clicked. + */ + void designbtnClicked(); + + /** + * Called if the "continue"-Button is clicked. + */ + void continuebtnClicked(); + + private: + /// \internal d-pointer class. + class Private; + /// \internal d-pointer instance. + Private* const d; + +}; + +#endif diff --git a/kexi/plugins/macros/kexipart/keximacroerrorbase.ui b/kexi/plugins/macros/kexipart/keximacroerrorbase.ui new file mode 100644 index 00000000..74e47cfc --- /dev/null +++ b/kexi/plugins/macros/kexipart/keximacroerrorbase.ui @@ -0,0 +1,213 @@ +<!DOCTYPE UI><UI version="3.3" stdsetdef="1"> +<class>KexiMacroErrorBase</class> +<widget class="QDialog"> + <property name="name"> + <cstring>KexiMacroErrorBase</cstring> + </property> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>492</width> + <height>424</height> + </rect> + </property> + <property name="caption"> + <string>Error</string> + </property> + <property name="sizeGripEnabled"> + <bool>true</bool> + </property> + <property name="modal"> + <bool>true</bool> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout4</cstring> + </property> + <vbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout8</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QLabel"> + <property name="name"> + <cstring>iconlbl</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>0</hsizetype> + <vsizetype>0</vsizetype> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>48</width> + <height>48</height> + </size> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>AlignVCenter|AlignLeft</set> + </property> + </widget> + <widget class="QLabel"> + <property name="name"> + <cstring>errorlbl</cstring> + </property> + <property name="sizePolicy"> + <sizepolicy> + <hsizetype>5</hsizetype> + <vsizetype>1</vsizetype> + <horstretch>1</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="frameShape"> + <enum>NoFrame</enum> + </property> + <property name="text"> + <string></string> + </property> + <property name="alignment"> + <set>WordBreak|AlignVCenter</set> + </property> + </widget> + </hbox> + </widget> + <widget class="KListView"> + <column> + <property name="text"> + <string>No</string> + </property> + <property name="clickable"> + <bool>false</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Name</string> + </property> + <property name="clickable"> + <bool>false</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <column> + <property name="text"> + <string>Value</string> + </property> + <property name="clickable"> + <bool>false</bool> + </property> + <property name="resizable"> + <bool>true</bool> + </property> + </column> + <property name="name"> + <cstring>errorlist</cstring> + </property> + <property name="allColumnsShowFocus"> + <bool>true</bool> + </property> + <property name="rootIsDecorated"> + <bool>true</bool> + </property> + <property name="resizeMode"> + <enum>LastColumn</enum> + </property> + <property name="fullWidth"> + <bool>true</bool> + </property> + <property name="itemsMovable"> + <bool>false</bool> + </property> + <property name="autoOpen"> + <bool>false</bool> + </property> + <property name="tooltipColumn"> + <number>1</number> + </property> + </widget> + <widget class="QLayoutWidget"> + <property name="name"> + <cstring>layout1</cstring> + </property> + <hbox> + <property name="name"> + <cstring>unnamed</cstring> + </property> + <widget class="QPushButton"> + <property name="name"> + <cstring>designerbtn</cstring> + </property> + <property name="text"> + <string>Open in design view</string> + </property> + <property name="accel"> + <string></string> + </property> + <property name="autoDefault"> + <bool>true</bool> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>continuebtn</cstring> + </property> + <property name="text"> + <string>Continue</string> + </property> + </widget> + <widget class="QPushButton"> + <property name="name"> + <cstring>cancelbtn</cstring> + </property> + <property name="text"> + <string>Abort</string> + </property> + </widget> + </hbox> + </widget> + </vbox> + </widget> + </vbox> +</widget> +<customwidgets> +</customwidgets> +<connections> + <connection> + <sender>cancelbtn</sender> + <signal>clicked()</signal> + <receiver>KexiMacroErrorBase</receiver> + <slot>close()</slot> + </connection> +</connections> +<layoutdefaults spacing="6" margin="11"/> +<includehints> + <includehint>klistview.h</includehint> +</includehints> +</UI> diff --git a/kexi/plugins/macros/kexipart/keximacrohandler.desktop b/kexi/plugins/macros/kexipart/keximacrohandler.desktop new file mode 100644 index 00000000..c08a7b2a --- /dev/null +++ b/kexi/plugins/macros/kexipart/keximacrohandler.desktop @@ -0,0 +1,81 @@ +[Desktop Entry] +Type=Service +ServiceTypes=Kexi/Handler + +GenericName=Macros +GenericName[bg]=Макроси +GenericName[br]=Makroù +GenericName[da]=Makroer +GenericName[de]=Makros +GenericName[el]=Μακροεντολές +GenericName[eo]=Makrooj +GenericName[et]=Makrod +GenericName[fa]=کلاندستورها +GenericName[fy]=Macro's +GenericName[ga]=Macraí +GenericName[hr]=Makroi +GenericName[hu]=Makrók +GenericName[it]=Macro +GenericName[ja]=マクロ +GenericName[km]=ម៉ាក្រូ +GenericName[lv]=Makross +GenericName[nb]=Makroer +GenericName[nds]=Makros +GenericName[ne]=म्याक्रोस +GenericName[nl]=Macro's +GenericName[pl]=Makra +GenericName[ru]=Макросы +GenericName[se]=Makroat +GenericName[sk]=Makrá +GenericName[sl]=Makri +GenericName[sr]=Макрои +GenericName[sr@Latn]=Makroi +GenericName[sv]=Makron +GenericName[uk]=Макроси +GenericName[uz]=Makros +GenericName[uz@cyrillic]=Макрос +GenericName[zh_TW]=巨集 + +Name=Macros +Name[bg]=Макроси +Name[br]=Makroù +Name[da]=Makroer +Name[de]=Makros +Name[el]=Μακροεντολές +Name[eo]=Makrooj +Name[et]=Makrod +Name[fa]=کلاندستورها +Name[fy]=Macro's +Name[ga]=Macraí +Name[hr]=Makroi +Name[hu]=Makrók +Name[it]=Macro +Name[ja]=マクロ +Name[km]=ម៉ាក្រូ +Name[lv]=Makross +Name[nb]=Makroer +Name[nds]=Makros +Name[ne]=म्याक्रोस +Name[nl]=Macro's +Name[pl]=Makra +Name[ru]=Макросы +Name[se]=Makroat +Name[sk]=Makrá +Name[sl]=Makri +Name[sr]=Макрои +Name[sr@Latn]=Makroi +Name[sv]=Makron +Name[uk]=Макроси +Name[uz]=Makros +Name[uz@cyrillic]=Макрос +Name[zh_TW]=巨集 + +X-KDE-Library=kexihandler_macro +X-KDE-ParentApp=kexi +X-Kexi-PartVersion=2 +X-Kexi-TypeName=macro +X-Kexi-TypeMime=kexi/macro +X-Kexi-ItemIcon=macro +X-Kexi-SupportsDataExport=false +X-Kexi-SupportsPrinting=false +X-Kexi-SupportsExecution=true diff --git a/kexi/plugins/macros/kexipart/keximacropart.cpp b/kexi/plugins/macros/kexipart/keximacropart.cpp new file mode 100644 index 00000000..c4f020e4 --- /dev/null +++ b/kexi/plugins/macros/kexipart/keximacropart.cpp @@ -0,0 +1,172 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Sebastian Sauer <mail@dipe.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "keximacropart.h" + +#include "keximacroview.h" +#include "keximacrodesignview.h" +#include "keximacrotextview.h" + +//#include "kexiviewbase.h" +//#include "keximainwindow.h" +//#include "kexiproject.h" + +#include <qdom.h> +#include <qstringlist.h> +#include <kgenericfactory.h> +#include <kexipartitem.h> +//#include <kxmlguiclient.h> +//#include <kexidialogbase.h> +//#include <kconfig.h> +//#include <kdebug.h> + +#include "../lib/manager.h" +#include "../lib/macro.h" +#include "../lib/macroitem.h" +#include "../lib/action.h" + +#include "../kexiactions/openaction.h" +#include "../kexiactions/executeaction.h" +#include "../kexiactions/navigateaction.h" +#include "../kexiactions/messageaction.h" +#include "../kexiactions/datatableaction.h" + +/** +* \internal d-pointer class to be more flexible on future extension of the +* functionality without to much risk to break the binary compatibility. +*/ +class KexiMacroPart::Private +{ + public: +}; + +KexiMacroPart::KexiMacroPart(QObject *parent, const char *name, const QStringList &l) + : KexiPart::Part(parent, name, l) + , d( new Private() ) +{ + //kdDebug() << "KexiMacroPart::KexiMacroPart() Ctor" << endl; + + //registered ID + m_registeredPartID = (int)KexiPart::MacroObjectType; + + //name of the instance. + m_names["instanceName"] + = i18n("Translate this word using only lowercase alphanumeric characters (a..z, 0..9). " + "Use '_' character instead of spaces. First character should be a..z character. " + "If you cannot use latin characters in your language, use english word.", + "macro"); + + //describing caption + m_names["instanceCaption"] = i18n("Macro"); + + //supported viewmodes + m_supportedViewModes = Kexi::DesignViewMode | Kexi::TextViewMode; +} + +KexiMacroPart::~KexiMacroPart() +{ + //kdDebug() << "KexiMacroPart::~KexiMacroPart() Dtor" << endl; + delete d; +} + +bool KexiMacroPart::execute(KexiPart::Item* item, QObject* sender) +{ + KexiDialogBase* dialog = new KexiDialogBase(m_mainWin); + dialog->setId( item->identifier() ); + KexiMacroView* view = dynamic_cast<KexiMacroView*>( createView(dialog, dialog, *item, Kexi::DataViewMode) ); + if(! view) { + kdWarning() << "KexiMacroPart::execute() Failed to create a view." << endl; + return false; + } + + if(! view->macro().data()) { + kdWarning() << "KexiMacroPart::execute() No such item " << item->name() << endl; + return false; + } + + kdDebug() << "KexiMacroPart::execute() itemname=" << item->name() << endl; + view->loadData(); + view->execute(sender); + view->deleteLater(); + return true; +} + +void KexiMacroPart::initPartActions() +{ + //kdDebug() << "KexiMacroPart::initPartActions()" << endl; + + KoMacro::Manager::init(m_mainWin); + new KexiMacro::OpenAction; + new KexiMacro::ExecuteAction; + new KexiMacro::DataTableAction; + new KexiMacro::NavigateAction; + new KexiMacro::MessageAction; +} + +void KexiMacroPart::initInstanceActions() +{ + //kdDebug() << "KexiMacroPart::initInstanceActions()" << endl; + //createSharedAction(Kexi::DesignViewMode, i18n("Execute Macro"), "exec", 0, "data_execute"); +} + +KexiViewBase* KexiMacroPart::createView(QWidget* parent, KexiDialogBase* dialog, KexiPart::Item& item, int viewMode, QMap<QString,QString>*) +{ + const QString itemname = item.name(); + //kdDebug() << "KexiMacroPart::createView() itemname=" << itemname << endl; + + if(! itemname.isNull()) { + KSharedPtr<KoMacro::Macro> macro = ::KoMacro::Manager::self()->getMacro(itemname); + if(! macro) { + // If we don't have a macro with that name yet, create one. + macro = ::KoMacro::Manager::self()->createMacro(itemname); + // and remember the new macro for later usage. + ::KoMacro::Manager::self()->addMacro(itemname, macro); + } + + KexiMainWindow *win = dialog->mainWin(); + if(win && win->project() && win->project()->dbConnection()) { + if(viewMode == Kexi::DesignViewMode) { + return new KexiMacroDesignView(win, parent, macro); + } + if(viewMode == Kexi::TextViewMode) { + return new KexiMacroTextView(win, parent, macro); + } + if(viewMode == Kexi::DataViewMode) { + // Called if the macro should be executed. + return new KexiMacroView(win, parent, macro); + } + } + } + + //kdDebug() << "KexiMacroPart::createView() No view available." << endl; + return 0; +} + +QString KexiMacroPart::i18nMessage(const QCString& englishMessage) const +{ + if(englishMessage=="Design of object \"%1\" has been modified.") { + return i18n("Design of macro \"%1\" has been modified."); + } + if(englishMessage=="Object \"%1\" already exists.") { + return i18n("Macro \"%1\" already exists."); + } + return englishMessage; +} + +K_EXPORT_COMPONENT_FACTORY( kexihandler_macro, KGenericFactory<KexiMacroPart>("kexihandler_macro") ) + +#include "keximacropart.moc" diff --git a/kexi/plugins/macros/kexipart/keximacropart.h b/kexi/plugins/macros/kexipart/keximacropart.h new file mode 100644 index 00000000..8d2d7af2 --- /dev/null +++ b/kexi/plugins/macros/kexipart/keximacropart.h @@ -0,0 +1,95 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Sebastian Sauer <mail@dipe.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KEXIMACROPART_H +#define KEXIMACROPART_H + +//#include <qcstring.h> + +#include <kexi.h> +#include <kexipart.h> +#include <kexidialogbase.h> + +/** + * Kexi Macro Plugin. + */ +class KexiMacroPart : public KexiPart::Part +{ + Q_OBJECT + + public: + + /** + * Constructor. + * + * \param parent The parent QObject this part is child of. + * \param name The name this part has. + * \param args Optional list of arguments passed to this part. + */ + KexiMacroPart(QObject *parent, const char *name, const QStringList& args); + + /** + * Destructor. + */ + virtual ~KexiMacroPart(); + + /** + * Implementation of the KexiPart::Part::action method used to + * provide scripts as KAction's to the outside world. + */ + virtual bool execute(KexiPart::Item* item, QObject* sender = 0); + + /** + * \return the i18n message for the passed \p englishMessage string. + */ + virtual QString i18nMessage(const QCString& englishMessage) const; + + protected: + + /** + * Create a new view. + * + * \param parent The parent QWidget the new view is displayed in. + * \param dialog The \a KexiDialogBase the view is child of. + * \param item The \a KexiPart::Item this view is for. + * \param viewMode The viewmode we like to have a view for. + */ + virtual KexiViewBase* createView(QWidget *parent, + KexiDialogBase* dialog, + KexiPart::Item& item, + int viewMode = Kexi::DesignViewMode, + QMap<QString,QString>* staticObjectArgs = 0); + + /** + * Initialize the part's actions. + */ + virtual void initPartActions(); + + /** + * Initialize the instance actions. + */ + virtual void initInstanceActions(); + + private: + /// \internal d-pointer class. + class Private; + /// \internal d-pointer instance. + Private* const d; +}; + +#endif + diff --git a/kexi/plugins/macros/kexipart/keximacroproperty.cpp b/kexi/plugins/macros/kexipart/keximacroproperty.cpp new file mode 100644 index 00000000..2fdafd28 --- /dev/null +++ b/kexi/plugins/macros/kexipart/keximacroproperty.cpp @@ -0,0 +1,626 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Sebastian Sauer <mail@dipe.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "keximacroproperty.h" + +#include <qlayout.h> +#include <qlineedit.h> +#include <qlistbox.h> +#include <qpainter.h> + +#include <kcombobox.h> +#include <kpushbutton.h> +#include <klocale.h> +#include <kiconloader.h> +#include <kdebug.h> + +#include "../lib/variable.h" +#include "../lib/macroitem.h" + +#define KEXIMACRO_PROPERTYEDITORTYPE 5682 + +/************************************************************* + * KexiMacroProperty + */ + +/** +* @internal d-pointer class to be more flexible on future extension of the +* functionality without to much risk to break the binary compatibility. +*/ +class KexiMacroProperty::Private +{ + public: + /** The @a KoMacro::MacroItem the custom property uses + internal. Together with the name we are able to identify + the used variable at runtime. */ + KSharedPtr<KoMacro::MacroItem> macroitem; + /** The name the variable @a KoMacro::Variable is known + as in the @a KoMacro::MacroItem defined above. */ + QString name; +}; + +KexiMacroProperty::KexiMacroProperty(KoProperty::Property* parent, KSharedPtr<KoMacro::MacroItem> macroitem, const QString& name) + : KoProperty::CustomProperty(parent) + , d( new Private() ) +{ + d->macroitem = macroitem; + d->name = name; + init(); +} + +KexiMacroProperty::~KexiMacroProperty() +{ + delete d; +} + +void KexiMacroProperty::init() +{ + Q_ASSERT( d->macroitem != 0 ); + //kdDebug() << "--------- KexiMacroProperty::set() macroitem=" << d->macroitem->name() << " name=" << d->name << endl; + + KSharedPtr<KoMacro::Action> action = d->macroitem->action(); + KSharedPtr<KoMacro::Variable> actionvariable = action->variable(d->name); + if(! actionvariable.data()) { + kdDebug() << "KexiMacroProperty::createProperty() Skipped cause there exists no such action=" << d->name << endl; + return; + } + + KSharedPtr<KoMacro::Variable> variable = d->macroitem->variable(d->name, true/*checkaction*/); + if(! variable.data()) { + kdDebug() << "KexiMacroProperty::createProperty() Skipped cause there exists no such variable=" << d->name << endl; + return; + } + + //TESTCASE!!!!!!!!!!!!!!!!!!!!!! + //if(! variable->isEnabled()) qFatal( QString("############## VARIABLE=%1").arg(variable->name()).latin1() ); + + Q_ASSERT(! d->name.isNull()); + m_property->setName( d->name.latin1() ); + m_property->setCaption( actionvariable->text() ); + m_property->setDescription( action->comment() ); + m_property->setValue( variable->variant(), true ); + m_property->setType( KEXIMACRO_PROPERTYEDITORTYPE ); // use our own propertytype +} + +KoProperty::Property* KexiMacroProperty::parentProperty() const +{ + return m_property; +} + +void KexiMacroProperty::setValue(const QVariant &value, bool rememberOldValue) +{ + Q_UNUSED(rememberOldValue); + kdDebug()<<"KexiMacroProperty::setValue name="<<d->name<<" value="<<value<<" rememberOldValue="<<rememberOldValue<<endl; + if(! d->macroitem->setVariant(d->name, value)) { // takes care of the type-conversation + kdDebug()<<"KexiMacroProperty::setValue Update failed !!!"<<endl; + return; + } + + // m_property->setValue() does check if the value changed by using + // this-value() and cause we already set it above, m_property->setValue() + // will be aborted. Well, we don't touch the properties value and handle + // it all via our CustomProperty class anyway. So, just ignore the property. + //m_property->setValue(this->value(), rememberOldValue, false/*useCustomProperty*/); + + emit valueChanged(); +} + +QVariant KexiMacroProperty::value() const +{ + KSharedPtr<KoMacro::Variable> variable = d->macroitem->variable(d->name, true); + Q_ASSERT( variable.data() != 0 ); + return variable.data() ? variable->variant() : QVariant(); +} + +bool KexiMacroProperty::handleValue() const +{ + return true; // we handle getting and setting of values and don't need KoProperty::Property for it. +} + +KSharedPtr<KoMacro::MacroItem> KexiMacroProperty::macroItem() const +{ + return d->macroitem; +} + +QString KexiMacroProperty::name() const +{ + return d->name; +} + +KSharedPtr<KoMacro::Variable> KexiMacroProperty::variable() const +{ + return d->macroitem->variable(d->name, true/*checkaction*/); +} + +KoProperty::Property* KexiMacroProperty::createProperty(KSharedPtr<KoMacro::MacroItem> macroitem, const QString& name) +{ + KoProperty::Property* property = new KoProperty::Property(); + KexiMacroProperty* customproperty = new KexiMacroProperty(property, macroitem, name); + if(! customproperty->variable().data()) { + kdWarning() << "KexiMacroProperty::createProperty() No such variable" << endl; + delete customproperty; customproperty = 0; + delete property; property = 0; + return 0; + } + property->setCustomProperty(customproperty); + return property; +} + +/************************************************************* + * KexiMacroPropertyFactory + */ + +KexiMacroPropertyFactory::KexiMacroPropertyFactory(QObject* parent) + : KoProperty::CustomPropertyFactory(parent) +{ +} + +KexiMacroPropertyFactory::~KexiMacroPropertyFactory() +{ +} + +KoProperty::CustomProperty* KexiMacroPropertyFactory::createCustomProperty(KoProperty::Property* parent) +{ + kdDebug()<<"KexiMacroPropertyFactory::createCustomProperty parent="<<parent->name()<<endl; + + KoProperty::CustomProperty* customproperty = parent->customProperty(); + KexiMacroProperty* parentcustomproperty = dynamic_cast<KexiMacroProperty*>(customproperty); + if(! parentcustomproperty) { + kdWarning() << "KexiMacroPropertyFactory::createCustomProperty() parent=" << parent->name() << " has an invalid customproperty." << endl; + return 0; + } + + KSharedPtr<KoMacro::MacroItem> macroitem = parentcustomproperty->macroItem(); + Q_ASSERT( macroitem.data() != 0 ); + const QString name = parentcustomproperty->name(); + Q_ASSERT(! name.isEmpty()); + + KexiMacroProperty* macroproperty = new KexiMacroProperty(parent, macroitem, name); + if(! macroproperty->variable().data()) { + delete macroproperty; macroproperty = 0; + return 0; + } + + return macroproperty; +} + +KoProperty::Widget* KexiMacroPropertyFactory::createCustomWidget(KoProperty::Property* property) +{ + kdDebug()<<"KexiMacroPropertyFactory::createCustomWidget property="<<property->name()<<endl; + return new KexiMacroPropertyWidget(property); +} + +void KexiMacroPropertyFactory::initFactory() +{ + CustomPropertyFactory* factory = KoProperty::FactoryManager::self()->factoryForEditorType(KEXIMACRO_PROPERTYEDITORTYPE); + if(! factory) { + factory = new KexiMacroPropertyFactory( KoProperty::FactoryManager::self() ); + KoProperty::FactoryManager::self()->registerFactoryForEditor(KEXIMACRO_PROPERTYEDITORTYPE, factory); + } +} + +/************************************************************* + * KexiMacroPropertyWidget + */ + +/** +* @internal implementation of a QListBoxItem to display the items of the +* combobox used within @a KexiMacroPropertyWidget to handle variables +* within a @a ListBox instance. +*/ +class ListBoxItem : public QListBoxText +{ + public: + ListBoxItem(QListBox* listbox) + : QListBoxText(listbox), m_enabled(true) {} + ListBoxItem(QListBox* listbox, const QString& text, QListBoxItem* after) + : QListBoxText(listbox, text, after), m_enabled(true) {} + virtual ~ListBoxItem() {} + void setEnabled(bool enabled) { m_enabled = enabled; } + virtual int width(const QListBox* lb) const { + Q_ASSERT( dynamic_cast<KComboBox*>( lb->parent() ) ); + return static_cast<KComboBox*>( lb->parent() )->lineEdit()->width() + 2; + } + virtual int height(const QListBox* lb) const { + Q_ASSERT( dynamic_cast<KComboBox*>( lb->parent() ) ); + return m_enabled ? static_cast<KComboBox*>( lb->parent() )->height() + 2 : 0; + } + private: + bool m_enabled; +}; + +/** +* @internal implementation of a @a ListBoxItem to provide an editable +* @a KoProperty::Widget as QListBoxItem in a @a ListBox instance. +*/ +class EditListBoxItem : public ListBoxItem +{ + public: + + EditListBoxItem(QListBox* listbox, KexiMacroProperty* macroproperty) + : ListBoxItem(listbox) + , m_macroproperty(macroproperty) + , m_prop(0) + , m_widget(0) + { + init(); + } + + virtual ~EditListBoxItem() { + delete m_widget; + delete m_prop; + } + + virtual QString text() const { + KSharedPtr<KoMacro::Variable> variable = m_macroproperty->variable(); + Q_ASSERT( variable.data() ); + //kdDebug()<<"EditListBoxItem::text() text="<<variable->toString()<<endl; + Q_ASSERT( variable->toString() != QString::null ); + return variable->toString(); + } + + KoProperty::Widget* widget() const { return m_widget; } + KSharedPtr<KoMacro::MacroItem> macroItem() const { return m_macroproperty->macroItem(); } + KSharedPtr<KoMacro::Variable> variable() const { return m_macroproperty->variable(); } + KSharedPtr<KoMacro::Action> action() const { return m_macroproperty->macroItem()->action(); } + + protected: + virtual void paint(QPainter* p) { + if(! m_widget) return; + Q_ASSERT( dynamic_cast<KComboBox*>( listBox()->parent() ) ); + const int w = width(listBox()); + const int h = height(listBox()); + m_widget->setFixedSize(w - 2, h - 2); + p->drawPixmap(0, 0, QPixmap::grabWidget(m_widget), 1, 1, w - 1, h - 1); + } + + private: + void init() { + KSharedPtr<KoMacro::MacroItem> macroitem = m_macroproperty->macroItem(); + Q_ASSERT( macroitem.data() ); + KSharedPtr<KoMacro::Action> action = m_macroproperty->macroItem()->action(); + if(! action.data()) { + kdWarning() << "EditListBoxItem::EditListBoxItem() Skipped cause there exists no action for macroproperty=" << m_macroproperty->name() << endl; + return; + } + KoProperty::Property* parentproperty = m_macroproperty->parentProperty(); + if(! parentproperty) { + kdWarning() << "EditListBoxItem::EditListBoxItem() No parentproperty defined" << endl; + return; + } + KSharedPtr<KoMacro::Variable> variable = m_macroproperty->variable(); + if(! variable.data()) { + kdWarning() << "EditListBoxItem::EditListBoxItem() No variable defined for property=" << parentproperty->name() << endl; + return; + } + + QVariant variant = variable->variant(); + + KSharedPtr<KoMacro::Variable> actionvariable = action->variable(m_macroproperty->name()); + if(actionvariable.data()) { + QVariant actionvariant = actionvariable->variant(); + Q_ASSERT( ! actionvariant.isNull() ); + Q_ASSERT( variant.canCast(actionvariant.type()) ); + variant.cast( actionvariant.type() ); //preserve type. + } + + int type = KoProperty::Auto; + switch(variant.type()) { + case QVariant::UInt: + case QVariant::Int: { + type = KoProperty::Integer; + } break; + case QVariant::CString: + case QVariant::String: { + type = KoProperty::String; + } break; + default: { + kdWarning() << "EditListBoxItem::EditListBoxItem() name=" << variable->name() << " type=" << QVariant::typeToName(variant.type()) << endl; + } break; + } + + QString name = variable->name(); + Q_ASSERT(! name.isNull()); + //if(name.isNull()) name = "aaaaaaaaaaaaaaaaa";//TESTCASE + m_prop = new KoProperty::Property( + name.latin1(), // name + variant, // value + variable->text(), // caption + QString::null, // description + type, // type + 0 //parentproperty // parent + ); + + m_widget = KoProperty::FactoryManager::self()->createWidgetForProperty(m_prop); + Q_ASSERT( m_widget != 0 ); + //m_widget->reparent(listBox()->viewport(), 0, QPoint(0,0)); + m_widget->reparent(listBox(), 0, QPoint(1,1)); + //layout->addWidget(m_widget, 1); + m_widget->setMinimumHeight(5); + m_widget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + } + + private: + KexiMacroProperty* m_macroproperty; + KoProperty::Property* m_prop; + KoProperty::Widget* m_widget; +}; + +/** +* @internal implementation of a @a QListBox for the combobox used within +* @a KexiMacroPropertyWidget to handle different variable-states. +*/ +class ListBox : public QListBox +{ + public: + ListBox(KComboBox* parent, KexiMacroProperty* macroproperty) + : QListBox(parent) + , m_macroproperty(macroproperty) + , m_edititem(0) + { + viewport()->setBackgroundMode(PaletteBackground); + setVariableHeight(true); + update(); + } + + virtual ~ListBox() {} + + void update() { + m_items.clear(); + delete m_edititem; + m_edititem = 0; + clear(); + + m_edititem = new EditListBoxItem(this, m_macroproperty); + Q_ASSERT( m_edititem->widget() != 0 ); + + const QString name = m_macroproperty->name(); + KoMacro::Variable::List children; + { + KoMacro::Variable::List actionchildren; + + KSharedPtr<KoMacro::Variable> itemvar = m_macroproperty->macroItem()->variable(name,false); + //kdDebug() << "KexiMacroProperty::ListBox::update() itemvar="<<(itemvar.data() ? "name:"+itemvar->name()+" value:"+itemvar->toString() : "NULL")<<endl; + if(itemvar.data()) + actionchildren = itemvar->children(); + + KSharedPtr<KoMacro::Action> action = m_edititem->action(); + KSharedPtr<KoMacro::Variable> actionvar = action.data() ? action->variable(name) : KSharedPtr<KoMacro::Variable>(); + //kdDebug() << "KexiMacroProperty::ListBox::update() actionvar="<<(actionvar.data() ? "name:"+actionvar->name()+" value:"+actionvar->toString() : "NULL")<<endl; + if(actionvar.data()) + actionchildren += actionvar->children(); + + KoMacro::Variable::List::ConstIterator it(actionchildren.constBegin()), end(actionchildren.constEnd()); + for(; it != end; ++it) { + if(name == (*it)->name()) { + KoMacro::Variable::List list = (*it)->children(); + KoMacro::Variable::List::ConstIterator listit(list.constBegin()), listend(list.constEnd()); + for(; listit != listend; ++listit) + children.append( *listit ); + } + } + + if(children.count() <= 0) + children = actionchildren; + } + + /* + kdDebug() << "KexiMacroProperty::ListBox::update() name="<<name<<" childcount="<<children.count()<<endl; + KoMacro::Variable::List::ConstIterator listit(children.constBegin()), listend(children.constEnd()); + for(; listit != listend; ++listit) { + kdDebug()<<" child name="<<(*listit)->name()<<" value="<<(*listit)->toString()<<" childcount="<<(*listit)->children().count()<<endl; + } + */ + + if(children.count() > 0) { + KoMacro::Variable::List::Iterator childit(children.begin()), childend(children.end()); + for(; childit != childend; ++childit) { + const QString n = (*childit)->name(); + //if(! n.startsWith("@")) continue; + const QVariant v = (*childit)->variant(); + + //kdDebug() << " child name=" << n << " value=" << v << endl; + switch( v.type() ) { + /* case QVariant::Map: { + const QMap<QString,QVariant> map = v.toMap(); + for(QMap<QString,QVariant>::ConstIterator it = map.constBegin(); it != map.constEnd(); ++it) + m_items.append(it.key()); + } break; */ + case QVariant::List: { + const QValueList<QVariant> list = v.toList(); + for(QValueList<QVariant>::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it) { + const QString s = (*it).toString().stripWhiteSpace(); + if(! s.isEmpty()) + m_items.append(s); + } + } break; + case QVariant::StringList: { + const QStringList list = v.toStringList(); + for(QStringList::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it) + if(! (*it).isEmpty()) + m_items.append(*it); + } break; + default: { + const QString s = v.toString().stripWhiteSpace(); + if(! s.isEmpty()) + m_items.append(s); + } break; + } + } + } + + QListBoxItem* item = m_edititem; + const uint count = m_items.count(); + for(uint i = 0; i < count; i++) + item = new ListBoxItem(this, m_items[i], item); + } + + EditListBoxItem* editItem() const { return m_edititem; } + QStringList items() const { return m_items; } + + virtual void hide () { + QListBox::hide(); + for(uint i = 0; i < count(); i++) + static_cast<ListBoxItem*>( item(i) )->setEnabled(false); + } + virtual void show() { + update(); + adjustSize(); + QListBox::show(); + } + + private: + KexiMacroProperty* m_macroproperty; + EditListBoxItem* m_edititem; + QStringList m_items; +}; + +/** +* @internal d-pointer class to be more flexible on future extension of the +* functionality without to much risk to break the binary compatibility. +*/ +class KexiMacroPropertyWidget::Private +{ + public: + KexiMacroProperty* macroproperty; + KComboBox* combobox; + ListBox* listbox; +}; + +KexiMacroPropertyWidget::KexiMacroPropertyWidget(KoProperty::Property* property, QWidget* parent) + : KoProperty::Widget(property, parent) + , d( new Private() ) +{ + kdDebug() << "KexiMacroPropertyWidget::KexiMacroPropertyWidget() Ctor" << endl; + + QHBoxLayout* layout = new QHBoxLayout(this, 0, 0); + + d->macroproperty = dynamic_cast<KexiMacroProperty*>( property->customProperty() ); + if(! d->macroproperty) { + kdWarning() << "KexiMacroPropertyWidget::KexiMacroPropertyWidget() Missing macroproperty for property=" << property->name() << endl; + return; + } + + d->combobox = new KComboBox(this); + layout->addWidget(d->combobox); + d->listbox = new ListBox(d->combobox, d->macroproperty); + d->combobox->setEditable(true); + d->combobox->setListBox(d->listbox); + d->combobox->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + d->combobox->setMinimumHeight(5); + d->combobox->setInsertionPolicy(QComboBox::NoInsertion); + d->combobox->setMinimumSize(10, 0); // to allow the combo to be resized to a small size + d->combobox->setAutoCompletion(false); + d->combobox->setContextMenuEnabled(false); + + QVariant value = d->macroproperty->value(); + int index = d->listbox->items().findIndex( value.toString() ); + if(index >= 0) { + d->combobox->setCurrentItem(index + 1); + d->listbox->setCurrentItem(index + 1); + } + else { + Q_ASSERT( d->listbox->editItem()->widget() != 0 ); + d->listbox->editItem()->widget()->setValue( d->macroproperty->value(), true ); + //d->combobox->setCurrentItem(0); + } + kdDebug() << ">>> KexiMacroPropertyWidget::KexiMacroPropertyWidget() CurrentItem=" << d->combobox->currentItem() << endl; + + d->combobox->setFocusProxy( d->listbox->editItem()->widget() ); + setFocusWidget( d->combobox->lineEdit() ); + + connect(d->combobox, SIGNAL(textChanged(const QString&)), + this, SLOT(slotComboBoxChanged())); + connect(d->combobox, SIGNAL(activated(int)), + this, SLOT(slotComboBoxActivated())); + connect(d->listbox->editItem()->widget(), SIGNAL(valueChanged(Widget*)), + this, SLOT(slotWidgetValueChanged())); + connect(d->macroproperty, SIGNAL(valueChanged()), + this, SLOT(slotPropertyValueChanged())); +} + +KexiMacroPropertyWidget::~KexiMacroPropertyWidget() +{ + kdDebug() << "KexiMacroPropertyWidget::~KexiMacroPropertyWidget() Dtor" << endl; + delete d; +} + +QVariant KexiMacroPropertyWidget::value() const +{ + kdDebug()<<"KexiMacroPropertyWidget::value() value="<<d->macroproperty->value()<<endl; + return d->macroproperty->value(); + /* QVariant value = d->combobox->currentText(); + value.cast( d->macroproperty->value().type() ); + return value; */ +} + +void KexiMacroPropertyWidget::setValue(const QVariant& value, bool emitChange) +{ + kdDebug()<<"KexiMacroPropertyWidget::setValue() value="<<value<<" emitChange="<<emitChange<<endl; + + if(! emitChange) + d->combobox->blockSignals(true); + + const QString s = value.toString(); + d->combobox->setCurrentText( s.isNull() ? "" : s ); + + if(emitChange) + emit valueChanged(this); + else + d->combobox->blockSignals(false); +} + +void KexiMacroPropertyWidget::setReadOnlyInternal(bool readOnly) +{ + Q_UNUSED(readOnly); + //kdDebug()<<"KexiMacroPropertyWidget::setReadOnlyInternal() readOnly="<<readOnly<<endl; +} + +void KexiMacroPropertyWidget::slotComboBoxChanged() +{ + kdDebug()<<"KexiMacroPropertyWidget::slotComboBoxChanged()"<<endl; + const QVariant v = d->combobox->currentText(); + d->macroproperty->setValue(v, true); + //emit valueChanged(this); +} + +void KexiMacroPropertyWidget::slotComboBoxActivated() +{ + Q_ASSERT( d->listbox->editItem()->widget() ); + const int index = d->combobox->currentItem(); + QString text = (index == 0) + ? d->listbox->editItem()->widget()->value().toString() + : d->combobox->text(index); + kdDebug()<<"KexiMacroPropertyWidget::slotComboBoxActivated() index="<<index<<" text="<<text<<endl; + d->combobox->setCurrentText(text); + slotWidgetValueChanged(); +} + +void KexiMacroPropertyWidget::slotWidgetValueChanged() +{ + d->macroproperty->emitPropertyChanged(); +} + +void KexiMacroPropertyWidget::slotPropertyValueChanged() +{ + Q_ASSERT( d->listbox->editItem()->widget() ); + const QVariant v = d->macroproperty->value(); + kdDebug()<<"KexiMacroPropertyWidget::slotPropertyValueChanged() value="<<v<<endl; + d->listbox->editItem()->widget()->setValue(v, true); +} + +#include "keximacroproperty.moc" diff --git a/kexi/plugins/macros/kexipart/keximacroproperty.h b/kexi/plugins/macros/kexipart/keximacroproperty.h new file mode 100644 index 00000000..19f7b7ac --- /dev/null +++ b/kexi/plugins/macros/kexipart/keximacroproperty.h @@ -0,0 +1,186 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Sebastian Sauer <mail@dipe.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KEXIMACROPROPERTY_H +#define KEXIMACROPROPERTY_H + +#include <ksharedptr.h> +#include <koproperty/property.h> +#include <koproperty/factory.h> +#include <koproperty/customproperty.h> +#include <koproperty/widget.h> + +namespace KoMacro { + class Variable; + class MacroItem; +} + +class KexiMacroPropertyWidget; + +/** +* Implementation of a @a KoProperty::CustomProperty to have +* more control about the handling of our macro-properties. +*/ +class KexiMacroProperty + : public QObject + , public KoProperty::CustomProperty +{ + Q_OBJECT + + friend class KexiMacroPropertyWidget; + + public: + + /** Constructor. */ + explicit KexiMacroProperty(KoProperty::Property* parent, KSharedPtr<KoMacro::MacroItem> macroitem, const QString& name); + /** Destructor. */ + virtual ~KexiMacroProperty(); + + /** @return the parent @a KoProperty::Property instance. */ + KoProperty::Property* parentProperty() const; + + /** This function is called by @ref KoProperty::Property::setValue() + when a custom property is set. + You don't have to modify the property value, it is done by Property class. + You just have to update child or parent properties value (m_property->parent()->setValue()). + Note that, when calling Property::setValue, you <b>need</b> to set + useCustomProperty (3rd parameter) to false, or there will be infinite recursion. */ + virtual void setValue(const QVariant &value, bool rememberOldValue); + + /** This function is called by @ref KoProperty::Property::value() + when a custom property is set and @ref handleValue() is true. + You should return property's value, taken from parent's value.*/ + virtual QVariant value() const; + + /** Tells whether CustomProperty should be used to get the property's value. + You should return true for child properties, and false for others. */ + virtual bool handleValue() const; + + /** \return the \a KoMacro::MacroItem this custom property has or + NULL if there was no item provided. */ + KSharedPtr<KoMacro::MacroItem> macroItem() const; + + /** \return the name the property has in the \a KoMacro::MacroItem + above. Is QString::null if there was no item provided. */ + QString name() const; + + /** \return the \a KoMacro::Variable which has the name @a name() + in the item @a macroItem() . If such a variable doesn't exists NULL + is returned. */ + KSharedPtr<KoMacro::Variable> variable() const; + + /** Factory function to create a new @a KoProperty::Property instance + that will use a @a KexiMacroProperty as container. */ + static KoProperty::Property* createProperty(KSharedPtr<KoMacro::MacroItem> macroitem, const QString& name); + + signals: + + /** Emitted if @a setValue was called and the value changed. */ + void valueChanged(); + + private: + /** \internal d-pointer class. */ + class Private; + /** \internal d-pointer instance. */ + Private* const d; + /** \internal initializer method. */ + inline void init(); +}; + +/** +* Implementation of a @a KoProperty::CustomPropertyFactory to handle +* creation of @a KexiMacroProperty and @a KexiMacroPropertyWidget +* instances for our macro-properties. +*/ +class KexiMacroPropertyFactory : public KoProperty::CustomPropertyFactory +{ + public: + /** Constructor. */ + explicit KexiMacroPropertyFactory(QObject* parent); + /** Destructor. */ + virtual ~KexiMacroPropertyFactory(); + + /** @return a new instance of custom property for @p parent. + Implement this for property types you want to support. + Use parent->type() to get type of the property. */ + virtual KoProperty::CustomProperty* createCustomProperty(KoProperty::Property* parent); + + /** @return a new instance of custom property for @p property. + Implement this for property editor types you want to support. + Use parent->type() to get type of the property. */ + virtual KoProperty::Widget* createCustomWidget(KoProperty::Property* property); + + /** Initializes this factory. The factory may register itself at + the @a KoProperty::FactoryManager if not alreadydone before. This + function should be called from within the @a KexiMacroDesignView + before the functionality provided with @a KexiMacroProperty and + @a KexiMacroPropertyWidget got used. */ + static void initFactory(); +}; + +/** + * Implementation of a @a KoProperty::Widget used to display and + * edit a @a KexiMacroProperty . + */ +class KexiMacroPropertyWidget : public KoProperty::Widget +{ + Q_OBJECT + + public: + /** Constructor. */ + explicit KexiMacroPropertyWidget(KoProperty::Property* property, QWidget* parent = 0); + /** Destructor. */ + virtual ~KexiMacroPropertyWidget(); + + /** @return the value this widget has. */ + virtual QVariant value() const; + + /** Set the value @p value this widget has. If @p emitChange is true, + the @p KoProperty::Widget::valueChanged signal will be emitted. */ + virtual void setValue(const QVariant& value, bool emitChange=true); + + //virtual void drawViewer(QPainter *p, const QColorGroup &cg, const QRect &r, const QVariant &value); + + protected: + + /** Called if the value should be read only. */ + virtual void setReadOnlyInternal(bool readOnly); + + private slots: + + /** Called if the text in the KComboBox changed. */ + void slotComboBoxChanged(); + + /** Called if an item in the QListBox of the KComboBox got activated. */ + void slotComboBoxActivated(); + + /** Called if the @a KoProperty::Widget of the EditListBoxItem got changed. */ + void slotWidgetValueChanged(); + + /** Called if the value of a @a KexiMacroProperty changed to update + the widget and the displayed content. */ + void slotPropertyValueChanged(); + + private: + /** \internal d-pointer class. */ + class Private; + /** \internal d-pointer instance. */ + Private* const d; +}; + +#endif + diff --git a/kexi/plugins/macros/kexipart/keximacrotextview.cpp b/kexi/plugins/macros/kexipart/keximacrotextview.cpp new file mode 100644 index 00000000..95c94a47 --- /dev/null +++ b/kexi/plugins/macros/kexipart/keximacrotextview.cpp @@ -0,0 +1,90 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Sebastian Sauer <mail@dipe.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "keximacrotextview.h" + +#include <ktextedit.h> +#include <kdebug.h> + +#include <kexidialogbase.h> +#include <kexidb/connection.h> + +#include "../lib/macro.h" +#include "../lib/xmlhandler.h" + +/** +* \internal d-pointer class to be more flexible on future extension of the +* functionality without to much risk to break the binary compatibility. +*/ +class KexiMacroTextView::Private +{ + public: + + /** + * The Editor used to display and edit the XML text. + */ + KTextEdit* editor; + +}; + +KexiMacroTextView::KexiMacroTextView(KexiMainWindow *mainwin, QWidget *parent, ::KoMacro::Macro* const macro) + : KexiMacroView(mainwin, parent, macro, "KexiMacroTextView") + , d( new Private() ) +{ + QHBoxLayout* layout = new QHBoxLayout(this); + d->editor = new KTextEdit(this); + d->editor->setTextFormat(Qt::PlainText); + d->editor->setWordWrap(QTextEdit::NoWrap); + layout->addWidget(d->editor); + + connect(d->editor, SIGNAL(textChanged()), this, SLOT(editorChanged())); +} + +KexiMacroTextView::~KexiMacroTextView() +{ + delete d; +} + +void KexiMacroTextView::editorChanged() +{ + setDirty(true); +} + +bool KexiMacroTextView::loadData() +{ + QString data; + if(! loadDataBlock(data)) { + kexipluginsdbg << "KexiMacroTextView::loadData(): no DataBlock" << endl; + return false; + } + + kdDebug() << QString("KexiMacroTextView::loadData()\n%1").arg(data) << endl; + //d->editor->blockSignals(true); + d->editor->setText(data); + //d->editor->blockSignals(false); + setDirty(false); + return true; +} + +tristate KexiMacroTextView::storeData(bool /*dontAsk*/) +{ + kexipluginsdbg << QString("KexiMacroTextView::storeData() %1 [%2]\n%3").arg(parentDialog()->partItem()->name()).arg(parentDialog()->id()).arg(d->editor->text()) << endl; + return storeDataBlock( d->editor->text() ); +} + +#include "keximacrotextview.moc" + diff --git a/kexi/plugins/macros/kexipart/keximacrotextview.h b/kexi/plugins/macros/kexipart/keximacrotextview.h new file mode 100644 index 00000000..66a2229c --- /dev/null +++ b/kexi/plugins/macros/kexipart/keximacrotextview.h @@ -0,0 +1,77 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Sebastian Sauer <mail@dipe.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KEXIMACROTEXTVIEW_H +#define KEXIMACROTEXTVIEW_H + +#include "keximacroview.h" + +// Forward declaration. +namespace KoMacro { + class Macro; +} + +/** + * The KexiMacroTextView implements \a KexiMacroView to provide + * a simple texteditor to edit the XML document of a Macro. + */ +class KexiMacroTextView : public KexiMacroView +{ + Q_OBJECT + public: + + /** + * Constructor. + * + * \param mainwin The \a KexiMainWindow instance this \a KexiViewBase + * belongs to. + * \param parent The parent widget this widget should be displayed in. + * \param macro The \a KoMacro::Macro instance this view is for. + */ + KexiMacroTextView(KexiMainWindow *mainwin, QWidget *parent, ::KoMacro::Macro* const macro); + + /** + * Destructor. + */ + virtual ~KexiMacroTextView(); + + /** + * Load the data and display it in the editor. + */ + virtual bool loadData(); + + /** + * Try to store the modified data in the already opened and + * currently used \a KexiDB::SchemaData instance. + */ + virtual tristate storeData(bool dontAsk = false); + + private slots: + + /** + * This slot got called if the text of the editor changed. + */ + void editorChanged(); + + private: + /// \internal d-pointer class. + class Private; + /// \internal d-pointer instance. + Private* const d; +}; + +#endif diff --git a/kexi/plugins/macros/kexipart/keximacroview.cpp b/kexi/plugins/macros/kexipart/keximacroview.cpp new file mode 100644 index 00000000..35200829 --- /dev/null +++ b/kexi/plugins/macros/kexipart/keximacroview.cpp @@ -0,0 +1,175 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Sebastian Sauer <mail@dipe.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#include "keximacroview.h" + +#include <qdom.h> +#include <kdebug.h> + +#include <kexidialogbase.h> +#include <kexidb/connection.h> +#include <kexidb/error.h> + +#include <core/kexi.h> +#include <core/kexiproject.h> +#include <core/kexipartmanager.h> +#include <core/kexipartinfo.h> + +#include "../lib/macro.h" +#include "../lib/xmlhandler.h" +#include "../lib/exception.h" + +#include "keximacroerror.h" + +/** +* \internal d-pointer class to be more flexible on future extension of the +* functionality without to much risk to break the binary compatibility. +*/ +class KexiMacroView::Private +{ + public: + + /** + * The \a KoMacro::Manager instance used to access the + * Macro Framework. + */ + KSharedPtr<KoMacro::Macro> macro; + + /** + * Constructor. + * + * \param m The passed \a KoMacro::Manager instance our + * \a manager points to. + */ + Private(KoMacro::Macro* const m) + : macro(m) + { + } + +}; + +KexiMacroView::KexiMacroView(KexiMainWindow *mainwin, QWidget *parent, KoMacro::Macro* const macro, const char* name) + : KexiViewBase(mainwin, parent, (name ? name : "KexiMacroView")) + , d( new Private(macro) ) +{ + //kdDebug() << "KexiMacroView::KexiMacroView() Ctor" << endl; + plugSharedAction( "data_execute", this, SLOT(execute()) ); +} + +KexiMacroView::~KexiMacroView() +{ + //kdDebug() << "KexiMacroView::~KexiMacroView() Dtor" << endl; + delete d; +} + +KSharedPtr<KoMacro::Macro> KexiMacroView::macro() const +{ + return d->macro; +} + +tristate KexiMacroView::beforeSwitchTo(int mode, bool& dontstore) +{ + kexipluginsdbg << "KexiMacroView::beforeSwitchTo mode=" << mode << " dontstore=" << dontstore << endl; + return true; +} + +tristate KexiMacroView::afterSwitchFrom(int mode) +{ + kexipluginsdbg << "KexiMacroView::afterSwitchFrom mode=" << mode << endl; + loadData(); // reload the data + return true; +} + +bool KexiMacroView::loadData() +{ + d->macro->clearItems(); + + QString data; + if(! loadDataBlock(data)) { + kexipluginsdbg << "KexiMacroView::loadData(): no DataBlock" << endl; + return false; + } + + QString errmsg; + int errline, errcol; + + QDomDocument domdoc; + bool parsed = domdoc.setContent(data, false, &errmsg, &errline, &errcol); + + if(! parsed) { + kexipluginsdbg << "KexiMacroView::loadData() XML parsing error line: " << errline << " col: " << errcol << " message: " << errmsg << endl; + return false; + } + + kexipluginsdbg << QString("KexiMacroView::loadData()\n%1").arg(domdoc.toString()) << endl; + QDomElement macroelem = domdoc.namedItem("macro").toElement(); + if(macroelem.isNull()) { + kexipluginsdbg << "KexiMacroView::loadData() Macro domelement is null" << endl; + return false; + } + + //kexipluginsdbg << "KexiMacroView::loadData()" << endl; + return d->macro->parseXML(macroelem); +} + +KexiDB::SchemaData* KexiMacroView::storeNewData(const KexiDB::SchemaData& sdata, bool &cancel) +{ + KexiDB::SchemaData *schema = KexiViewBase::storeNewData(sdata, cancel); + kexipluginsdbg << "KexiMacroView::storeNewData() new id:" << schema->id() << endl; + + if(!schema || cancel) { + delete schema; + return 0; + } + + if(! storeData()) { + kexipluginsdbg << "KexiMacroView::storeNewData() Failed to store the data." << endl; + //failure: remove object's schema data to avoid garbage + KexiDB::Connection *conn = parentDialog()->mainWin()->project()->dbConnection(); + conn->removeObject( schema->id() ); + delete schema; + return 0; + } + + return schema; +} + +tristate KexiMacroView::storeData(bool /*dontAsk*/) +{ + QDomDocument domdoc("macros"); + QDomElement macroelem = d->macro->toXML(); + domdoc.appendChild(macroelem); + const QString xml = domdoc.toString(2); + const QString name = QString("%1 [%2]").arg(parentDialog()->partItem()->name()).arg(parentDialog()->id()); + kexipluginsdbg << QString("KexiMacroView::storeData %1\n%2").arg(name).arg(xml) << endl; + return storeDataBlock(xml); +} + +void KexiMacroView::execute(QObject* sender) +{ + KSharedPtr<KoMacro::Context> context = d->macro->execute(sender); + if(context->hadException()) { + KexiMacroError* error = new KexiMacroError( + mainWin(), // The parent KexiMainWindow + context // The KoMacro::Context where the error occured. + ); + error->exec(); + } +} + +#include "keximacroview.moc" + diff --git a/kexi/plugins/macros/kexipart/keximacroview.h b/kexi/plugins/macros/kexipart/keximacroview.h new file mode 100644 index 00000000..beed842e --- /dev/null +++ b/kexi/plugins/macros/kexipart/keximacroview.h @@ -0,0 +1,140 @@ +/* This file is part of the KDE project + Copyright (C) 2006 Sebastian Sauer <mail@dipe.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + Boston, MA 02110-1301, USA. +*/ + +#ifndef KEXIMACROVIEW_H +#define KEXIMACROVIEW_H + +#include <kexiviewbase.h> + +// Forward declarations. +namespace KoMacro { + class Macro; +} +namespace KoProperty { + class Property; +} +namespace KexiDB { + class ResultInfo; +} +class KexiTableItem; + +/** + * The KexiMacroView implements \a KexiViewBase to provide + * a base KexiView instance for Macros. + * + * The \a KexiMacroDesignView and the \a KexiMacroTextView + * are inherited from this class. + */ +class KexiMacroView : public KexiViewBase +{ + Q_OBJECT + public: + + /** + * Constructor. + * + * \param mainwin The \a KexiMainWindow instance this \a KexiViewBase + * belongs to. + * \param parent The parent widget this widget should be displayed in. + * \param macro The \a KoMacro::Macro instance this view is for. + */ + KexiMacroView(KexiMainWindow *mainwin, QWidget *parent, ::KoMacro::Macro* const macro, const char* name = 0); + + /** + * Destructor. + */ + virtual ~KexiMacroView(); + + /** + * \return the Macro instance. + */ + KSharedPtr<KoMacro::Macro> macro() const; + + /** + * Load the data from XML source and fill the internally + * used \a KoMacro::Macro instance. + */ + virtual bool loadData(); + + /** + * Try to call \a storeData with new data we like to store. On + * success the matching \a KexiDB::SchemaData is returned. + * + * \param sdata The source \a KexiDB::SchemaData instance. + * \param cancel Cancel on failure and don't try to clean + * possible temporary created data up. + * \return The matching \a KexiDB::SchemaData instance or NULL + * if storing failed. + */ + virtual KexiDB::SchemaData* storeNewData(const KexiDB::SchemaData& sdata, bool &cancel); + + /** + * Try to store the modified data in the already opened and + * currently used \a KexiDB::SchemaData instance. + */ + virtual tristate storeData(bool dontAsk = false); + + public slots: + + /** + * This slot will be invoked if Kexi's menuitem Data=>Execute + * got activated and will execute the Macro. + */ + void execute(QObject* sender = 0); + + protected: + + /** + * Called by \a KexiDialogBase::switchToViewMode() right before dialog + * is switched to new mode. + * + * \param mode The viewmode to which should be switched. This + * could be either Kexi::DataViewMode, Kexi::DesignViewMode + * or Kexi::TextViewMode. + * \param donstore This call-by-reference boolean value defines + * if \a storeData should be called for the old but still + * selected viewmode. Set \a dontstore to true (it's false + * by default) if you want to avoid data storing. + * \return true if you accept or false if a error occupied and view + * shouldn't change. If there is no error but switching + * should be just cancelled (probably after showing some + * info messages), you need to return cancelled. + */ + virtual tristate beforeSwitchTo(int mode, bool& dontstore); + + /** + * Called by \a KexiDialogBase::switchToViewMode() right after dialog + * is switched to new mode. + * + * \param mode The viewmode to which we switched. This could + * be either Kexi::DataViewMode, Kexi::DesignViewMode + * or Kexi::TextViewMode. + * \return true if you accept or false if a error occupied and view + * shouldn't change. If there is no error but switching + * should be just cancelled (probably after showing + * some info messages), you need to return cancelled. + */ + virtual tristate afterSwitchFrom(int mode); + + private: + /// \internal d-pointer class. + class Private; + /// \internal d-pointer instance. + Private* const d; +}; + +#endif diff --git a/kexi/plugins/macros/lib/Makefile.am b/kexi/plugins/macros/lib/Makefile.am new file mode 100644 index 00000000..fc7867b8 --- /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 00000000..e2dc0b64 --- /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 00000000..5200c1a4 --- /dev/null +++ b/kexi/plugins/macros/lib/action.h @@ -0,0 +1,187 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2005 by Tobi Krebs (tobi.krebs@gmail.com) + * copyright (C) 2006 by Sascha Kupper (kusato@kfnv.de) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#ifndef KOMACRO_ACTION_H +#define KOMACRO_ACTION_H + +#include "manager.h" +#include "context.h" +#include "variable.h" + +#include <qobject.h> +#include <ksharedptr.h> +#include <qstringlist.h> + +namespace KoMacro { + + /** + * The Action class extendes KAction to implement some additional + * functionality KAction doesn't provide. + */ + class KOMACRO_EXPORT Action + : public QObject // Qt functionality like signals and slots + , public KShared // shared reference-counting + { + Q_OBJECT + + /// Property to get/set the name. + Q_PROPERTY(QString name READ name WRITE setName) + + /// Property to get/set the text. + Q_PROPERTY(QString text READ text WRITE setText) + + /// Property to get/set the comment. + Q_PROPERTY(QString comment READ comment WRITE setComment) + + public: + + /** + * Shared pointer to implement reference-counting. + */ + typedef QMap<QString, KSharedPtr<Action> > Map; + + /** + * Constructor. + * + * @param name The unique name this @a Action has. + * @param text The i18n-caption text this @a Action has. + */ + explicit Action(const QString& name, const QString& text = QString::null); + + /** + * Destructor. + */ + virtual ~Action(); + + /** + * @return a string representation of the functionality + * this action provides. + */ + virtual const QString toString() const; + + /** + * The name this @a Action has. + */ + const QString name() const; + + /** + * Set the name of the @a Action to @p name . + */ + void setName(const QString& name); + + /** + * @return the i18n-caption text this @a Action has. + */ + const QString text() const; + + /** + * Set the i18n-caption text this @a Action has. + */ + void setText(const QString& text); + + /** + * @return the comment associated with this action. + */ + const QString comment() const; + + /** + * Set the @p comment associated with this action. + */ + void setComment(const QString& comment); + + /** + * @return true if there exists a variable with the + * name @p name else false is returned. + */ + bool hasVariable(const QString& name) const; + + /** + * @return the variable @a Variable defined for the + * name @p name . If there exists no @a Variable with + * such a name, NULL is returned. + */ + KSharedPtr<Variable> variable(const QString& name) const; + + /** + * @return the map of variables this @a Action provides. + */ + Variable::Map variables() const; + + /** + * @return a list of variablenames this @a Action provides.s + */ + QStringList variableNames() const; + + /** + * Append the @a Variable @p variable to list of variables + * this @a Action provides. + */ + void setVariable(KSharedPtr<Variable> variable); + + /** + * Set the variable. + * + * @param name The name the variable should have. + * @param text The i18n-caption used for display. + * @param variant The QVariant value. + */ + void setVariable(const QString& name, const QString& text, const QVariant& variant); + + /** + * Remove the variable defined with @p name . If there exists + * no such variable, nothing is done. + */ + void removeVariable(const QString& name); + + /** + * This function is called, when the @a KoMacro::Variable + * with name @p name used within the @a KoMacro::MacroItem + * @p macroitem got changed. + * + * @param macroitem The @a KoMacro::MacroItem instance where + * the variable defined with @p name is located in. + * @param name The name the @a KoMacro::Variable has. + * @return true if the update was successfully else false + * is returned. + */ + virtual bool notifyUpdated(const KSharedPtr<MacroItem> ¯oitem, const QString& name) { + Q_UNUSED(macroitem); + Q_UNUSED(name); + return true; // The default implementation does nothing. + } + + public slots: + + /** + * Called if the @a Action should be executed within the + * defined @p context . + */ + virtual void activate(KSharedPtr<Context> context) = 0; + + private: + /// @internal d-pointer class. + class Private; + /// @internal d-pointer instance. + Private* const d; + }; + +} + +#endif diff --git a/kexi/plugins/macros/lib/context.cpp b/kexi/plugins/macros/lib/context.cpp new file mode 100644 index 00000000..135c10c9 --- /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 00000000..dd467dad --- /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 00000000..7cfc7d71 --- /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 00000000..73504de0 --- /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 00000000..cc4b41a8 --- /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 00000000..688cc7b0 --- /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 00000000..da38e05b --- /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 00000000..4027f2cc --- /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 00000000..8f3e1502 --- /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 00000000..77ad98b1 --- /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 00000000..964f9d7c --- /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 00000000..8aa4dc54 --- /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 00000000..df53ac60 --- /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 00000000..000f4181 --- /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 00000000..8b611574 --- /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 00000000..7f072b2b --- /dev/null +++ b/kexi/plugins/macros/lib/metaparameter.cpp @@ -0,0 +1,146 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2005 by Tobi Krebs (tobi.krebs@gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#include "metaparameter.h" +#include "exception.h" +#include "variable.h" + +#include <kdebug.h> + +using namespace KoMacro; + +namespace KoMacro { + + /** + * @internal d-pointer class to be more flexible on future extension of the + * functionality without to much risk to break the binary compatibility. + */ + class MetaParameter::Private + { + public: + + /** + * The signatures argument that represents this MetaParameter. + * This could be something like "const QString&", "int" or + * "QMap < QString, QVariant > ". + */ + QString signatureargument; + + /** + * The type of the @a Variable . + */ + MetaParameter::Type type; + + /** + * If the @a MetaParameter::Type is a Variant this QVariant::Type + * is used to defined what kind of Variant it is. + */ + QVariant::Type varianttype; + + }; + +} + +MetaParameter::MetaParameter(const QString& signatureargument) + : KShared() + , d( new Private() ) // create the private d-pointer instance. +{ + d->type = TypeNone; + + if(! signatureargument.isNull()) { + setSignatureArgument( signatureargument ); + } +} + +MetaParameter::~MetaParameter() +{ + delete d; +} + +MetaParameter::Type MetaParameter::type() const +{ + return d->type; +} + +const QString MetaParameter::typeName() const +{ + switch( d->type ) { + case TypeNone: + return "None"; + case TypeVariant: + return "Variant"; + case TypeObject: + return "Object"; + } + return QString::null; +} + +void MetaParameter::setType(MetaParameter::Type type) +{ + d->type = type; + d->varianttype = QVariant::Invalid; +} + +QVariant::Type MetaParameter::variantType() const +{ + return d->varianttype; +} + +void MetaParameter::setVariantType(QVariant::Type varianttype) +{ + d->type = TypeVariant; + d->varianttype = varianttype; +} + +void MetaParameter::setSignatureArgument(const QString& signatureargument) +{ + d->signatureargument = signatureargument; + + QString argument = signatureargument; + if(argument.startsWith("const")) { + argument = argument.mid(5).stripWhiteSpace(); + } + + if(argument.endsWith("&")) { + argument = argument.left( argument.length() - 1 ).stripWhiteSpace(); + } + + if(argument.isEmpty()) { + throw Exception(QString("Empty signature argument passed.")); + } + if(argument == "QVariant") { + setVariantType( QVariant::Invalid ); + } + + QVariant::Type type = argument.isNull() ? QVariant::Invalid : QVariant::nameToType(argument.latin1()); + if (type != QVariant::Invalid) { + setVariantType( type ); + } + else { + setType( TypeObject ); + } +} + +bool MetaParameter::validVariable(KSharedPtr<Variable> variable) const +{ + if( type() != variable->type() ) { + return false; + } + return true; +} diff --git a/kexi/plugins/macros/lib/metaparameter.h b/kexi/plugins/macros/lib/metaparameter.h new file mode 100644 index 00000000..ab2a4004 --- /dev/null +++ b/kexi/plugins/macros/lib/metaparameter.h @@ -0,0 +1,136 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2005 by Tobi Krebs (tobi.krebs@gmail.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * You should have received a copy of the GNU Library General Public License + * along with this program; see the file COPYING. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. + ***************************************************************************/ + +#ifndef KOMACRO_METAPARAMETER_H +#define KOMACRO_METAPARAMETER_H + +#include <qstring.h> +#include <qvariant.h> +#include <qobject.h> +#include <ksharedptr.h> + +#include "komacro_export.h" + +namespace KoMacro { + + // Forward declarations. + class Variable; + + /** + * Class to provide abstract methods for the undocumented + * Qt3 QUObject-API functionality. + * + * The design tried to limit future porting to Qt4 by providing a + * somewhat similar API to the Qt4 QMeta* stuff. + */ + class KOMACRO_EXPORT MetaParameter : public KShared + { + + /** + * Property to get the type of the variable. + */ + Q_PROPERTY(Type type READ type) + + /** + * Property to get the type of the variable as string. + */ + Q_PROPERTY(QString typeName READ typeName) + + public: + + /** + * List of @a MetaParameter instances. + */ + typedef QValueList<KSharedPtr <MetaParameter > > List; + + /** + * Constructor. + * + * @param signatureargument The signatures argument + * that will be used to determinate the arguments + * type. This could be something like "const QString&", + * "int" or "QMap < QString, QVariant > ". + */ + explicit MetaParameter(const QString& signatureargument = QString::null); + + /** + * Destructor. + */ + ~MetaParameter(); + + /** + * Possible types the @a MetaParameter could provide. + */ + enum Type { + TypeNone = 0, /// None type, the @a MetaParameter is empty. + TypeVariant, /// The @a MetaParameter is a QVariant. + TypeObject /// The @a MetaParameter is a QObject. + }; + + /** + * @return the @a MetaParameter::Type this variable has. + */ + Type type() const; + + /** + * @return the @a MetaParameter::Type as string. The typename + * could be "None", "Variant" or "Object". + */ + const QString typeName() const; + + /** + * Set the @a MetaParameter::Type this variable is. + */ + void setType(Type type); + + /** + * @return the @a MetaParameter::Type this variable is. + */ + QVariant::Type variantType() const; + + /** + * Set the @a MetaParameter::Type this variable is. + */ + void setVariantType(QVariant::Type varianttype); + + /** + * @return true if the passed @a Variable @p variable is + * valid for this @a MetaParameter . Valid means, that + * the variable has a castable type. + */ + bool validVariable(KSharedPtr<Variable> variable) const; + + protected: + + /** + * @internal used method to set the signature argument. Those + * argument will be used to determinate the arguments type. + */ + void setSignatureArgument(const QString& signatureargument); + + private: + /// @internal d-pointer class. + class Private; + /// @internal d-pointer instance. + Private* const d; + }; + +} + +#endif diff --git a/kexi/plugins/macros/lib/variable.cpp b/kexi/plugins/macros/lib/variable.cpp new file mode 100644 index 00000000..598b8b46 --- /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 00000000..26e9619e --- /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 00000000..b35759e1 --- /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 00000000..b6978d0f --- /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 diff --git a/kexi/plugins/macros/tests/Makefile.am b/kexi/plugins/macros/tests/Makefile.am new file mode 100644 index 00000000..36dbd76f --- /dev/null +++ b/kexi/plugins/macros/tests/Makefile.am @@ -0,0 +1,28 @@ +if include_kunittestgui + GUIBINPROGRAM = komacrotestgui +else + GUIBINPROGRAM = +endif + +bin_PROGRAMS = komacrotest $(GUIBINPROGRAM) + +komacrotest_SOURCES = komacrotest.cpp testobject.cpp testaction.cpp actiontests.cpp macrotests.cpp macroitemtests.cpp variabletests.cpp xmlhandlertests.cpp xmlhandlertests2.cpp +komacrotest_LDFLAGS = $(KDE_RPATH) $(all_libraries) +komacrotest_LDADD = -lkunittest ../lib/libkomacro.la $(LIB_KDEUI) $(LIB_KPARTS) + +if include_kunittestgui + komacrotestgui_SOURCES = komacrotestgui.cpp testobject.cpp testaction.cpp actiontests.cpp macrotests.cpp macroitemtests.cpp variabletests.cpp xmlhandlertests.cpp xmlhandlertests2.cpp + komacrotestgui_LDFLAGS = $(KDE_RPATH) $(all_libraries) + komacrotestgui_LDADD = -lkunittestgui ../lib/libkomacro.la $(LIB_KDEUI) $(LIB_KPARTS) +endif + +KDE_CXXFLAGS = $(USE_EXCEPTIONS) +INCLUDES = -I$(srcdir)/tests -I$(srcdir)../ $(all_includes) +METASOURCES = AUTO + +guicheck: komacrotestgui + kunittest ./komacrotestgui + +check: komacrotest + echo $(srcdir) + kunittest ./komacrotest diff --git a/kexi/plugins/macros/tests/actiontests.cpp b/kexi/plugins/macros/tests/actiontests.cpp new file mode 100644 index 00000000..0150ecfd --- /dev/null +++ b/kexi/plugins/macros/tests/actiontests.cpp @@ -0,0 +1,211 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * + * 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 "actiontests.h" +#include "testobject.h" +#include "testaction.h" +#include "komacrotestbase.h" + +#include "../lib/action.h" +#include "../lib/function.h" +#include "../lib/manager.h" +#include "../lib/macro.h" +#include "../lib/variable.h" +#include "../lib/metaobject.h" +#include "../lib/metamethod.h" +#include "../lib/metaparameter.h" +#include "../lib/exception.h" +#include "../lib/macroitem.h" + +#include <ostream> + +#include <qstringlist.h> +#include <qdom.h> + +#include <kdebug.h> +#include <kunittest/runner.h> +#include <kxmlguiclient.h> + +using namespace KUnitTest; +using namespace KoMacroTest; + +namespace KoMacroTest { + + /** + * Register KoMacroTest::CommonTests as TestSuite. + */ + + KUNITTEST_SUITE("KoMacroTestSuite"); + KUNITTEST_REGISTER_TESTER(ActionTests); + + + class ActionTests::Private + { + public: + /** + * An KXMLGUIClient instance created on @a setUp() and + * passed to the @a KoMacro::Manager to bridge to the + * app-functionality. + */ + KXMLGUIClient* xmlguiclient; + + /** + * An @a TestObject instance used internaly to test + * handling and communication with from QObject + * inheritated instances. + */ + TestAction* testaction; + + QDomDocument* doomdocument; + + KSharedPtr<KoMacro::Macro> macro; + + QValueList< KSharedPtr<KoMacro::MacroItem> > items; + + KSharedPtr<KoMacro::Action> actionptr; + + Private() + : xmlguiclient(0) + , testaction(0) + , doomdocument(0) + , macro(0) + , actionptr(0) + { + } + }; +} + +typedef QValueList< KSharedPtr<KoMacro::MacroItem> >::size_type sizetype; + + +ActionTests::ActionTests() + : KUnitTest::SlotTester() + , d( new Private() ) // create the private d-pointer instance. +{ +} + +ActionTests::~ActionTests() +{ + delete d->xmlguiclient; + delete d; +} + + +void ActionTests::setUp() +{ + d->xmlguiclient = new KXMLGUIClient(); + + if (::KoMacro::Manager::self() == 0) { + ::KoMacro::Manager::init( d->xmlguiclient ); + } + + d->testaction = new TestAction(); + ::KoMacro::Manager::self()->publishAction(d->testaction); + + d->doomdocument = new QDomDocument(); + + QString const xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\" >" + "<item action=\"testaction\" >" + "</item>" + "</macro>"); + + d->doomdocument->setContent(xml); + d->macro = KoMacro::Manager::self()->createMacro("testMacro"); + d->macro->parseXML(d->doomdocument->documentElement()); + d->macro->execute(this); + d->items = d->macro->items(); + d->actionptr = d->items[0]->action(); +} + +void ActionTests::tearDown() +{ + delete d->actionptr; + delete d->macro; + delete d->doomdocument; + delete d->xmlguiclient; +} + + +void ActionTests::testMacro() +{ + kdDebug()<<"===================== testMacro() ======================" << endl; + + //fetch Items and .. + //QValueList< KSharedPtr<KoMacro::MacroItem> >& items = d->macro->items(); + + //... check that there is one + KOMACROTEST_XASSERT( d->items.count(), sizetype(0) ); +} + +void ActionTests::testAction() +{ + kdDebug()<<"===================== testAction() ======================" << endl; + + //get it + //KSharedPtr<KoMacro::Action> actionptr = d->items[0]->action(); + //-> check that it is not null + KOMACROTEST_XASSERT(sizetype(d->actionptr.data()), sizetype(0)); +} + +void ActionTests::testText() +{ + kdDebug()<<"===================== testText() ======================" << endl; + + //KSharedPtr<KoMacro::Action> actionptr = items[0]->action(); + + const QString leetSpeech = "']['3 $']['"; + + //check i18n text + KOMACROTEST_ASSERT(d->actionptr->text(),QString("Test")); + //change it + d->actionptr->setText(leetSpeech); + //retest it + KOMACROTEST_ASSERT(d->actionptr->text(),QString(leetSpeech)); +} + + +void ActionTests::testName() +{ + kdDebug()<<"===================== testName() ======================" << endl; + + //KSharedPtr<KoMacro::Action> actionptr = items[0]->action(); + + //check name + KOMACROTEST_ASSERT(d->actionptr->name(),QString("testaction")); + //change it + d->actionptr->setName("ActionJackson"); + //retest it + KOMACROTEST_ASSERT(d->actionptr->name(),QString("ActionJackson")); +} + +void ActionTests::testComment() +{ + kdDebug()<<"===================== testComment() ======================" << endl; + + //KSharedPtr<KoMacro::Action> actionptr = items[0]->action(); + + //check comment + KOMACROTEST_XASSERT(d->actionptr->comment(),QString("No Comment!")); + //set comment + d->actionptr->setComment("Stringtest"); + //check comment again + KOMACROTEST_ASSERT(d->actionptr->comment(),QString("Stringtest")); +} + +#include "actiontests.moc" diff --git a/kexi/plugins/macros/tests/actiontests.h b/kexi/plugins/macros/tests/actiontests.h new file mode 100644 index 00000000..48b5a252 --- /dev/null +++ b/kexi/plugins/macros/tests/actiontests.h @@ -0,0 +1,89 @@ +/*************************************************************************** + * 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 KOMACROTEST_ACTIONTESTS_H +#define KOMACROTEST_ACTIONTESTS_H + +#include <kunittest/tester.h> + +namespace KoMacroTest { + + /** + * The common testsuite used to test common @a KoMacro + * functionality. + */ + class ActionTests : public KUnitTest::SlotTester + { + Q_OBJECT + public: + + /** + * Constructor. + */ + ActionTests(); + + /** + * Destructor. + */ + virtual ~ActionTests(); + + public slots: + + /** + * This slot got called by KUnitTest before testing + * starts. + */ + void setUp(); + + /** + * This slot got called by KUnitTest after all tests + * are done. + */ + void tearDown(); + + /** + * Subtest for the @a KoMacro::Action functionality. + */ + void testMacro(); + + /** + * Test the @a KoMacro::Action functionality. + */ + void testAction(); + + void testText(); + /** + * Subtest for the @a KoMacro::Action functionality. + */ + void testName(); + /** + * Subtest for the @a KoMacro::Action functionality. + */ + void testComment(); + + private: + /// @internal d-pointer class. + class Private; + /// @internal d-pointer instance. + Private* const d; + }; + +} + +#endif diff --git a/kexi/plugins/macros/tests/commontests.cpp b/kexi/plugins/macros/tests/commontests.cpp new file mode 100644 index 00000000..84c596aa --- /dev/null +++ b/kexi/plugins/macros/tests/commontests.cpp @@ -0,0 +1,907 @@ +/*************************************************************************** + * 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 "commontests.h" +#include "testobject.h" +#include "testaction.h" +#include "komacrotestbase.h" + +#include "../lib/action.h" +#include "../lib/function.h" +#include "../lib/manager.h" +#include "../lib/macro.h" +#include "../lib/variable.h" +#include "../lib/metaobject.h" +#include "../lib/metamethod.h" +#include "../lib/metaparameter.h" +#include "../lib/exception.h" +#include "../lib/macroitem.h" + +#include <ostream> +#include <climits> + +#include <qstringlist.h> +#include <qdom.h> + +#include <kdebug.h> +#include <kunittest/runner.h> +#include <kxmlguiclient.h> + +using namespace KUnitTest; +using namespace KoMacroTest; + +namespace KoMacroTest { + + /** + * Register KoMacroTest::CommonTests as TestSuite. + */ + KUNITTEST_SUITE("CommonTestsSuite") + KUNITTEST_REGISTER_TESTER(CommonTests); + + /** + * @internal d-pointer class to be more flexible on future extension of the + * functionality without to much risk to break the binary compatibility. + */ + class CommonTests::Private + { + public: + + /** + * An KXMLGUIClient instance created on @a setUp() and + * passed to the @a KoMacro::Manager to bridge to the + * app-functionality. + */ + KXMLGUIClient* xmlguiclient; + + /** + * An @a TestObject instance used internaly to test + * handling and communication with from QObject + * inheritated instances. + */ + TestObject* testobject; + + TestAction* testaction; + + QDomDocument* doomdocument; + + /** + * Constructor. + */ + Private() + : xmlguiclient(0) + , testobject(0) + , testaction(0) + , doomdocument(0) + { + } + }; + +} + +typedef QValueList< KSharedPtr<KoMacro::MacroItem> >::size_type sizetype; + +CommonTests::CommonTests() + : KUnitTest::SlotTester() + , d( new Private() ) // create the private d-pointer instance. +{ +} + +CommonTests::~CommonTests() +{ + delete d->xmlguiclient; + delete d; +} + +void CommonTests::setUp() +{ + d->xmlguiclient = new KXMLGUIClient(); + ::KoMacro::Manager::init( d->xmlguiclient ); + + d->testobject = new TestObject( this ); + ::KoMacro::Manager::self()->publishObject("TestObject", d->testobject); + + d->testaction = new TestAction(); + ::KoMacro::Manager::self()->publishAction(d->testaction); + + d->doomdocument = new QDomDocument(); + + QString const xml = QString("<!DOCTYPE macros>" + + "<macro xmlversion=\"1\">" + + "<item action=\"testaction\" >" + "</item>" + "</macro>"); + + d->doomdocument->setContent(xml); +} + +void CommonTests::tearDown() +{ + delete d->doomdocument; + delete d->testobject; + delete d->xmlguiclient; +} + +void CommonTests::testManager() +{ + kdDebug()<<"===================== testManager() ======================" << endl; + + //check if manager-guiClient equals xmlguiclient + KOMACROTEST_ASSERT( ::KoMacro::Manager::self()->guiClient(), d->xmlguiclient ); + //check if manger-object equals testobject + KOMACROTEST_ASSERT( dynamic_cast<TestObject*>( (QObject*)::KoMacro::Manager::self()->object("TestObject") ), d->testobject ); +} +/* +void CommonTests::testAction() +{ + const QString testString = "teststring"; + const QString testInt = "testint"; + const QString testBool = "testbool"; + + //TODO: CLEANUP!!!!!! + //TODO: test manipulation of action and macroitem and context. + + kdDebug()<<"===================== testAction() ======================" << endl; + + //Publish TestAction for the first time. + + QDomElement const domelement = d->doomdocument->documentElement(); + + KSharedPtr<KoMacro::Macro> macro = KoMacro::Manager::self()->createMacro("testMacro"); + + //Is our XML parseable ? + KOMACROTEST_ASSERT(macro->parseXML(domelement),true); + + //?? + macro->execute(this); + + //create list of KSharedPtr from the childs of the macro + QValueList< KSharedPtr<KoMacro::MacroItem> >& items = macro->items(); + + + //check that there is one + KOMACROTEST_ASSERT( items.count(), sizetype(1) ); + //fetch the first one + KSharedPtr<KoMacro::Action> actionptr = items[0]->action(); + //How do we know that an action exist ? + //-> check that it is not null + KOMACROTEST_XASSERT(sizetype(actionptr.data()), sizetype(0)); + //fetch the "teststring"-variable + KSharedPtr<KoMacro::Variable> variableptr = actionptr->variable("teststring"); + //check that it is not null + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + //check that it is " " + KOMACROTEST_ASSERT(variableptr->variant().toString(),QString("testString")); + + //fetch the "testint"-variable + variableptr = actionptr->variable("testint"); + //check that it is not null + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + //check that it is " " + KOMACROTEST_ASSERT(variableptr->variant().toInt(),int(0)); + + //fetch the "testbool"-variable + variableptr = actionptr->variable("testbool"); + //check that it is not null + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + //check that it is " " + KOMACROTEST_ASSERT(variableptr->variant().toBool(),true); + + actionptr->setVariable("teststring", "STRINGTEST", "TestString"); + variableptr = actionptr->variable("teststring"); + //check that it is not null + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + //check that it is " " + KOMACROTEST_ASSERT(variableptr->variant().toString(),QString("TestString")); + + actionptr->setVariable("testint","INTTEST",INT_MAX); + variableptr = actionptr->variable("testint"); + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + KOMACROTEST_ASSERT(sizetype(variableptr->variant().toInt()),sizetype(INT_MAX)); + + actionptr->setVariable("testbool","BOOLTEST", "false"); + variableptr = actionptr->variable("testbool"); + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + KOMACROTEST_ASSERT(variableptr->variant().toBool(),false); + + //create new macroitem for testing + KoMacro::MacroItem* macroitem = new KoMacro::MacroItem(); + //set the action + macroitem->setAction(d->testaction); + //append the macroitem to testitems + items.append(macroitem); + //increased ?? + KOMACROTEST_ASSERT( items.count(), sizetype(2) ); + + //Manipulate the macroitem + macroitem->setVariable("teststring", "TeStString"); + variableptr = macroitem->variable("teststring"); + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + KOMACROTEST_ASSERT(variableptr->variant().toString(),QString("TeStString")); + + macroitem->setVariable("testint",INT_MIN); + variableptr = macroitem->variable("testint"); + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + KOMACROTEST_ASSERT(sizetype(variableptr->variant().toInt()),sizetype(INT_MIN)); + + macroitem->setVariable("testint",-1); + variableptr = macroitem->variable("testint"); + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + KOMACROTEST_ASSERT(sizetype(variableptr->variant().toInt()),sizetype(-1)); + + + //commontests.cpp: In member function 'void KoMacroTest::CommonTests::testAction()': + //commontests.cpp:249: error: call of overloaded 'setVariable(const char [8], int)' is ambiguous + //../lib/macroitem.h:131: note: candidates are: QStringList KoMacro::MacroItem::setVariable(const QString&, KSharedPtr<KoMacro::Variable>) + //../lib/macroitem.h:137: note: QStringList KoMacro::MacroItem::setVariable(const QString&, const QVariant&) + + macroitem->setVariable("testint",(int) 0); + variableptr = macroitem->variable("testint"); + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + KOMACROTEST_ASSERT(sizetype(variableptr->variant().toInt()),sizetype(0)); + + + macroitem->setVariable("testint",1); + variableptr = macroitem->variable("testint"); + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + KOMACROTEST_ASSERT(sizetype(variableptr->variant().toInt()),sizetype(1)); + + macroitem->setVariable("testint",INT_MAX); + variableptr = macroitem->variable("testint"); + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + KOMACROTEST_ASSERT(sizetype(variableptr->variant().toInt()),sizetype(INT_MAX)); + + macroitem->setVariable("testbool","false"); + variableptr = macroitem->variable("testbool"); + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + KOMACROTEST_ASSERT(variableptr->variant().toBool(),false); + + //secondway for appending an macroitem + //add the manipulated macroitem + macro->addItem(macroitem); + //increased ?? + KOMACROTEST_ASSERT( items.count(), sizetype(3)); +} */ + +void CommonTests::testXmlhandler() +{ + kdDebug()<<"===================== testXmlhandler() ======================" << endl; + + // Local Init + KSharedPtr<KoMacro::Macro> macro = KoMacro::Manager::self()->createMacro("testMacro"); + QDomElement domelement; + + // Save old doomdocument + QString xmlOld = d->doomdocument->toString(); + + // Part 1: From XML to a Macro. + // Test-XML-document with normal allocated variables. + QString xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >testString</variable>" + "<variable name=\"testint\" >0</variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testbla\" >somethingwrong</variable>" // TODO Is here a kdDebug-msg enough? + "<variable name=\"testdouble\" >0.6</variable>" + "</item>" + "</macro>"); + // Set the XML-document with the above string. + d->doomdocument->setContent(xml); + domelement = d->doomdocument->documentElement(); + //Is our XML parseable ? + KOMACROTEST_ASSERT(macro->parseXML(domelement),true); + + // Test-XML-document with bad root element. + xml = QString("<!DOCTYPE macros>" + "<maro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >testString</variable>" + "<variable name=\"testint\" >0</variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" >0.6</variable>" + "</item>" + "</maro>"); + d->doomdocument->setContent(xml); + domelement = d->doomdocument->documentElement(); + KOMACROTEST_ASSERT(macro->parseXML(domelement),false); + + // Test-XML-document with wrong macro-xmlversion. + xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"2\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >testString</variable>" + "<variable name=\"testint\" >0</variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" >0.6</variable>" + "</item>" + "</macro>"); + d->doomdocument->setContent(xml); + domelement = d->doomdocument->documentElement(); + KOMACROTEST_ASSERT(macro->parseXML(domelement),false); + + // TODO Test-XML-document if it has a wrong structure like wrong parathesis + // or missing end tag (is this critical??). + /*xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >testString</variable>" + "<variable name=\"testint\" >0</variable>" + "<variable name=\"testbool\" >true</variable>" + "</item>" + "</macro>"); + d->doomdocument->setContent(xml); + domelement = d->doomdocument->documentElement(); + KOMACROTEST_ASSERT(macro->parseXML(domelement),false);*/ + + // Test-XML-document with wrong item- and variable-tags. + // TODO Could this happen?? + xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\">" + "<iem action=\"testaction\" >" + "<vle name=\"teststring\" >testString</variable>" + "<v name=\"testint\" >0</variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" >0.6</variable>" + "</item>" + "</macro>"); + d->doomdocument->setContent(xml); + domelement = d->doomdocument->documentElement(); + KOMACROTEST_ASSERT(macro->parseXML(domelement),true); //should be false? + + // TODO Test-XML-document with maximum field-size. + xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >testString</variable>" + "<variable name=\"testint\" > 0 </variable>" // the value should be INT_MAX + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" >0.6</variable>" // DBL_MAX + "</item>" + "</macro>"); + d->doomdocument->setContent(xml); + domelement = d->doomdocument->documentElement(); + KOMACROTEST_ASSERT(macro->parseXML(domelement),true); + + // TODO Test-XML-document with minimum field-size. + xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >testString</variable>" + "<variable name=\"testint\" >0</variable>" // INT_MIN + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" >0.6</variable>" // DBL_MIN + "</item>" + "</macro>"); + d->doomdocument->setContent(xml); + domelement = d->doomdocument->documentElement(); + KOMACROTEST_ASSERT(macro->parseXML(domelement),true); + + // TODO Part 2: Read the parsen macro and make a comparison to the XML-document. + + // TODO Part 3: From a Macro to XML. + + // RODO Part 4: Compare the transformed XML with the given macro. + + // Set back xml-string for other tests. + d->doomdocument->setContent(xmlOld); +} + +void CommonTests::testFunction() +{ +//TODO: CLEANUP!!!!!! +/* + kdDebug()<<"===================== testFunction() ======================" << endl; + + //create a QDomDocument + QDomDocument domdocument = QDomDocument(); + //create some data + QString const comment = "Describe what the function does"; + QString const name = "myfunc"; + QString const text = "My Function"; + QString const receiver = "TestObject"; + QString const argument1 = "Some string"; + int const argument2 = 12345; + + //set "Function"-content in QDocument + domdocument.setContent(QString( + "<function name=\"" + name + "\" text=\"" + text + "\" comment=\"" + comment + "\" receiver=\"" + receiver + "\" slot=\"myslot(const QString & , int)\">" + "<argument>" + argument1 + "</argument>" + "<argument>" + QString("%1").arg(argument2) + "</argument>" + "</function>" + )); + + //create an KomacroFunction with our data, and put it into a KSharedPtr + KSharedPtr<KoMacro::Action> functionptr = ::KoMacro::Manager::self()->createAction( domdocument.documentElement() ); + //cast KSharedPtr to KoMacro-"Function" + KoMacro::Function* func = dynamic_cast<KoMacro::Function*>( functionptr.data() ); + //check that function is not null + KOMACROTEST_XASSERT((int) func, 0); + + //check domElement + KOMACROTEST_ASSERT( func->domElement(), domdocument.documentElement() ); + //check name + KOMACROTEST_ASSERT( QString(func->name()), name ); + //check text + KOMACROTEST_ASSERT( func->text(), text ); + //check comment + KOMACROTEST_ASSERT( func->comment(), comment ); + //check receiver + KOMACROTEST_ASSERT( func->receiver(), receiver ); + //check slot (arguments) + KOMACROTEST_ASSERT( QString(func->slot()), QString("myslot(const QString&,int)") ); + + //create KoMacro-MetaObject from receiverObject + KSharedPtr<KoMacro::MetaObject> receivermetaobject = func->receiverObject(); + //check that receivermetaobject.data is not null + KOMACROTEST_XASSERT((int) receivermetaobject.data(), 0); + + //create KoMacro-MetaMethod from receiverObject + KSharedPtr<KoMacro::MetaMethod> receivermetamethod = receivermetaobject->slot( func->slot().latin1() ); + //check that receivermetamethod.data is not null + KOMACROTEST_XASSERT((int) receivermetamethod.data(), 0); + + //create list of variables from func + KoMacro::Variable::List funcvariables = func->variables(); + //counter for hardcoded tests see below ... + uint i = 0; + KoMacro::Variable::List::ConstIterator it, end( funcvariables.constEnd() ); + for( it = funcvariables.constBegin(); it != end; ++it) { + kdDebug() << "VARIABLE => " << (*it ? (*it)->toString() : "<NULL>") << endl; + //hardcoded test: + // firstrun we have a QString, secondrun we have an int + switch(i) { + case 0: { // returnvalue + KOMACROTEST_ASSERT(*it, KSharedPtr<KoMacro::Variable>(NULL)); + } break; + case 1: { // first parameter + //check first variable of func is the same as argument1 + //QString const argument1 = "Some string"; + KOMACROTEST_ASSERT((*it)->toString(), argument1); + } break; + case 2: { // second parameter + //check second variable of func is the same as argument2 + //int const argument2 = 12345; + KOMACROTEST_ASSERT((*it)->toInt(), argument2); + } break; + default: { + } break; + } + i++; + } + + //check that we have two arguments + one returnvalue in func + KOMACROTEST_ASSERT( funcvariables.count(), uint(3) ); + + // check that the first argument (the returnvalue) is empty + KOMACROTEST_ASSERT( funcvariables[0], KSharedPtr<KoMacro::Variable>(NULL) ); + + //create a KoMacro-Variable-Ptr from first func argument + KSharedPtr<KoMacro::Variable> stringvar = funcvariables[1]; + //check that it is not null + KOMACROTEST_XASSERT((int) stringvar.data(),0); + //check via QVariant type that stringvar is from Type Variant + KOMACROTEST_ASSERT( stringvar->type(), KoMacro::MetaParameter::TypeVariant ); + //check via metaparameter that variant is from type string + KOMACROTEST_ASSERT( stringvar->variantType(), QVariant::String ); + //chech that stringvar equals argument1 + KOMACROTEST_ASSERT( stringvar->toString(), argument1 ); + + //create a KoMacro-Variable-Ptr from second func argument + KSharedPtr<KoMacro::Variable> intvar = funcvariables[2]; + //check that it is not null + KOMACROTEST_XASSERT((int) intvar.data(), 0); + //check via QVariant type that stringvar is from Type Variant + KOMACROTEST_ASSERT( intvar->type(), KoMacro::MetaParameter::TypeVariant ); + //check that intvar is An String -> we create an string from int because of xml + KOMACROTEST_ASSERT( intvar->variantType(), QVariant::String ); + //check that intvar equals argument2 + KOMACROTEST_ASSERT( intvar->toInt(), argument2 ); + + //returnvalue see testobject .... + KSharedPtr<KoMacro::Variable> funcreturnvalue = receivermetamethod->invoke( funcvariables ); + kdDebug() << "CommonTests::testFunction() RETURNVALUE =====> " << funcreturnvalue->toString() << endl; + KOMACROTEST_ASSERT( funcreturnvalue->toInt(), argument2 ); + + //check returnvalue + //func->setReturnValue(new KoMacro::Variable("54321")); + //KOMACROTEST_ASSERT( func->returnValue()->toString(), QString("54321") ); +*/ +} + +void CommonTests::testIntFunction() +{ +//TODO: CLEANUP!!!!!! +/* + kdDebug()<<"===================== testIntFunction() ======================" << endl; + + //create a QDomDocument + QDomDocument domdocument = QDomDocument(); + + //set "Function"-content in QDocument + domdocument.setContent(QString( + "<function name=\"myfunc\" text=\"My Function\" comment=\"comment\" receiver=\"TestObject\" slot=\"myslot(const QString & , int)\">" + "<argument>Some string</argument>" + "<argument>12345</argument>" + "</function>" + )); + + //create an KomacroFunction with our data, and put it into a KSharedPtr + KSharedPtr<KoMacro::Action> functionptr = ::KoMacro::Manager::self()->createAction( domdocument.documentElement() ); + //Cast data to function + KoMacro::Function* func = dynamic_cast<KoMacro::Function*>( functionptr.data() ); + //check that it is not null + KOMACROTEST_XASSERT((int) func, 0); + //execute the function + func->activate(); + //Check returnvalue is same value we entered + //KOMACROTEST_ASSERT(func->returnValue()->toString(),QString("12345")); +*/ +} + +void CommonTests::testDoubleFunction() +{ +//TODO: CLEANUP!!!!!! +/* + kdDebug()<<"===================== testDoubleFunction() ======================" << endl; + + //create a QDomDocument + QDomDocument domdocument = QDomDocument(); + + //set "Function"-content in QDocument + domdocument.setContent(QString( + "<function name=\"myfunc\" text=\"My Function\" comment=\"comment\" receiver=\"TestObject\" slot=\"myslot(const QString & , double)\">" + "<argument>Some string</argument>" + "<argument>12.56</argument>" + "</function>" + )); + + //create an KomacroFunction with our data, and put it into a KSharedPtr + KSharedPtr<KoMacro::Action> functionptr = ::KoMacro::Manager::self()->createAction( domdocument.documentElement() ); + //Cast data to function + KoMacro::Function* func = dynamic_cast<KoMacro::Function*>( functionptr.data() ); + //check that it is not null + KOMACROTEST_XASSERT((int) func, 0); + //execute the function + func->activate(); + //Check returnvalue is same value we entered + //KOMACROTEST_ASSERT(func->returnValue()->toString(),QString("12.56")); +*/ +} + +void CommonTests::testQStringFunction() +{ +//TODO: CLEANUP!!!!!! +/* + kdDebug()<<"===================== testQStringFunction() ======================" << endl; + + //create a QDomDocument + QDomDocument domdocument = QDomDocument(); + + //set "Function"-content in QDocument + domdocument.setContent(QString( + "<function name=\"myfunc\" text=\"My Function\" comment=\"comment\" receiver=\"TestObject\" slot=\"myslot(const QString &)\">" + "<argument>Some string</argument>" + "</function>" + )); + + //create an KomacroFunction with our data, and put it into a KSharedPtr + KSharedPtr<KoMacro::Action> functionptr = ::KoMacro::Manager::self()->createAction( domdocument.documentElement() ); + //Cast data to function + KoMacro::Function* func = dynamic_cast<KoMacro::Function*>( functionptr.data() ); + //check that it is not null + KOMACROTEST_XASSERT((int) func, 0); + //execute the function func->activate(); + //Check returnvalue is same value we entered + //KOMACROTEST_ASSERT(func->returnValue()->toString(),QString("Some string")); +*/ +} + +void CommonTests::testMacro() +{ +//TODO: CLEANUP!!!!!! + kdDebug()<<"===================== testMacro() ======================" << endl; + + QDomElement const domelement = d->doomdocument->documentElement(); + + KSharedPtr<KoMacro::Macro> macro = KoMacro::Manager::self()->createMacro("testMacro"); + //Is our XML parseable ? + KOMACROTEST_ASSERT(macro->parseXML(domelement),true); + +// //create a QDomDocument +// QDomDocument domdocument = QDomDocument(); +// +// //Fully fleged content this time with macro,function and action +// domdocument.setContent(QString( +// "<macro name=\"mymacro\" icon=\"myicon\" text=\"My Macro\" comment=\"Some comment to describe the Macro.\">" +// "<action name=\"myaction\" text=\"My Action\" comment=\"Just some comment\" />" +// "<function name=\"myfunc\" text=\"My Function\" comment=\"Describe what the function does\" receiver=\"TestObject\" slot=\"myslot(const QString &)\">" +// "<argument>The myfunc argument string</argument>" +// "</function>" +// "</macro>" +// )); +// +// //create Macro +// // KSharedPtr<KoMacro::Action> macroptr = ::KoMacro::Manager::self()->createAction( domdocument.documentElement() ); +// //cast data to Macro +// KoMacro::Macro* macro = dynamic_cast<KoMacro::Macro*>( macroptr.data() ); + //check that it is not null + KOMACROTEST_XASSERT(sizetype(macro.data()), sizetype(0)); + //check that domeElement given to manager is the sam as in the macro +// KOMACROTEST_ASSERT( macro->toXML(), d->doomdocument->documentElement() ); + //check the name + KOMACROTEST_ASSERT( QString(macro->name()), QString("testMacro") ); + + /** + @deprecated values no longer exist + + //check the text + KOMACROTEST_ASSERT( macro->text(), QString("My Macro") ); + //check iconname + KOMACROTEST_ASSERT( QString(macro->icon()), QString("myicon") ); + //check comment + KOMACROTEST_ASSERT( macro->comment(), QString("Some comment to describe the Macro.") ); + */ + + //create list of KsharedPtr from the childs of the macro + QValueList< KSharedPtr<KoMacro::MacroItem> >& items = macro->items(); + //check that there is one + KOMACROTEST_ASSERT( items.count(), sizetype(1) ); + //fetch the first one + KSharedPtr<KoMacro::Action> actionptr = items[0]->action(); + //How do we know that an action exist ? + //-> check that it is not null + KOMACROTEST_XASSERT(sizetype(actionptr.data()), sizetype(0)); + //check that it has the right name + KOMACROTEST_ASSERT( QString(actionptr->name()), QString("testaction") ); + //check that it has the right text + KOMACROTEST_ASSERT( actionptr->text(), QString("Test") ); + //check that it has the right comment +// KOMACROTEST_ASSERT( actionptr->comment(), QString("") ); +/* + //fetch the second one + KSharedPtr<KoMacro::Action> myfuncptr = children[1]; + //cast it to function + + KoMacro::Function* myfunc = dynamic_cast<KoMacro::Function*>( myfuncptr.data() ); + //check that it isn?t null + KOMACROTEST_XASSERT((int) myfunc, 0); + + //check it?s name + KOMACROTEST_ASSERT( QString(myfunc->name()), QString("myfunc")); + + //check it?s text + KOMACROTEST_ASSERT( myfunc->text(), QString("My Function") ); + //check it?s comment + KOMACROTEST_ASSERT( myfunc->comment(), QString("Describe what the function does") ); + //check it?s receiver object + KOMACROTEST_ASSERT( myfunc->receiver(), QString("TestObject") ); + //check it?s slot + KOMACROTEST_ASSERT( myfunc->slot(), QString("myslot(const QString&)") ); + + //exceute it + myfunc->activate(); +*/ + //create another macro + KSharedPtr<KoMacro::Macro> yanMacro = KoMacro::Manager::self()->createMacro("testMacro2"); + + KOMACROTEST_ASSERT(yanMacro->parseXML(domelement),true); + //create two more macros + //KSharedPtr<KoMacro::Action> yanActionptr2 = ::KoMacro::Manager::self()->createAction( domdocument.documentElement() ); + //KSharedPtr<KoMacro::Action> yanActionptr3 = ::KoMacro::Manager::self()->createAction( domdocument.documentElement() ); + + //check that they aren?t null + KOMACROTEST_XASSERT(sizetype(yanMacro.data()), sizetype(0)); + //KOMACROTEST_XASSERT((int) yanActionptr2.data(), 0); + //KOMACROTEST_XASSERT((int) yanActionptr3.data(), 0); + + //create a list of the children from yanMacro + //QValueList< KSharedPtr<KoMacro::Action> > yanChildren = yanMacro->children(); + //check that there are two + //KOMACROTEST_ASSERT(yanChildren.count(), uint(2)); +/* + { + //keep oldsize + const int oldsize = yanChildren.count(); + //add a new child to the macro + yanMacro->addChild(yanActionptr2); + //get the children + yanChildren = yanMacro->children(); + //get count of children + const int size = yanChildren.count(); + //check count has changed + KOMACROTEST_XASSERT(size, oldsize); + } + + { + //keep oldsize + const int oldsize = yanChildren.count(); + //add a new child to the macro + yanMacro->addChild(yanActionptr3); + //get the children + yanChildren = yanMacro->children(); + //get count of children + const int size = yanChildren.count(); + //check count has changed + KOMACROTEST_XASSERT(size, oldsize); + //check the hasChildren function + KOMACROTEST_ASSERT(yanMacro->hasChildren(), true); + } +*/ + +} + +void CommonTests::testDom() { +//TODO: CLEANUP!!!!!! + kdDebug()<<"===================== testDom() ======================" << endl; +/* + //create a QDomDocument + QDomDocument domdocument = QDomDocument(); + //create data for various documents + QString const comment = "Describe what the function does"; + QString const name = "myfunc"; + QString const text = "My Function"; + QString const receiver1 = "TestObject"; + QString const receiver2 = "GibtsNich"; + + //create wrong Argument tag + domdocument.setContent(QString( + "<function name=\"" + name + "\" text=\"" + text + "\" comment=\"" + comment + "\" receiver=\"" + receiver1 + "\" slot=\"myslot(const QString & , int)\">" + "<Arg0ment>Some string</Arg0ment>" + "<Arg0ment>12345</Arg0ment>" + "</function>" + )); + //create functiom + KSharedPtr<KoMacro::Action> macroptr = ::KoMacro::Manager::self()->createAction( domdocument.documentElement() ); + //try to execute function and catch exception + KOMACROTEST_ASSERTEXCEPTION(KoMacro::Exception&, macroptr->activate()); + + //create wrong receiver + domdocument.setContent(QString( + "<function name=\"" + name + "\" text=\"" + text + "\" comment=\"" + comment + "\" receiver=\"" + receiver2 + "\" slot=\"myslot(const QString & , int)\">" + "<argument>Some string</argument>" + "<argument>12345</argument>" + "</function>" + )); + //create function + macroptr = ::KoMacro::Manager::self()->createAction( domdocument.documentElement() ); + //try to execute function and catch exception + KOMACROTEST_ASSERTEXCEPTION(KoMacro::Exception&, macroptr->activate()); + + //create "wrong" number of parameters + domdocument.setContent(QString( + "<function name=\"" + name + "\" text=\"" + text + "\" comment=\"" + comment + "\" receiver=\"" + receiver1 + "\" slot=\"myslot(const QString & , int, double)\">" + "<argument>Some string</argument>" + "<argument>12345</argument>" + "<argument>12345.25</argument>" + "</function>" + )); + //create function + macroptr = ::KoMacro::Manager::self()->createAction( domdocument.documentElement() ); + //try to execute function and catch exception + KOMACROTEST_ASSERTEXCEPTION(KoMacro::Exception&, macroptr->activate()); + + //create wrong function tag + domdocument.setContent(QString( + "<NoFunction name=\"" + name + "\" text=\"" + text + "\" comment=\"" + comment + "\" receiver=\"" + receiver1 + "\" slot=\"myslot(const QString & , int, double)\">" + "<argument>Some string</argument>" + "<argument>12345</argument>" + "<argument>12345.25</argument>" + "</NoFunction>" + )); + //try to create function and catch exception + KOMACROTEST_ASSERTEXCEPTION(KoMacro::Exception&, macroptr = ::KoMacro::Manager::self()->createAction( domdocument.documentElement() )); + + //create empty function + domdocument.setContent(QString( + "<function name=\"\" text=\"\" comment=\"\" receiver=\"\" slot=\"\">" + "<argument> </argument>" + "<argument> </argument>" + "<argument> </argument>" + "</function>" + )); + //create function + macroptr = ::KoMacro::Manager::self()->createAction( domdocument.documentElement() ); + //try to execute function and catch exception + KOMACROTEST_ASSERTEXCEPTION(KoMacro::Exception&, macroptr->activate()); + + + //create empty function + domdocument.setContent(QString( + "<function>" + "</function>" + )); + //create function + macroptr = ::KoMacro::Manager::self()->createAction( domdocument.documentElement() ); + //try to execute function and catch exception + KOMACROTEST_ASSERTEXCEPTION(KoMacro::Exception&, macroptr->activate()); +*/ +} + +void CommonTests::testVariables() +{ +//TODO: CLEANUP!!!!!! + kdDebug()<<"===================== testVariables() ======================" << endl; +/* + //create a QDomDocument + QDomDocument domdocument = QDomDocument(); + //create data + domdocument.setContent(QString( + "<macro name=\"mymacro123\" text=\"My Macro 123\">" + "<function name=\"func1\" text=\"Function1\" receiver=\"TestObject\" slot=\"myslot(const QString &)\" >" + "<argument>$MyArgumentVariable</argument>" + "<return>$MyReturnVariable</return>" + "</function>" + "</macro>" + )); + + //create an macro + KSharedPtr<KoMacro::Action> macroptr = ::KoMacro::Manager::self()->createAction( domdocument.documentElement() ); + //cast data to macro + KoMacro::Macro* macro = dynamic_cast<KoMacro::Macro*>( macroptr.data() ); + //check that it is not null + KOMACROTEST_XASSERT((int) macro, 0); + + //create a list of its children + QValueList< KSharedPtr<KoMacro::Action> > children = macro->children(); + //Check that there are two children. The first child is always the returnvalue. + KOMACROTEST_ASSERT( children.count(), uint(2) ); + //fetch the children + KSharedPtr<KoMacro::Action> func1ptr = children[1]; + + //create new context + KSharedPtr<KoMacro::Context> context = new KoMacro::Context(macroptr); + + { + //try to execute function with non-functional variable + KOMACROTEST_ASSERTEXCEPTION(KoMacro::Exception&, func1ptr->activate(context)); + + KOMACROTEST_ASSERTEXCEPTION(KoMacro::Exception&, context->variable("$MyReturnVariable333")); + } + + { + //set variable to be a QString + context->setVariable("$MyArgumentVariable", new KoMacro::Variable("Some string")); + //execute function + func1ptr->activate(context); + //fetch return value + KSharedPtr<KoMacro::Variable> returnvariable = context->variable("$MyReturnVariable"); + //check that it is not null + KOMACROTEST_XASSERT( (int) returnvariable.data(), 0); + //check that it is "Some String" + KOMACROTEST_ASSERT(returnvariable->toString(),QString("Some string")); + } + + { + //set variable to be an Int + context->setVariable("$MyArgumentVariable", new KoMacro::Variable( 12345 )); + //execute function + func1ptr->activate(context); + //fetch return value + KSharedPtr<KoMacro::Variable> returnvariable = context->variable("$MyReturnVariable"); + //check that it is not null + KOMACROTEST_XASSERT( (int) returnvariable.data(), 0); + //check that it is 12345 + KOMACROTEST_ASSERT(returnvariable->toInt(),12345); + } +*/ +} + +#include "commontests.moc" diff --git a/kexi/plugins/macros/tests/commontests.h b/kexi/plugins/macros/tests/commontests.h new file mode 100644 index 00000000..a3199ce2 --- /dev/null +++ b/kexi/plugins/macros/tests/commontests.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 KOMACROTEST_COMMONTESTS_H +#define KOMACROTEST_COMMONTESTS_H + +#include <kunittest/tester.h> + +namespace KoMacroTest { + + /** + * The common testsuite used to test common @a KoMacro + * functionality. + */ + class CommonTests : public KUnitTest::SlotTester + { + Q_OBJECT + public: + + /** + * Constructor. + */ + CommonTests(); + + /** + * Destructor. + */ + virtual ~CommonTests(); + + public slots: + + /** + * This slot got called by KUnitTest before testing + * starts. + */ + void setUp(); + + /** + * This slot got called by KUnitTest after all tests + * are done. + */ + void tearDown(); + + /** + * Test the @a KoMacro::Manager functionality. + */ + void testManager(); + + /** + * Test the @a KoMacro::Action functionality. + */ + //void testAction(); + + /** + * Test the @a KoMacro::XmlHandler functionality. + */ + void testXmlhandler(); + + /** + * Test the @a KoMacro::Function functionality. + */ + void testFunction(); + + /** + * Test the @a KoMacro::Function functionality with an int. + */ + void testIntFunction(); + + /** + * Test the @a KoMacro::Function functionality with a double. + */ + void testDoubleFunction(); + + /** + * Test the @a KoMacro::Function functionality with a QString. + */ + void testQStringFunction(); + + /** + * Test the @a KoMacro::Macro functionality. + */ + void testMacro(); + + /** + * Test the @a KoMacro::Dom functionality. + */ + void testDom(); + /** + * Test the @a KoMacro::Variable functionality. + */ + void testVariables(); + + private: + /// @internal d-pointer class. + class Private; + /// @internal d-pointer instance. + Private* const d; + }; + +} + +#endif diff --git a/kexi/plugins/macros/tests/komacrotest.cpp b/kexi/plugins/macros/tests/komacrotest.cpp new file mode 100644 index 00000000..55d017a9 --- /dev/null +++ b/kexi/plugins/macros/tests/komacrotest.cpp @@ -0,0 +1,58 @@ +/*************************************************************************** + * 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 <kaboutdata.h> +#include <kapplication.h> +#include <kcmdlineargs.h> +#include <klocale.h> +#include <kunittest/runner.h> + +static const char description[] = + I18N_NOOP("KoMacroTester"); +static const char version[] = "0.1"; +static KCmdLineOptions options[] = +{ + KCmdLineLastOption +}; + +int main( int argc, char** argv ) +{ + try { + KAboutData about("KoMacroTester", + I18N_NOOP("KoMacroTester"), + version, + description, + KAboutData::License_LGPL, + "(C) 2005 Sebastian Sauer", 0, 0, "mail@dipe.org"); + + KCmdLineArgs::init(argc, argv, &about); + KCmdLineArgs::addCmdLineOptions( options ); + KApplication app; + + //create an new "Console"-runner + KUnitTest::Runner * runner = KUnitTest::Runner::self(); + //start our Testsuite + runner->runTests(); + //done + return 0; + } + // mmh seems we forgot to catch an exception... + catch(...) { + qFatal("Unhandled Exception!"); + } +} diff --git a/kexi/plugins/macros/tests/komacrotestbase.h b/kexi/plugins/macros/tests/komacrotestbase.h new file mode 100644 index 00000000..d423e086 --- /dev/null +++ b/kexi/plugins/macros/tests/komacrotestbase.h @@ -0,0 +1,90 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org) + * + * 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 KOMACROTEST_BASE_H +#define KOMACROTEST_BASE_H + +//Our own extended Macros from KUnittest +/** +* Macro to perform an equality check and exits the method if the check failed. +* +* @param actual The actual value. +* @param expected The expected value. +*/ +#define KOMACROTEST_ASSERT(actual, expected) \ + { \ + std::cout << QString("Testing: %1 == %2").arg(#actual).arg(#expected).latin1() << std::endl; \ + check( __FILE__, __LINE__, #actual, actual, expected, false ); \ + if(actual != expected) \ + { \ + kdWarning() << QString("==============> FAILED") << endl; \ + return; \ + } \ + } + +/** +* Macro to perform a check that is expected to fail and that exits the method if the check failed. +* +* @param actual The actual value. +* @param notexpected The not expected value. +*/ +#define KOMACROTEST_XASSERT(actual, notexpected) \ + { \ + std::cout << QString("Testing: %1 != %2").arg(#actual).arg(#notexpected).latin1() << std::endl; \ + check( __FILE__, __LINE__, #actual, actual, notexpected, true ); \ + if(actual == notexpected) \ + { \ + kdWarning() << QString("==============> FAILED") << endl; \ + return; \ + } \ + } + +/** +* Macro to test that @p expression throws an exception that is catched with the +* @p exceptionCatch exception. +* +* @param exceptionCatch The exception that is expected to be thrown. +* @param expression The expression that is executed within a try-catch block to +* check for the @p exceptionCatch . +*/ +#define KOMACROTEST_ASSERTEXCEPTION(exceptionCatch, expression) \ + { \ + try { \ + expression; \ + } \ + catch(exceptionCatch) { \ + setExceptionRaised(true); \ + } \ + if(exceptionRaised()) { \ + success(QString(__FILE__) + "[" + QString::number(__LINE__) + "]: passed " + #expression); \ + setExceptionRaised(false); \ + } \ + else { \ + failure(QString(__FILE__) + "[" + QString::number(__LINE__) + QString("]: failed to throw an exception on: ") + #expression); \ + return; \ + } \ + } + +#endif + +//Used more tha once at various places +//names of variables from testaction +namespace KoMacroTest { + static const QString TESTSTRING = "teststring"; + static const QString TESTINT = "testint"; + static const QString TESTBOOL = "testbool"; +} diff --git a/kexi/plugins/macros/tests/komacrotestgui.cpp b/kexi/plugins/macros/tests/komacrotestgui.cpp new file mode 100644 index 00000000..abf4459d --- /dev/null +++ b/kexi/plugins/macros/tests/komacrotestgui.cpp @@ -0,0 +1,60 @@ +/*************************************************************************** + * 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 <kaboutdata.h> +#include <kapplication.h> +#include <kcmdlineargs.h> +#include <klocale.h> + +#include "kunittest/runnergui.h" + +static const char description[] = + I18N_NOOP("KoMacroTestgui."); + +static const char version[] = "0.1"; + +static const KCmdLineOptions options[] = +{ + KCmdLineLastOption +}; + +int main( int argc, char** argv ) +{ + try { + KAboutData const about("KomacroTests", I18N_NOOP("KomacroTests"), version, description, + KAboutData::License_LGPL, "(C) 2005 Tobi Krebs", 0, 0, + "Tobi.Krebs@gmail.com"); + + KCmdLineArgs::init(argc, argv, &about); + KCmdLineArgs::addCmdLineOptions( options ); + //create new kapplication + KApplication app; + //create new kunitrunnergui + KUnitTest::RunnerGUI runner(0); + //show the ui + runner.show(); + //set ui mainwidget + app.setMainWidget(&runner); + //return exitcode of ui + return app.exec(); + } + // mmh seems we forgot to catch an exception... + catch(...) { + qFatal("Unhandled Exception!"); + } +} diff --git a/kexi/plugins/macros/tests/macroitemtests.cpp b/kexi/plugins/macros/tests/macroitemtests.cpp new file mode 100644 index 00000000..366318e1 --- /dev/null +++ b/kexi/plugins/macros/tests/macroitemtests.cpp @@ -0,0 +1,243 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * + * 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 "macroitemtests.h" +#include "testaction.h" +#include "komacrotestbase.h" + +#include "../lib/action.h" +#include "../lib/manager.h" +#include "../lib/macro.h" +#include "../lib/variable.h" +#include "../lib/metaobject.h" +#include "../lib/metamethod.h" +#include "../lib/metaparameter.h" +#include "../lib/exception.h" +#include "../lib/macroitem.h" + +#include <ostream> + +#include <qstringlist.h> +#include <qdom.h> + +#include <kdebug.h> +#include <kunittest/runner.h> +#include <kxmlguiclient.h> + +using namespace KUnitTest; +using namespace KoMacroTest; + +namespace KoMacroTest { + + /** + * Register KoMacroTest::CommonTests as TestSuite. + */ + + KUNITTEST_SUITE("KoMacroTestSuite"); + KUNITTEST_REGISTER_TESTER(MacroitemTests); + + + class MacroitemTests::Private + { + public: + /** + * An KXMLGUIClient instance created on @a setUp() and + * passed to the @a KoMacro::Manager to bridge to the + * app-functionality. + */ + KXMLGUIClient* xmlguiclient; + + /** + * An @a TestObject instance used internaly to test + * handling and communication with from QObject + * inheritated instances. + */ + TestAction* testaction; + + QDomDocument* doomdocument; + + KSharedPtr<KoMacro::Macro> macro; + + Private() + : xmlguiclient(0) + , testaction(0) + , doomdocument(0) + , macro(0) + { + } + }; +} + +typedef QValueList< KSharedPtr<KoMacro::MacroItem> >::size_type sizetype; + +MacroitemTests::MacroitemTests() + : KUnitTest::SlotTester() + , d( new Private() ) // create the private d-pointer instance. +{ +} + +MacroitemTests::~MacroitemTests() +{ + delete d->xmlguiclient; + delete d; +} + +void MacroitemTests::setUp() +{ + d->xmlguiclient = new KXMLGUIClient(); + + if (::KoMacro::Manager::self() == 0) { + ::KoMacro::Manager::init( d->xmlguiclient ); + } + + d->testaction = new TestAction(); + ::KoMacro::Manager::self()->publishAction(d->testaction); + + d->doomdocument = new QDomDocument(); + + QString const xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\" >" + "<item action=\"testaction\" >" + "</item>" + "</macro>"); + + d->doomdocument->setContent(xml); + d->macro = KoMacro::Manager::self()->createMacro("testMacro"); + d->macro->parseXML(d->doomdocument->documentElement()); + d->macro->execute(this); +} + +void MacroitemTests::tearDown() +{ + delete d->macro; + delete d->doomdocument; + delete d->xmlguiclient; +} + + +void MacroitemTests::testMacro() +{ + kdDebug()<<"===================== testMacroitem() ======================" << endl; + kdDebug()<<"===================== testMacro() ======================" << endl; + + //fetch Items and .. + QValueList< KSharedPtr<KoMacro::MacroItem> >& items = d->macro->items(); + + //... check that there is one + KOMACROTEST_XASSERT( items.count(), sizetype(0) ); +} + +void MacroitemTests::testMacroItemString() +{ + + + kdDebug()<<"===================== testMacroItemString() ======================" << endl; + + QValueList< KSharedPtr<KoMacro::MacroItem> >& items = d->macro->items(); + KSharedPtr<KoMacro::Action> actionptr = items[0]->action(); + KSharedPtr<KoMacro::Variable> variableptr = actionptr->variable(TESTSTRING); + + //create new macroitem for testing + KoMacro::MacroItem* macroitem = new KoMacro::MacroItem(); + //set the action + macroitem->setAction(d->testaction); + + //append the macroitem to testitems + items.append(macroitem); + + //increased ?? + KOMACROTEST_ASSERT( items.count(), sizetype(2) ); + + //Manipulate the macroitem + macroitem->setVariable(TESTSTRING, "TeStString"); + variableptr = macroitem->variable(TESTSTRING); + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + KOMACROTEST_ASSERT(variableptr->variant().toString(),QString("TeStString")); + + + //secondway for appending an macroitem + //add the manipulated macroitem + d->macro->addItem(macroitem); + + //increased ?? + KOMACROTEST_ASSERT( items.count(), sizetype(3)); + +} + +void MacroitemTests::testMacroItemInt() +{ + + + kdDebug()<<"===================== testMacroItemInt() ======================" << endl; + + QValueList< KSharedPtr<KoMacro::MacroItem> >& items = d->macro->items(); + KSharedPtr<KoMacro::Action> actionptr = items[0]->action(); + + //create new macroitem for testing + KoMacro::MacroItem* macroitem = new KoMacro::MacroItem(); + //set the action + macroitem->setAction(d->testaction); + items.append(macroitem); + + macroitem->setVariable(TESTINT,INT_MIN); + KSharedPtr<KoMacro::Variable> variableptr = macroitem->variable(TESTINT); + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + KOMACROTEST_ASSERT(sizetype(variableptr->variant().toInt()),sizetype(INT_MIN)); + + macroitem->setVariable(TESTINT,-1); + variableptr = macroitem->variable(TESTINT); + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + KOMACROTEST_ASSERT(sizetype(variableptr->variant().toInt()),sizetype(-1)); + + macroitem->setVariable(TESTINT,QVariant(0)); + variableptr = macroitem->variable(TESTINT); + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + KOMACROTEST_ASSERT(sizetype(variableptr->variant().toInt()),sizetype(0)); + + macroitem->setVariable(TESTINT,1); + variableptr = macroitem->variable(TESTINT); + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + KOMACROTEST_ASSERT(sizetype(variableptr->variant().toInt()),sizetype(1)); + + macroitem->setVariable(TESTINT,INT_MAX); + variableptr = macroitem->variable(TESTINT); + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + KOMACROTEST_ASSERT(sizetype(variableptr->variant().toInt()),sizetype(INT_MAX)); +} + +void MacroitemTests::testMacroItemBool() +{ + + + kdDebug()<<"===================== testMacroItemBool() ======================" << endl; + + QValueList< KSharedPtr<KoMacro::MacroItem> >& items = d->macro->items(); + KSharedPtr<KoMacro::Action> actionptr = items[0]->action(); + + //create new macroitem for testing + KoMacro::MacroItem* macroitem = new KoMacro::MacroItem(); + //set the action + macroitem->setAction(d->testaction); + items.append(macroitem); + + macroitem->setVariable(TESTBOOL,"false"); + KSharedPtr<KoMacro::Variable> variableptr = macroitem->variable(TESTBOOL); + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + KOMACROTEST_ASSERT(variableptr->variant().toBool(),false); +} +#include "macroitemtests.moc" diff --git a/kexi/plugins/macros/tests/macroitemtests.h b/kexi/plugins/macros/tests/macroitemtests.h new file mode 100644 index 00000000..3e44eebd --- /dev/null +++ b/kexi/plugins/macros/tests/macroitemtests.h @@ -0,0 +1,87 @@ +/*************************************************************************** + * 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 KOMACROTEST_ACTIONTESTS_H +#define KOMACROTEST_ACTIONTESTS_H + +#include <kunittest/tester.h> + +namespace KoMacroTest { + + /** + * The common testsuite used to test common @a KoMacro + * functionality. + */ + class MacroitemTests : public KUnitTest::SlotTester + { + Q_OBJECT + public: + + /** + * Constructor. + */ + MacroitemTests(); + + /** + * Destructor. + */ + virtual ~MacroitemTests(); + + public slots: + + /** + * This slot got called by KUnitTest before testing + * starts. + */ + void setUp(); + + /** + * This slot got called by KUnitTest after all tests + * are done. + */ + void tearDown(); + + /** + * Subtest for the @a KoMacro::Action functionality. + */ + void testMacro(); + + /** + * Subtest for the @a KoMacro::Action functionality. + */ + void testMacroItemString(); + /** + * Subtest for the @a KoMacro::Action functionality. + */ + void testMacroItemInt(); + /** + * Subtest for the @a KoMacro::Action functionality. + */ + void testMacroItemBool(); + + private: + /// @internal d-pointer class. + class Private; + /// @internal d-pointer instance. + Private* const d; + }; + +} + +#endif diff --git a/kexi/plugins/macros/tests/macrotests.cpp b/kexi/plugins/macros/tests/macrotests.cpp new file mode 100644 index 00000000..ed222df2 --- /dev/null +++ b/kexi/plugins/macros/tests/macrotests.cpp @@ -0,0 +1,192 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * + * 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 "macrotests.h" +#include "testobject.h" +#include "testaction.h" +#include "komacrotestbase.h" + +#include "../lib/action.h" +#include "../lib/function.h" +#include "../lib/manager.h" +#include "../lib/macro.h" +#include "../lib/variable.h" +#include "../lib/metaobject.h" +#include "../lib/metamethod.h" +#include "../lib/metaparameter.h" +#include "../lib/exception.h" +#include "../lib/macroitem.h" + +#include <ostream> + +#include <qstringlist.h> +#include <qdom.h> + +#include <kdebug.h> +#include <kunittest/runner.h> +#include <kxmlguiclient.h> + +using namespace KUnitTest; +using namespace KoMacroTest; + +namespace KoMacroTest { + + /** + * Register KoMacroTest::CommonTests as TestSuite. + */ + KUNITTEST_SUITE("KoMacroTestSuite") + KUNITTEST_REGISTER_TESTER(MacroTests); + + class MacroTests::Private + { + public: + /** + * An KXMLGUIClient instance created on @a setUp() and + * passed to the @a KoMacro::Manager to bridge to the + * app-functionality. + */ + KXMLGUIClient* xmlguiclient; + + /** + * An @a TestObject instance used internaly to test + * handling and communication with from QObject + * inheritated instances. + */ + TestObject* testobject; + + TestAction* testaction; + + QDomDocument* doomdocument; + + Private() + : xmlguiclient(0) + , testobject(0) + , testaction(0) + , doomdocument(0) + { + } + }; +} + +typedef QValueList< KSharedPtr<KoMacro::MacroItem> >::size_type sizetype; + + +MacroTests::MacroTests() + : KUnitTest::SlotTester() + , d( new Private() ) // create the private d-pointer instance. +{ +} + +MacroTests::~MacroTests() +{ + delete d->xmlguiclient; + delete d; +} + + +void MacroTests::setUp() +{ + d->xmlguiclient = new KXMLGUIClient(); + //::KoMacro::Manager::init( d->xmlguiclient ); + if (::KoMacro::Manager::self() == 0) { + ::KoMacro::Manager::init( d->xmlguiclient ); + } + d->testobject = new TestObject( this ); + ::KoMacro::Manager::self()->publishObject("TestObject", d->testobject); + + d->testaction = new TestAction(); + ::KoMacro::Manager::self()->publishAction(d->testaction); + + d->doomdocument = new QDomDocument(); + + QString const xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\" >" + "<item action=\"testaction\" >" + "</item>" + "</macro>"); + + d->doomdocument->setContent(xml); +} + +void MacroTests::tearDown() +{ + delete d->doomdocument; + delete d->testobject; + delete d->xmlguiclient; +} + +void MacroTests::testMacro() +{ + kdDebug()<<"===================== testMacro() ======================" << endl; + + QDomElement const domelement = d->doomdocument->documentElement(); + + KSharedPtr<KoMacro::Macro> macro1 = KoMacro::Manager::self()->createMacro("testMacro"); + KSharedPtr<KoMacro::Macro> macro2 = KoMacro::Manager::self()->createMacro("testMacro"); + //Is our XML parseable ? + KOMACROTEST_ASSERT(macro1->parseXML(domelement),true); + KOMACROTEST_ASSERT(macro2->parseXML(domelement),true); + + //check that it is not null + KOMACROTEST_XASSERT(sizetype(macro1.data()), sizetype(0)); + KOMACROTEST_XASSERT(sizetype(macro2.data()), sizetype(0)); + + //check macro1 == macro2 + KOMACROTEST_ASSERT(macro1->name(), macro2->name() ); + + //create list of KsharedPtr from the childs of the macro + QValueList< KSharedPtr<KoMacro::MacroItem> >& items1 = macro1->items(); + QValueList< KSharedPtr<KoMacro::MacroItem> >& items2 = macro2->items(); + + //check that there is one + KOMACROTEST_XASSERT( items1.count(), sizetype(0) ); + KOMACROTEST_XASSERT( items2.count(), sizetype(0) ); + + //check macro1 == macro2 + KOMACROTEST_ASSERT( items1.count(), items2.count() ); + + //check the name + KOMACROTEST_ASSERT( QString(macro1->name()), QString("testMacro") ); + + { + const QString tmp1 = QString("test"); + macro1->setName(tmp1); + + //check the name changed + KOMACROTEST_XASSERT( QString(macro1->name()), QString("testMacro") ); + //check the name + KOMACROTEST_ASSERT( QString(macro1->name()), QString("test") ); + } + + //fetch the first one + KSharedPtr<KoMacro::Action> actionptr = items1[0]->action(); + //check that it is not null + KOMACROTEST_XASSERT(sizetype(actionptr.data()), sizetype(0)); + //check that it has the right name + KOMACROTEST_ASSERT( QString(actionptr->name()), QString("testaction") ); + //check that it has the right text + KOMACROTEST_ASSERT( actionptr->text(), QString("Test") ); + + //try to clear items + macro1->clearItems(); + //get items + items1 = macro1->items(); + //check that they are deleted + KOMACROTEST_ASSERT( items1.count(), sizetype(0) ); +} +#include "macrotests.moc" diff --git a/kexi/plugins/macros/tests/macrotests.h b/kexi/plugins/macros/tests/macrotests.h new file mode 100644 index 00000000..ed8d0f21 --- /dev/null +++ b/kexi/plugins/macros/tests/macrotests.h @@ -0,0 +1,74 @@ +/*************************************************************************** + * 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 KOMACROTEST_MACROTESTS_H +#define KOMACROTEST_MACROTESTS_H + +#include <kunittest/tester.h> + +namespace KoMacroTest { + + /** + * The common testsuite used to test common @a KoMacro + * functionality. + */ + class MacroTests : public KUnitTest::SlotTester + { + Q_OBJECT + public: + + /** + * Constructor. + */ + MacroTests(); + + /** + * Destructor. + */ + virtual ~MacroTests(); + + public slots: + + /** + * This slot got called by KUnitTest before testing + * starts. + */ + void setUp(); + + /** + * This slot got called by KUnitTest after all tests + * are done. + */ + void tearDown(); + + /** + * Test the @a KoMacro::Action functionality. + */ + void testMacro(); + + private: + /// @internal d-pointer class. + class Private; + /// @internal d-pointer instance. + Private* const d; + }; + +} + +#endif diff --git a/kexi/plugins/macros/tests/testaction.cpp b/kexi/plugins/macros/tests/testaction.cpp new file mode 100644 index 00000000..4063aa1b --- /dev/null +++ b/kexi/plugins/macros/tests/testaction.cpp @@ -0,0 +1,61 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2006 by Bernd Steindorff (bernd@itii.de) + * 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 "testaction.h" + +#include "../lib/action.h" +#include "../lib/context.h" +#include "../lib/macroitem.h" +#include "../lib/variable.h" + +#include <klocale.h> +#include <kdebug.h> + +using namespace KoMacroTest; + +TestAction::TestAction() + : KoMacro::Action("testaction", "Test") +{ + setVariable("teststring", "Stringtest", QString("testString")); + setVariable("testint", "Inttest", int(0)); + setVariable("testdouble", "Doubletest", double(0.5)); + setVariable("testbool", "Booltest", QVariant(true,0)); +} + +TestAction::~TestAction() +{ +} + +bool TestAction::notifyUpdated(KSharedPtr<KoMacro::MacroItem> macroitem, const QString& name) +{ + Q_UNUSED(macroitem); + Q_UNUSED(name); + return true; +} + +void TestAction::activate(KSharedPtr<KoMacro::Context> context) +{ + kdDebug() << "TestAction::activate(KSharedPtr<Context>)" << endl; + const QString teststring = context->variable("teststring")->variant().toString(); + const int testint = context->variable("testint")->variant().toInt(); + const bool testbool = context->variable("testbool")->variant().toBool(); +} + +#include "testaction.moc" diff --git a/kexi/plugins/macros/tests/testaction.h b/kexi/plugins/macros/tests/testaction.h new file mode 100644 index 00000000..9eebff3c --- /dev/null +++ b/kexi/plugins/macros/tests/testaction.h @@ -0,0 +1,78 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * copyright (C) 2006 by Bernd Steindorff (bernd@itii.de) + * 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 KOMACROTEST_TESTACTION_H +#define KOMACROTEST_TESTACTION_H + +#include <ksharedptr.h> + +#include "../lib/action.h" + +namespace KoMacro { + class Context; + class MacroItem; +} + +namespace KoMacroTest { + + /** + * This TestAction implements a @a KoMacro::Action to + * test the functionality provided by this class. + */ + class TestAction : public KoMacro::Action + { + Q_OBJECT + public: + + /** + * Constructor. + */ + TestAction(); + + /** + * Destructor. + */ + virtual ~TestAction(); + + /** + * 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(KSharedPtr<KoMacro::MacroItem> macroitem, const QString& name); + + public slots: + + /** + * Called if the @a Action should be executed within the + * defined @p context . + */ + virtual void activate(KSharedPtr<KoMacro::Context> context); + + }; +} + +#endif diff --git a/kexi/plugins/macros/tests/testobject.cpp b/kexi/plugins/macros/tests/testobject.cpp new file mode 100644 index 00000000..39cadb7a --- /dev/null +++ b/kexi/plugins/macros/tests/testobject.cpp @@ -0,0 +1,117 @@ +/*************************************************************************** + * 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 "testobject.h" + +//#include "../lib/manager.h" +//#include "../lib/action.h" +//#include "../lib/function.h" +//#include "../lib/macro.h" +//#include "../lib/metaobject.h" + +//#include <qstringlist.h> +//#include <qdom.h> + +#include <kdebug.h> +//#include <kxmlguiclient.h> + +using namespace KoMacroTest; + +namespace KoMacroTest { + + /** + * @internal d-pointer class to be more flexible on future extension of the + * functionality without to much risk to break the binary compatibility. + */ + class TestObject::Private + { + public: + + /** + * The @a KUnitTest::Tester instance that likes to test + * our TestObject instance. + */ + KUnitTest::Tester* const tester; + Private(KUnitTest::Tester* const tester) + : tester(tester) + { + } + }; + +} + +TestObject::TestObject(KUnitTest::Tester* const tester) + : QObject() + , d( new Private(tester) ) // create the private d-pointer instance. +{ + setName("TestObject"); +} + +TestObject::~TestObject() +{ + delete d; +} + +//testObject without arguments +void TestObject::myslot() +{ + QString s = "CALLED => TestObject::myslot()"; + //be loud + kdDebug() << s << endl; + //add some extra Debuginfos to TestResults see tester.h + d->tester->results()->addDebugInfo(s); +} + +//testobject with QString and int argument +//int is returnvalue +int TestObject::myslot(const QString&, int i) +{ + QString s = "CALLED => TestObject::myslot(const QString&, int)"; + //be loud + kdDebug() << s << endl; + //add some extra debuginfos to TestResults + d->tester->results()->addDebugInfo(s); + return i; +} + +//testobject with QString argument +//QString is returnvalue +QString TestObject::myslot(const QString& s) +{ + QString t = QString("CALLED => TestObject::myslot(const QString& s) s=%1").arg(s); + //be loud + kdDebug() << t << endl; + //add some extra Debuginfos to TestResults + d->tester->results()->addDebugInfo(t); + return s; +} + +//testobject with QString and double argument +//double is returnvalue +double TestObject::myslot(const QString&, double d) +{ + QString s = "CALLED => TestObject::myslot(const QString&, double)"; + //be loud + kdDebug() << s << endl; + //add some extra Debuginfos to TestResults + this->d->tester->results()->addDebugInfo(s); + return d; +} + +#include "testobject.moc" diff --git a/kexi/plugins/macros/tests/testobject.h b/kexi/plugins/macros/tests/testobject.h new file mode 100644 index 00000000..da5e8ae2 --- /dev/null +++ b/kexi/plugins/macros/tests/testobject.h @@ -0,0 +1,85 @@ +/*************************************************************************** + * 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 KOMACROTEST_TESTOBJECT_H +#define KOMACROTEST_TESTOBJECT_H + +#include <qobject.h> +#include <kunittest/tester.h> + +namespace KoMacroTest { + + /** + * The TestObject class is used to test handling and communication + * of external from QObject inheritated classes. + */ + class TestObject : public QObject + { + Q_OBJECT + public: + + /** + * Constructor. + * + * @param tester The @a KUnitTest::Tester instance + * that likes to test our TestObject instance. + */ + TestObject(KUnitTest::Tester* const tester); + + /** + * Destructor. + */ + virtual ~TestObject(); + + public slots: + + /** + * This slot got published to the KoMacro-framework + * and will be called to test the functionality. + */ + void myslot(); + + /** + * This slot got published to the KoMacro-framework + * and will be called to test the functionality. + */ + int myslot(const QString&, int); + + /** + * This slot got published to the KoMacro-framework + * and will be called to test the functionality. + */ + QString myslot(const QString&); + + /** + * This slot got published to the KoMacro-framework + * and will be called to test the functionality. + * @return is @param d + */ + double myslot(const QString&, double d); + + private: + /// @internal d-pointer class. + class Private; + /// @internal d-pointer instance. + Private* const d; + }; +} + +#endif diff --git a/kexi/plugins/macros/tests/variabletests.cpp b/kexi/plugins/macros/tests/variabletests.cpp new file mode 100644 index 00000000..8bc8d9c7 --- /dev/null +++ b/kexi/plugins/macros/tests/variabletests.cpp @@ -0,0 +1,236 @@ +/*************************************************************************** + * This file is part of the KDE project + * copyright (C) 2006 by Sebastian Sauer (mail@dipe.org) + * + * 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 "variabletests.h" +#include "testobject.h" +#include "testaction.h" +#include "komacrotestbase.h" + +#include "../lib/action.h" +#include "../lib/function.h" +#include "../lib/manager.h" +#include "../lib/macro.h" +#include "../lib/variable.h" +#include "../lib/metaobject.h" +#include "../lib/metamethod.h" +#include "../lib/metaparameter.h" +#include "../lib/exception.h" +#include "../lib/macroitem.h" + +#include <ostream> + +#include <qstringlist.h> +#include <qdom.h> + +#include <kdebug.h> +#include <kunittest/runner.h> +#include <kxmlguiclient.h> + +using namespace KUnitTest; +using namespace KoMacroTest; + +namespace KoMacroTest { + + /** + * Register KoMacroTest::CommonTests as TestSuite. + */ + + KUNITTEST_SUITE("KoMacroTestSuite"); + KUNITTEST_REGISTER_TESTER(VariableTests); + + + class VariableTests::Private + { + public: + /** + * An KXMLGUIClient instance created on @a setUp() and + * passed to the @a KoMacro::Manager to bridge to the + * app-functionality. + */ + KXMLGUIClient* xmlguiclient; + + /** + * An @a TestObject instance used internaly to test + * handling and communication with from QObject + * inheritated instances. + */ + TestAction* testaction; + + QDomDocument* doomdocument; + + KSharedPtr<KoMacro::Macro> macro; + + Private() + : xmlguiclient(0) + , testaction(0) + , doomdocument(0) + , macro(0) + { + } + }; +} + +typedef QValueList< KSharedPtr<KoMacro::MacroItem> >::size_type sizetype; + +/****************************************************************************** +* This is an xtra big TODO: +* - get rid of all double declarations +* - create xtra-class for Variable/Macroitem tests +* - add comments +******************************************************************************/ +VariableTests::VariableTests() + : KUnitTest::SlotTester() + , d( new Private() ) // create the private d-pointer instance. +{ +} + +VariableTests::~VariableTests() +{ + delete d->xmlguiclient; + delete d; +} + + +void VariableTests::setUp() +{ + d->xmlguiclient = new KXMLGUIClient(); + + if (::KoMacro::Manager::self() == 0) { + ::KoMacro::Manager::init( d->xmlguiclient ); + } + + d->testaction = new TestAction(); + ::KoMacro::Manager::self()->publishAction(d->testaction); + + d->doomdocument = new QDomDocument(); + + QString const xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\" >" + "<item action=\"testaction\" >" + "</item>" + "</macro>"); + + d->doomdocument->setContent(xml); + d->macro = KoMacro::Manager::self()->createMacro("testMacro"); + d->macro->parseXML(d->doomdocument->documentElement()); + d->macro->execute(this); +} + +void VariableTests::tearDown() +{ + delete d->macro; + delete d->doomdocument; + delete d->xmlguiclient; +} + +void VariableTests::testMacro() +{ + kdDebug()<<"===================== testVariable() ===================" << endl; + kdDebug()<<"===================== testMacro() ======================" << endl; + + //fetch Items and .. + QValueList< KSharedPtr<KoMacro::MacroItem> >& items = d->macro->items(); + + //... check that there is one + KOMACROTEST_XASSERT( items.count(), sizetype(0) ); +} + +void VariableTests::testVariableString() { + kdDebug()<<"===================== testVariableString() ======================" << endl; + QValueList< KSharedPtr<KoMacro::MacroItem> >& items = d->macro->items(); + KSharedPtr<KoMacro::Action> actionptr = items[0]->action(); + + //fetch the "teststring"-variable + KSharedPtr<KoMacro::Variable> variableptr = actionptr->variable(TESTSTRING); + //So there is a variable, does hasVariable() work ? + KOMACROTEST_ASSERT(actionptr->hasVariable(TESTSTRING),true); + //check count of variables + KOMACROTEST_ASSERT(sizetype(actionptr->variableNames().count()),sizetype(4)); + //remove one + actionptr->removeVariable(TESTSTRING); + //Decreased ?? + KOMACROTEST_ASSERT(sizetype(actionptr->variableNames().count()),sizetype(3)); + //add one + actionptr->setVariable(variableptr); + //increased ?? + KOMACROTEST_ASSERT(sizetype(actionptr->variableNames().count()),sizetype(4)); + + //check that it is not null + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + //check that it is "testString" + KOMACROTEST_ASSERT(variableptr->variant().toString(),QString("testString")); + + actionptr->setVariable("teststring", "STRINGTEST", "TestString"); + variableptr = actionptr->variable("teststring"); + //check that it is not null + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + //check that it is " " + KOMACROTEST_ASSERT(variableptr->variant().toString(),QString("TestString")); +} + +void VariableTests::testVariableInt() { + kdDebug()<<"===================== testVariableInt() ======================" << endl; + QValueList< KSharedPtr<KoMacro::MacroItem> >& items = d->macro->items(); + KSharedPtr<KoMacro::Action> actionptr = items[0]->action(); + + //fetch the "testint"-variable + KSharedPtr<KoMacro::Variable> variableptr = actionptr->variable(TESTINT); + //check that it is not null + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + //check that it is 0 + KOMACROTEST_ASSERT(variableptr->variant().toInt(),int(0)); + + actionptr->setVariable(TESTINT,"INTTEST",INT_MAX); + variableptr = actionptr->variable("testint"); + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + KOMACROTEST_ASSERT(sizetype(variableptr->variant().toInt()),sizetype(INT_MAX)); + + actionptr->setVariable(TESTINT,"INTTEST",INT_MAX+1); + variableptr = actionptr->variable("testint"); + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + KOMACROTEST_ASSERT(sizetype(variableptr->variant().toInt()),sizetype(INT_MAX+1)); + + actionptr->setVariable(TESTINT,"INTTEST",INT_MIN); + variableptr = actionptr->variable("testint"); + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + KOMACROTEST_ASSERT(sizetype(variableptr->variant().toInt()),sizetype(INT_MIN)); + + actionptr->setVariable(TESTINT,"INTTEST",INT_MIN-1); + variableptr = actionptr->variable("testint"); + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + KOMACROTEST_ASSERT(sizetype(variableptr->variant().toInt()),sizetype(INT_MIN-1)); +} + +void VariableTests::testVariableBool() { + kdDebug()<<"===================== testVariableBool() ======================" << endl; + QValueList< KSharedPtr<KoMacro::MacroItem> >& items = d->macro->items(); + KSharedPtr<KoMacro::Action> actionptr = items[0]->action(); + + //fetch the "testbool"-variable + KSharedPtr<KoMacro::Variable> variableptr = actionptr->variable(TESTBOOL); + //check that it is not null + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + //check that it is " " + KOMACROTEST_ASSERT(variableptr->variant().toBool(),true); + + actionptr->setVariable("testbool","BOOLTEST", "false"); + variableptr = actionptr->variable("testbool"); + KOMACROTEST_XASSERT(sizetype(variableptr.data()), sizetype(0)); + KOMACROTEST_ASSERT(variableptr->variant().toBool(),false); +} +#include "variabletests.moc" diff --git a/kexi/plugins/macros/tests/variabletests.h b/kexi/plugins/macros/tests/variabletests.h new file mode 100644 index 00000000..5bc7f144 --- /dev/null +++ b/kexi/plugins/macros/tests/variabletests.h @@ -0,0 +1,87 @@ +/*************************************************************************** + * 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 KOMACROTEST_VARIABLETESTS_H +#define KOMACROTEST_VARIABLETESTS_H + +#include <kunittest/tester.h> + +namespace KoMacroTest { + + /** + * The common testsuite used to test common @a KoMacro + * functionality. + */ + class VariableTests : public KUnitTest::SlotTester + { + Q_OBJECT + public: + + /** + * Constructor. + */ + VariableTests(); + + /** + * Destructor. + */ + virtual ~VariableTests(); + + public slots: + + /** + * This slot got called by KUnitTest before testing + * starts. + */ + void setUp(); + + /** + * This slot got called by KUnitTest after all tests + * are done. + */ + void tearDown(); + + /** + * Subtest for the @a KoMacro::Action functionality. + */ + void testMacro(); + + /** + * Subtest for the @a KoMacro::Action functionality. + */ + void testVariableString(); + /** + * Subtest for the @a KoMacro::Action functionality. + */ + void testVariableInt(); + /** + * Subtest for the @a KoMacro::Action functionality. + */ + void testVariableBool(); + + private: + /// @internal d-pointer class. + class Private; + /// @internal d-pointer instance. + Private* const d; + }; + +} + +#endif diff --git a/kexi/plugins/macros/tests/xmlhandlertests.cpp b/kexi/plugins/macros/tests/xmlhandlertests.cpp new file mode 100644 index 00000000..9a0ebcb1 --- /dev/null +++ b/kexi/plugins/macros/tests/xmlhandlertests.cpp @@ -0,0 +1,619 @@ +/*************************************************************************** + * This file is part of the KDE project + * 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 "xmlhandlertests.h" +#include "testaction.h" +#include "komacrotestbase.h" + +#include "../lib/action.h" +#include "../lib/manager.h" +#include "../lib/macro.h" +#include "../lib/variable.h" +#include "../lib/macroitem.h" + +#include <ostream> +#include <cfloat> + +#include <qdom.h> + +#include <kdebug.h> +#include <kunittest/runner.h> +#include <kxmlguiclient.h> + +using namespace KUnitTest; +using namespace KoMacroTest; + +namespace KoMacroTest { + + /** + * Register KoMacroTest::CommonTests as TestSuite. + */ + KUNITTEST_SUITE("KoMacroTestSuite") + KUNITTEST_REGISTER_TESTER(XMLHandlerTests); + + class XMLHandlerTests::Private + { + public: + /** + * An KXMLGUIClient instance created on @a setUp() and + * passed to the @a KoMacro::Manager to bridge to the + * app-functionality. + */ + KXMLGUIClient* xmlguiclient; + + /** + * An @a TestObject instance used internaly to test + * handling and communication with from QObject + * inheritated instances. + */ + KSharedPtr<KoMacro::Action> testaction; + + Private() + : xmlguiclient(0) + , testaction(0) + { + } + }; +} + +XMLHandlerTests::XMLHandlerTests() + : KUnitTest::SlotTester() + , d( new Private() ) // create the private d-pointer instance. +{ +} + +XMLHandlerTests::~XMLHandlerTests() +{ + delete d->xmlguiclient; + delete d; +} + + +void XMLHandlerTests::setUp() +{ + d->xmlguiclient = new KXMLGUIClient(); + + //Singelton more or less ... + if (::KoMacro::Manager::self() == 0) { + ::KoMacro::Manager::init( d->xmlguiclient ); + } + + d->testaction = new TestAction(); + ::KoMacro::Manager::self()->publishAction(d->testaction); +} + +void XMLHandlerTests::tearDown() +{ + delete d->xmlguiclient; +} + +/** +* Test the @a KoMacro::XMLHandler parseXML() and toXML()-function. +*/ +void XMLHandlerTests::testParseAndToXML() +{ + kdDebug()<<"===================== testParseAndToXML() ======================" << endl; + + // 1.Test - Correct DomElement. + testCorrectDomElement(); + // 2.Test - XML-document with bad root element. + testBadRoot(); + // 3.Test - XML-document with a missing Variable. + testMissingVariable(); + // 4.Test - One more Variable in XML-Document. + testMoreVariables(); + // 5.Test - XML-document with wrong macro-xmlversion. + testWrongVersion(); + // 6.Test - XML-document if it has a wrong structure like wrong parathesis + // or missing end tag. + testWrongXMLStruct(); + // 7.Test-XML-document with maximum field-size. + testMaxNum(); + // 8.Test-XML-document with maximum+1 field-size. + testMaxNum2(); + // 9.Test-XML-document with minimum field-size. + testMinNum(); + // 10.Test-XML-document with minimum-1 field-size. + testMinNum2(); + // 11.Test - With a to big number. + testBigNumber(); + // 12.Test - With two MacroItems. + testTwoMacroItems(); +} + +/*************************************************************************** +* Begin of Sub-methos of testParseXML(). +***************************************************************************/ +// 1.Test - Correct DomElement. +void XMLHandlerTests::testCorrectDomElement() +{ + // Local Init + KSharedPtr<KoMacro::Macro> macro = KoMacro::Manager::self()->createMacro("testMacro"); + QDomDocument doomdocument; + + // Part 1: From XML to a Macro. + // Test-XML-document with normal allocated variables. + const QString xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" >0</variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" >0.6</variable>" + "</item>" + "</macro>"); + // Set the XML-document with the above string. + doomdocument.setContent(xml); + const QDomElement elem = doomdocument.documentElement(); + // Is our XML parseable by calling parseXML()? + KOMACROTEST_ASSERT(macro->parseXML(elem),true); + + // Is the parsen content in the Macro correct ? + QMap<QString,bool> isvariableok; + isvariableok["teststring"] = true; + isvariableok["testint"] = true; + isvariableok["testbool"] = true; + isvariableok["testdouble"] = true; + assertMacroContentEqToXML(macro,elem,false,true,isvariableok); + + // Transform back by calling toXML(). + const QDomElement elem2 = macro->toXML(); + assertMacroContentEqToXML(macro,elem2,false,true,isvariableok); + + // Test the Compare-method when a Variable will change, it must fail. + macro->items().first()->variable("teststring")->setVariant("bla"); + isvariableok.replace("teststring",false); + assertMacroContentEqToXML(macro,elem,false,true,isvariableok); +} + +// 2.Test - XML-document with bad root element. +void XMLHandlerTests::testBadRoot() +{ + KSharedPtr<KoMacro::Macro> macro = KoMacro::Manager::self()->createMacro("testMacro"); + QDomDocument doomdocument; + + const QString xml = QString("<!DOCTYPE macros>" + "<maro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" >0</variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" >0.6</variable>" + "</item>" + "</maro>"); + doomdocument.setContent(xml); + const QDomElement elem = doomdocument.documentElement(); + KOMACROTEST_XASSERT(macro->parseXML(elem),true); + + //no assertMacroContentEqToXML(), because parsing failed. + assertMacroContentEqToXML(macro,elem,true,false,QMap<QString,bool>()); + + const QDomElement elem2 = macro->toXML(); + assertMacroContentEqToXML(macro,elem2,true,false,QMap<QString,bool>()); +} + +// 3.Test - XML-document with a missing Variable. +void XMLHandlerTests::testMissingVariable() +{ + KSharedPtr<KoMacro::Macro> macro = KoMacro::Manager::self()->createMacro("testMacro"); + QDomDocument doomdocument; + + const QString xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" >0</variable>" + "<variable name=\"testdouble\" >0.6</variable>" + "</item>" + "</macro>"); + doomdocument.setContent(xml); + const QDomElement elem = doomdocument.documentElement(); + KOMACROTEST_ASSERT(macro->parseXML(elem),true); + + QMap<QString,bool> isvariableok; + isvariableok["teststring"] = true; + isvariableok["testint"] = true; + isvariableok["testdouble"] = true; + assertMacroContentEqToXML(macro,elem,false,true,isvariableok); + + const QDomElement elem2 = macro->toXML(); + assertMacroContentEqToXML(macro,elem2,false,true,isvariableok); +} + +// 4.Test - One more Variable in XML-Document. +void XMLHandlerTests::testMoreVariables() +{ + KSharedPtr<KoMacro::Macro> macro = KoMacro::Manager::self()->createMacro("testMacro"); + QDomDocument doomdocument; + + const QString xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" >0</variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" >0.6</variable>" + "<variable name=\"testbla\" >somethingwrong</variable>" + "</item>" + "</macro>"); + doomdocument.setContent(xml); + const QDomElement elem = doomdocument.documentElement(); + KOMACROTEST_ASSERT(macro->parseXML(elem),true); + + QMap<QString,bool> isvariableok; + isvariableok["teststring"] = true; + isvariableok["testint"] = true; + isvariableok["testbool"] = true; + isvariableok["testdouble"] = true; + isvariableok["testbla"] = true; + assertMacroContentEqToXML(macro,elem,false,true,isvariableok); + + const QDomElement elem2 = macro->toXML(); + assertMacroContentEqToXML(macro,elem2,false,true,isvariableok); +} + +// 5.Test - XML-document with wrong macro-xmlversion. +void XMLHandlerTests::testWrongVersion() +{ + KSharedPtr<KoMacro::Macro> macro = KoMacro::Manager::self()->createMacro("testMacro"); + QDomDocument doomdocument; + + const QString xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"2\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" >0</variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" >0.6</variable>" + "</item>" + "</macro>"); + doomdocument.setContent(xml); + const QDomElement elem = doomdocument.documentElement(); + KOMACROTEST_XASSERT(macro->parseXML(elem),true); + + //no assertMacroContentEqToXML(), because parsing failed. + assertMacroContentEqToXML(macro,elem,true,false,QMap<QString,bool>()); + + const QDomElement elem2 = macro->toXML(); + assertMacroContentEqToXML(macro,elem2,true,false,QMap<QString,bool>()); +} + +// 6.Test - XML-document if it has a wrong structure like wrong parathesis +// or missing end tag. +void XMLHandlerTests::testWrongXMLStruct() +{ + KSharedPtr<KoMacro::Macro> macro = KoMacro::Manager::self()->createMacro("testMacro"); + QDomDocument doomdocument; + + const QString xml = QString("<!DOCTYPE macros>" + "macro xmlversion=\"1\">>" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" >0</variable>" + "</item>" + "</macro>"); + KOMACROTEST_XASSERT(doomdocument.setContent(xml),true); + const QDomElement elem = doomdocument.documentElement(); + KOMACROTEST_XASSERT(macro->parseXML(elem),true); + + //no assertMacroContentEqToXML(), because parsing failed. + assertMacroContentEqToXML(macro,elem,true,false,QMap<QString,bool>()); + + const QDomElement elem2 = macro->toXML(); + assertMacroContentEqToXML(macro,elem2,true,false,QMap<QString,bool>()); +} + +// 7.Test-XML-document with maximum field-size. +void XMLHandlerTests::testMaxNum() +{ + KSharedPtr<KoMacro::Macro> macro = KoMacro::Manager::self()->createMacro("testMacro"); + QDomDocument doomdocument; + + const QString xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" > %1 </variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" > %2 </variable>" + "</item>" + "</macro>").arg(INT_MAX).arg(DBL_MAX); + doomdocument.setContent(xml); + const QDomElement elem = doomdocument.documentElement(); + KOMACROTEST_ASSERT(macro->parseXML(elem),true); + + QMap<QString,bool> isvariableok; + isvariableok["teststring"] = true; + isvariableok["testint"] = true; + isvariableok["testbool"] = true; + isvariableok["testdouble"] = true; + assertMacroContentEqToXML(macro,elem,false,true,isvariableok); + + QDomElement elem2 = macro->toXML(); + assertMacroContentEqToXML(macro,elem2,false,true,isvariableok); +} + +// 8.Test-XML-document with maximum+1 field-size. +void XMLHandlerTests::testMaxNum2() +{ + KSharedPtr<KoMacro::Macro> macro = KoMacro::Manager::self()->createMacro("testMacro"); + QDomDocument doomdocument; + + const QString xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" > %1 </variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" > %2 </variable>" + "</item>" + "</macro>").arg(INT_MAX+1).arg(DBL_MAX+1); + doomdocument.setContent(xml); + const QDomElement elem = doomdocument.documentElement(); + KOMACROTEST_ASSERT(macro->parseXML(elem),true); + + QMap<QString,bool> isvariableok; + isvariableok["teststring"] = true; + isvariableok["testint"] = true; + isvariableok["testbool"] = true; + isvariableok["testdouble"] = true; + assertMacroContentEqToXML(macro,elem,false,true,isvariableok); + + const QDomElement elem2 = macro->toXML(); + assertMacroContentEqToXML(macro,elem2,false,true,isvariableok); +} + +// 9.Test-XML-document with minimum field-size. +void XMLHandlerTests::testMinNum() +{ + KSharedPtr<KoMacro::Macro> macro = KoMacro::Manager::self()->createMacro("testMacro"); + QDomDocument doomdocument; + + const QString xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" > %1 </variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" > %2 </variable>" + "</item>" + "</macro>").arg(INT_MIN).arg(DBL_MIN); + doomdocument.setContent(xml); + const QDomElement elem = doomdocument.documentElement(); + KOMACROTEST_ASSERT(macro->parseXML(elem),true); + + QMap<QString,bool> isvariableok; + isvariableok["teststring"] = true; + isvariableok["testint"] = true; + isvariableok["testbool"] = true; + isvariableok["testdouble"] = true; + assertMacroContentEqToXML(macro,elem,false,true,isvariableok); + + const QDomElement elem2 = macro->toXML(); + assertMacroContentEqToXML(macro,elem2,false,true,isvariableok); +} + +// 10.Test-XML-document with minimum+1 field-size. +void XMLHandlerTests::testMinNum2() +{ + KSharedPtr<KoMacro::Macro> macro = KoMacro::Manager::self()->createMacro("testMacro"); + QDomDocument doomdocument; + + const QString xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" > %1 </variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" > %2 </variable>" + "</item>" + "</macro>").arg(INT_MIN-1).arg(DBL_MIN-1); + doomdocument.setContent(xml); + const QDomElement elem = doomdocument.documentElement(); + KOMACROTEST_ASSERT(macro->parseXML(elem),true); + + QMap<QString,bool> isvariableok; + isvariableok["teststring"] = true; + isvariableok["testint"] = true; + isvariableok["testbool"] = true; + isvariableok["testdouble"] = true; + assertMacroContentEqToXML(macro,elem,false,true,isvariableok); + + const QDomElement elem2 = macro->toXML(); + assertMacroContentEqToXML(macro,elem2,false,true,isvariableok); +} + +// 11.Test - With a to big number. +void XMLHandlerTests::testBigNumber() +{ + KSharedPtr<KoMacro::Macro> macro = KoMacro::Manager::self()->createMacro("testMacro"); + QDomDocument doomdocument; + + const QString xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" > 0123456789012345678901234567890123456789 </variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" > %1 </variable>" + "</item>" + "</macro>").arg(DBL_MAX+1); + doomdocument.setContent(xml); + const QDomElement elem = doomdocument.documentElement(); + KOMACROTEST_ASSERT(macro->parseXML(elem),true); + + QMap<QString,bool> isvariableok; + isvariableok["teststring"] = true; + isvariableok["testint"] = true; + isvariableok["testbool"] = true; + isvariableok["testdouble"] = true; + assertMacroContentEqToXML(macro,elem,false,true,isvariableok); + + const QDomElement elem2 = macro->toXML(); + assertMacroContentEqToXML(macro,elem2,false,true,isvariableok); +} + +// 12.Test - With two MacroItems. +void XMLHandlerTests::testTwoMacroItems() +{ + KSharedPtr<KoMacro::Macro> macro = KoMacro::Manager::self()->createMacro("testMacro"); + QDomDocument doomdocument; + + const QString xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" >0</variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" >0.6</variable>" + "<variable name=\"testbla\" >somethingwrong</variable>" + "</item>" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >testBBstring2</variable>" + "<variable name=\"testint\" >4</variable>" + "<variable name=\"testbool\" >false</variable>" + "<variable name=\"testdouble\" >0.7</variable>" + "<variable name=\"testbla\" >somethingwrong2</variable>" + "</item>" + "</macro>"); + doomdocument.setContent(xml); + const QDomElement elem = doomdocument.documentElement(); + KOMACROTEST_ASSERT(macro->parseXML(elem),true); + + QMap<QString,bool> isvariableok; + isvariableok["teststring"] = true; + isvariableok["testint"] = true; + isvariableok["testbool"] = true; + isvariableok["testdouble"] = true; + assertMacroContentEqToXML(macro,elem,false,true,isvariableok); + + const QDomElement elem2 = macro->toXML(); + assertMacroContentEqToXML(macro,elem2,false,true,isvariableok); +} +/*************************************************************************** +* End of Sub-methos of testParseAndToXML(). +***************************************************************************/ + +/** +* Compares a XML-Element with a Macro. Call sub-asserts. +* @p macro The parsen @a Macro. +* @p elem The given @a QDomElement which is parsen. +* @p isitemsempty Bool for expectation of an empty @a MacroItem -List. +* @p isactionset Bool for expectation that the @a Action -names are equal. +* @p isvariableok QMap of Bools for comparing each @a Variable . +*/ +void XMLHandlerTests::assertMacroContentEqToXML(const KSharedPtr<KoMacro::Macro> macro, + const QDomElement& elem, + const bool isitemsempty, + const bool isactionset, + const QMap<QString, bool> isvariableok) +{ + // Make an Iterator over the MacroItems of the Macro. + const QValueList<KSharedPtr<KoMacro::MacroItem > > macroitems = macro->items(); + QValueList<KSharedPtr<KoMacro::MacroItem > >::ConstIterator + mit(macroitems.constBegin()), end(macroitems.constEnd()); + + //1.comparison - Is the MacroItem-list empty? + { + if( isitemsempty ) { + KOMACROTEST_XASSERT(macroitems.empty(),false); + kdDebug() << "There is no correct MacroItem parsen." << endl; + return; + } + else { + KOMACROTEST_ASSERT(macroitems.empty(),false); + } + } + + // Got to the first item-elements of the elem (there is only one in the tests). + QDomNode itemnode = elem.firstChild(); + + // Iterate over the MacroItems and item-elements. + while(mit != end && ! itemnode.isNull()) { + const KSharedPtr<KoMacro::MacroItem> macroitem = *mit; + const QDomElement itemelem = itemnode.toElement(); + + //2.comparison - Is the Action-name equal? + { + if( ! isactionset) { + KOMACROTEST_XASSERT(macroitem->action()->name() == itemelem.attribute("action"),true); + kdDebug() << "Action-name not equal: " + << macroitem->action()->name() + << " != " << itemelem.attribute("action") << endl; + return; + } + else { + KOMACROTEST_ASSERT(macroitem->action()->name() == itemelem.attribute("action"),true); + } + } + + // Go down to MacroItem->Variable and item->variable and compare them. + QMap<QString, KSharedPtr<KoMacro::Variable > > mvariables = macroitem->variables(); + QDomNode varnode = itemelem.firstChild(); + + while ( ! varnode.isNull()) { + const QDomElement varelem = varnode.toElement(); + const KSharedPtr<KoMacro::Variable> varitem = mvariables.find(varelem.attribute("name")).data(); + + //3.comparison - Is the content of the Variable + // in the MacroItem and and item equal? + { + const bool var = *isvariableok.find(varelem.attribute("name")); + if( ! var ) { + KOMACROTEST_XASSERT(varitem->variant() == QVariant(varelem.text()), !var); + kdDebug() << "The content of the Variable: " << varitem->name() + << " is not equal." << varitem->variant() + << "!=" << varelem.text() << endl; + } + else { + KOMACROTEST_ASSERT(varitem->variant() == QVariant(varelem.text()), var); + } + + } + + // Erase the MacroItem from the map, because it is parsen correctly. + mvariables.erase(varitem->name()); + // Go to next Variable in node-tree. + varnode = varnode.nextSibling(); + } + + //4.comparison - Is every MacroItem parsen? + { + KOMACROTEST_ASSERT(mvariables.empty(),true); + kdDebug() << "There are non-filled variable in the MacroItem: " << mvariables.count() <<endl; + } + + // Go to next MacroItem and next item-element. + mit++; + itemnode = itemnode.nextSibling(); + } +} + +// Prints a QMap of Variables to kdDebug(). +void XMLHandlerTests::printMvariables(const QMap<QString, KSharedPtr<KoMacro::Variable > > mvariables, const QString s) +{ + //QValueList<QString>::ConstIterator kit (keys.constBegin()), end(keys.constEnd()); + QMap<QString, KSharedPtr<KoMacro::Variable > >::ConstIterator mvit (mvariables.constBegin()), end(mvariables.constEnd()); + while(mvit != end){ + const KoMacro::Variable * v = *mvit; + kdDebug() << s << ": " << v->name() << endl; + mvit++; + } +} + +#include "xmlhandlertests.moc" diff --git a/kexi/plugins/macros/tests/xmlhandlertests.h b/kexi/plugins/macros/tests/xmlhandlertests.h new file mode 100644 index 00000000..c78a8c79 --- /dev/null +++ b/kexi/plugins/macros/tests/xmlhandlertests.h @@ -0,0 +1,122 @@ +/*************************************************************************** + * This file is part of the KDE project + * 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 KOMACROTEST_XMLHandlerTests_H +#define KOMACROTEST_XMLHandlerTests_H + +#include <kunittest/tester.h> +#include "../lib/macro.h" + +namespace KoMacroTest { + + /** + * The common testsuite used to test common @a KoMacro + * functionality. + */ + class XMLHandlerTests : public KUnitTest::SlotTester + { + Q_OBJECT + public: + + /** + * Constructor. + */ + XMLHandlerTests(); + + /** + * Destructor. + */ + virtual ~XMLHandlerTests(); + + public slots: + + /** + * This slot got called by KUnitTest before testing + * starts. + */ + void setUp(); + + /** + * This slot got called by KUnitTest after all tests + * are done. + */ + void tearDown(); + + /** + * Test the @a KoMacro::XMLHandler parseXML()-function. + */ + void testParseAndToXML(); + + private: + /// @internal d-pointer class. + class Private; + /// @internal d-pointer instance. + Private* const d; + + /** + * Compares a XML-Element with a Macro. Call sub-asserts. + * @p macro The parsen @a Macro. + * @p domelement The given @a QDomElement which is parsen. + * @p isitemsempty Bool for expectation of an empty @a MacroItem -List. + * @p isactionset Bool for expectation that the @a Action -names are equal. + * @p isvariableok QMap of Bools for comparing each @a Variable . + */ + void assertMacroContentEqToXML(const KSharedPtr<KoMacro::Macro> macro, + const QDomElement& elem, + const bool isitemsempty, + const bool isactionset, + const QMap<QString, bool> isvariableok); + + // Prints a QMap of Variables to kdDebug(). + void printMvariables(const QMap<QString, KSharedPtr<KoMacro::Variable > > mvariables, const QString s); + + /** + * Sub-methods of testParseXML() and testToXML(). + * Test the correct parsing of a @a QDomElement into a @a Macro + * respectively expected failure of parsing. Then transform it + * back and compare it. + */ + // 1.Test - Correct DomElement. + void testCorrectDomElement(); + // 2.Test - XML-document with bad root element. + void testBadRoot(); + // 3.Test - XML-document with a missing Variable. + void testMissingVariable(); + // 4.Test - One more Variable in XML-Document. + void testMoreVariables(); + // 5.Test - XML-document with wrong macro-xmlversion. + void testWrongVersion(); + // 6.Test - XML-document if it has a wrong structure like + // wrong parathesis or missing end tag. + void testWrongXMLStruct(); + // 7.Test-XML-document with maximum field-size. + void testMaxNum(); + // 8.Test-XML-document with maximum+1 field-size. + void testMaxNum2(); + // 9.Test-XML-document with minimum field-size. + void testMinNum(); + // 10.Test-XML-document with minimum-1 field-size. + void testMinNum2(); + // 11.Test - With a to big number. + void testBigNumber(); + // 12.Test - With two MacroItems. + void testTwoMacroItems(); + }; +} + +#endif diff --git a/kexi/plugins/macros/tests/xmlhandlertests2.cpp b/kexi/plugins/macros/tests/xmlhandlertests2.cpp new file mode 100644 index 00000000..2234eaae --- /dev/null +++ b/kexi/plugins/macros/tests/xmlhandlertests2.cpp @@ -0,0 +1,1161 @@ +/*************************************************************************** + * This file is part of the KDE project + * 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 "xmlhandlertests2.h" +#include "testaction.h" +#include "komacrotestbase.h" + +#include "../lib/action.h" +#include "../lib/manager.h" +#include "../lib/macro.h" +#include "../lib/variable.h" +#include "../lib/macroitem.h" + +#include <ostream> +#include <cfloat> + +#include <qdom.h> + +#include <kdebug.h> +#include <kunittest/runner.h> +#include <kxmlguiclient.h> + +using namespace KUnitTest; +using namespace KoMacroTest; + +namespace KoMacroTest { + + /** + * Register KoMacroTest::CommonTests as TestSuite. + */ + KUNITTEST_SUITE("KoMacroTestSuite") + KUNITTEST_REGISTER_TESTER(XMLHandlerTests2); + + class XMLHandlerTests2::Private + { + public: + /** + * An KXMLGUIClient instance created on @a setUp() and + * passed to the @a KoMacro::Manager to bridge to the + * app-functionality. + */ + KXMLGUIClient* xmlguiclient; + + /** + * @a Macro instance as a container for the macroitems; + */ + KSharedPtr<KoMacro::Macro> macro; // container for manually created items + KSharedPtr<KoMacro::Macro> macro2; // container for parsen items + KSharedPtr<KoMacro::Macro> macro3; // container for parsen items after back-converting by toXML() and again parseXML() + + /** + * An @a TestObject instance used internaly to test + * handling and communication with from QObject + * inheritated instances. + */ + KSharedPtr<KoMacro::Action> testaction; + KSharedPtr<KoMacro::Action> action2; // action of the parsen macro2 + KSharedPtr<KoMacro::Action> action3; // action of the parsen macro3 + KSharedPtr<KoMacro::Action> testaction_2; // for test12 + KSharedPtr<KoMacro::Action> action2_2; // action of the parsen macro2, for test12 + KSharedPtr<KoMacro::Action> action3_2; // action of the parsen macro3, for test12 + + /** + * Represents a @a QValuList of @a MacroItem which are parsen in the + * correspondig @a Macro . + */ + QValueList<KSharedPtr<KoMacro::MacroItem > > macroitems2; // items of macro2 + QValueList<KSharedPtr<KoMacro::MacroItem > > macroitems3; // items of macro3 + + /** + * @a MacroItem instances which ist fillen manually from the given XML + * and parsen by the @a XMLHandler over the XML. + */ + KSharedPtr<KoMacro::MacroItem> macroitem; // created manually from XML + KSharedPtr<KoMacro::MacroItem> macroitem2; // parsen from XML in macro2 + KSharedPtr<KoMacro::MacroItem> macroitem3; // parsen from XML in macro3 + KSharedPtr<KoMacro::MacroItem> macroitem_2; // created manually from XML, for test12 + KSharedPtr<KoMacro::MacroItem> macroitem2_2;// parsen from XML in macro2, for test12 + KSharedPtr<KoMacro::MacroItem> macroitem3_2;// parsen from XML in macro3, for test12 + + Private() + : xmlguiclient(0) + , testaction(0) + { + } + }; +} + +XMLHandlerTests2::XMLHandlerTests2() + : KUnitTest::SlotTester() + , d( new Private() ) // create the private d-pointer instance. +{ +} + +XMLHandlerTests2::~XMLHandlerTests2() +{ + delete d->xmlguiclient; + delete d; +} + + +void XMLHandlerTests2::setUp() +{ + d->xmlguiclient = new KXMLGUIClient(); + + //Singelton more or less ... + if (::KoMacro::Manager::self() == 0) { + ::KoMacro::Manager::init( d->xmlguiclient ); + } + + d->macro = KoMacro::Manager::self()->createMacro("testMacro"); + d->macro2 = KoMacro::Manager::self()->createMacro("testMacro"); + d->macro3 = KoMacro::Manager::self()->createMacro("testMacro"); + + d->testaction = new TestAction(); + d->testaction_2 = new TestAction(); + ::KoMacro::Manager::self()->publishAction(d->testaction); + ::KoMacro::Manager::self()->publishAction(d->testaction_2); +} + +void XMLHandlerTests2::tearDown() +{ + delete d->xmlguiclient; +} + +/** +* Test the @a KoMacro::XMLHandler parseXML() and toXML()-function. +*/ +void XMLHandlerTests2::testParseAndToXML() +{ + kdDebug()<<"===================== testParseAndToXML2() ======================" << endl; + + // 1.Test - Correct DomElement. + testCorrectDomElement(); + // 2.Test - XML-document with bad root element. + testBadRoot(); + // 3.Test - XML-document with a missing Variable. + testMissingVariable(); + // 4.Test - One more Variable in XML-Document. + testMoreVariables(); + // 5.Test - XML-document with wrong macro-xmlversion. + testWrongVersion(); + // 6.Test - XML-document if it has a wrong structure like wrong parathesis + // or missing end tag. + testWrongXMLStruct(); + // 7.Test-XML-document with maximum field-size. + testMaxNum(); + // 8.Test-XML-document with maximum+1 field-size. + testMaxNum2(); + // 9.Test-XML-document with minimum field-size. + testMinNum(); + // 10.Test-XML-document with minimum-1 field-size. + testMinNum2(); + // 11.Test - With a to big number. + testBigNumber(); + // 12.Test - With two MacroItems. + testTwoMacroItems(); +} + + +/*************************************************************************** +* Begin of Sub-methos of testParseXML(). +***************************************************************************/ +// 1.Test - Correct DomElement. +void XMLHandlerTests2::testCorrectDomElement() +{ + // Clear macroitems in the macros. + d->macro->clearItems(); + d->macro2->clearItems(); + d->macro3->clearItems(); + + // Part 1: From XML to a Macro. + // Test-XML-document with normal allocated variables. + const QString xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" >0</variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" >0.6</variable>" + "</item>" + "</macro>"); + // Set the XML-document with the above string. + QDomDocument doomdocument; + doomdocument.setContent(xml); + const QDomElement elem = doomdocument.documentElement(); + + // Create a MacroItem with the TestAction for macro2 and add it to macro. + d->macroitem = new KoMacro::MacroItem(); + d->macro->addItem(d->macroitem); + + d->macroitem->setAction(d->testaction); + + // Push the Variables into the macroitem. + KSharedPtr<KoMacro::Variable> varstring = d->macroitem->addVariable("teststring",QVariant("test_string")); + KSharedPtr<KoMacro::Variable> varint = d->macroitem->addVariable("testint",QVariant(0)); + KSharedPtr<KoMacro::Variable> varbool = d->macroitem->addVariable("testbool",QVariant(true)); + KSharedPtr<KoMacro::Variable> vardouble = d->macroitem->addVariable("testdouble",QVariant(0.6)); + + // Is our XML parseable into a 2. Macro by calling parseXML()? + KOMACROTEST_ASSERT(d->macro2->parseXML(elem),true); + + // Go down to the MacroItem of macro2. + d->macroitems2 = d->macro2->items(); + // 1a.comparison - Test if the MacroItems have the correct number? + KOMACROTEST_ASSERT(d->macroitems2.size(),(sizetypelist)1); + + { + // 2a.comparison - Test if the Action is correct? + d->macroitem2 = *d->macroitems2.constBegin(); + d->action2 = d->macroitem2->action(); + KOMACROTEST_ASSERT(assertActionsEqual(d->testaction,d->action2),true); + + // 3a.comparison - Test if the Variables have the correct number? + KOMACROTEST_ASSERT(d->macroitem2->variables().size(),(sizetypemap)4); + { + // 4a.comparison - Test if the Variables are equal. + KOMACROTEST_ASSERT(assertVariablesEqual(varstring, d->macroitem2->variable("teststring")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varint, d->macroitem2->variable("testint")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbool, d->macroitem2->variable("testbool")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(vardouble, d->macroitem2->variable("testdouble")), true); + } + } + // Change varint and the belonging Variable in the parsen macro2test + // and test it in the macro3 below + varint->setVariant(117); + d->macroitem2->variable("testint")->setVariant(117); + + // Now convert the parsen macro2 back to a QDomElement and again into macro3 for a better comparison. + const QDomElement elem2 = d->macro2->toXML(); + KOMACROTEST_ASSERT(d->macro3->parseXML(elem2),true); + + // Go down to the MacroItem of macro2. + d->macroitems3 = d->macro3->items(); + // 1b.comparison - Test if the MacroItems have the correct number? + KOMACROTEST_ASSERT(d->macroitems3.size(),(sizetypelist)1); + + { + // 2b.comparison - Test if the Action is correct? + d->macroitem3 = *d->macroitems3.constBegin(); + d->action3 = d->macroitem3->action(); + KOMACROTEST_ASSERT(assertActionsEqual(d->testaction,d->action3),true); + + // 3b.comparison - Test if the Variables have the correct number? + KOMACROTEST_ASSERT(d->macroitem3->variables().size(),(sizetypemap)4); + { + // 4b.comparison - Test if the Variables are equal. + KOMACROTEST_ASSERT(assertVariablesEqual(varstring, d->macroitem3->variable("teststring")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varint, d->macroitem3->variable("testint")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbool, d->macroitem3->variable("testbool")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(vardouble, d->macroitem3->variable("testdouble")), true); + } + } +} + + +// 2.Test - XML-document with bad root element. +void XMLHandlerTests2::testBadRoot() +{ + // Clear macroitems in the macros. + d->macro->clearItems(); + d->macro2->clearItems(); + d->macro3->clearItems(); + + // Part 1: From XML to a Macro. + // Test-XML-document with normal allocated variables. + const QString xml = QString("<!DOCTYPE macros>" + "<maro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" >0</variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" >0.6</variable>" + "</item>" + "</maro>"); + // Set the XML-document with the above string. + QDomDocument doomdocument; + doomdocument.setContent(xml); + const QDomElement elem = doomdocument.documentElement(); + + // Create a MacroItem with the TestAction for macro2 and add it to macro. + d->macroitem = new KoMacro::MacroItem(); + d->macro->addItem(d->macroitem); + + d->macroitem->setAction(d->testaction); + + // Push the Variables into the macroitem. + KSharedPtr<KoMacro::Variable> varstring = d->macroitem->addVariable("teststring",QVariant("test_string")); + KSharedPtr<KoMacro::Variable> varint = d->macroitem->addVariable("testint",QVariant(0)); + KSharedPtr<KoMacro::Variable> varbool = d->macroitem->addVariable("testbool",QVariant(true)); + KSharedPtr<KoMacro::Variable> vardouble = d->macroitem->addVariable("testdouble",QVariant(0.6)); + + // Is our XML parseable into a 2. Macro by calling parseXML()? + KOMACROTEST_XASSERT(d->macro2->parseXML(elem),true); +} + +// 3.Test - XML-document with a missing Variable. +void XMLHandlerTests2::testMissingVariable() +{ + // Clear macroitems in the macros. + d->macro->clearItems(); + d->macro2->clearItems(); + d->macro3->clearItems(); + + // Part 1: From XML to a Macro. + // Test-XML-document with normal allocated variables. + const QString xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" >0</variable>" + "<variable name=\"testdouble\" >0.6</variable>" + "</item>" + "</macro>"); + // Set the XML-document with the above string. + QDomDocument doomdocument; + doomdocument.setContent(xml); + const QDomElement elem = doomdocument.documentElement(); + + // Create a MacroItem with the TestAction for macro2 and add it to macro. + d->macroitem = new KoMacro::MacroItem(); + d->macro->addItem(d->macroitem); + + d->macroitem->setAction(d->testaction); + + // Push the Variables into the macroitem. + KSharedPtr<KoMacro::Variable> varstring = d->macroitem->addVariable("teststring",QVariant("test_string")); + KSharedPtr<KoMacro::Variable> varint = d->macroitem->addVariable("testint",QVariant(0)); + KSharedPtr<KoMacro::Variable> vardouble = d->macroitem->addVariable("testdouble",QVariant(0.6)); + + // Is our XML parseable into a 2. Macro by calling parseXML()? + KOMACROTEST_ASSERT(d->macro2->parseXML(elem),true); + + // Go down to the MacroItem of macro2. + d->macroitems2 = d->macro2->items(); + // 1a.comparison - Test if the MacroItems have the correct number? + KOMACROTEST_ASSERT(d->macroitems2.size(),(sizetypelist)1); + + { + // 2a.comparison - Test if the Action is correct? + d->macroitem2 = *d->macroitems2.constBegin(); + d->action2 = d->macroitem2->action(); + KOMACROTEST_ASSERT(assertActionsEqual(d->testaction,d->action2),true); + + // 3a.comparison - Test if the Variables have the correct number? + KOMACROTEST_ASSERT(d->macroitem2->variables().size(),(sizetypemap)3); + { + // 4a.comparison - Test if the Variables are equal. + KOMACROTEST_ASSERT(assertVariablesEqual(varstring, d->macroitem2->variable("teststring")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varint, d->macroitem2->variable("testint")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(vardouble, d->macroitem2->variable("testdouble")), true); + } + } + + // Now convert the parsen macro2 back to a QDomElement and again into macro3 for a better comparison. + const QDomElement elem2 = d->macro2->toXML(); + KOMACROTEST_ASSERT(d->macro3->parseXML(elem2),true); + + // Go down to the MacroItem of macro2. + d->macroitems3 = d->macro3->items(); + // 1b.comparison - Test if the MacroItems have the correct number? + KOMACROTEST_ASSERT(d->macroitems3.size(),(sizetypelist)1); + + { + // 2b.comparison - Test if the Action is correct? + d->macroitem3 = *d->macroitems3.constBegin(); + d->action3 = d->macroitem3->action(); + KOMACROTEST_ASSERT(assertActionsEqual(d->testaction,d->action3),true); + + // 3b.comparison - Test if the Variables have the correct number? + KOMACROTEST_ASSERT(d->macroitem3->variables().size(),(sizetypemap)3); + { + // 4b.comparison - Test if the Variables are equal. + KOMACROTEST_ASSERT(assertVariablesEqual(varstring, d->macroitem3->variable("teststring")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varint, d->macroitem3->variable("testint")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(vardouble, d->macroitem3->variable("testdouble")), true); + } + } +} + +// 4.Test - One more Variable in XML-Document. +void XMLHandlerTests2::testMoreVariables() +{ + // Clear macroitems in the macros. + d->macro->clearItems(); + d->macro2->clearItems(); + d->macro3->clearItems(); + + // Part 1: From XML to a Macro. + // Test-XML-document with normal allocated variables. + const QString xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" >0</variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" >0.6</variable>" + "<variable name=\"testbla\" >somethingwrong</variable>" + "</item>" + "</macro>"); + // Set the XML-document with the above string. + QDomDocument doomdocument; + doomdocument.setContent(xml); + const QDomElement elem = doomdocument.documentElement(); + + // Create a MacroItem with the TestAction for macro2 and add it to macro. + d->macroitem = new KoMacro::MacroItem(); + d->macro->addItem(d->macroitem); + + d->macroitem->setAction(d->testaction); + + // Push the Variables into the macroitem. + KSharedPtr<KoMacro::Variable> varstring = d->macroitem->addVariable("teststring",QVariant("test_string")); + KSharedPtr<KoMacro::Variable> varint = d->macroitem->addVariable("testint",QVariant(0)); + KSharedPtr<KoMacro::Variable> varbool = d->macroitem->addVariable("testbool",QVariant(true)); + KSharedPtr<KoMacro::Variable> vardouble = d->macroitem->addVariable("testdouble",QVariant(0.6)); + KSharedPtr<KoMacro::Variable> varbla = d->macroitem->addVariable("testbla","somethingwrong"); + + // Is our XML parseable into a 2. Macro by calling parseXML()? + KOMACROTEST_ASSERT(d->macro2->parseXML(elem),true); + + // Go down to the MacroItem of macro2. + d->macroitems2 = d->macro2->items(); + // 1a.comparison - Test if the MacroItems have the correct number? + KOMACROTEST_ASSERT(d->macroitems2.size(),(sizetypelist)1); + + { + // 2a.comparison - Test if the Action is correct? + d->macroitem2 = *d->macroitems2.constBegin(); + d->action2 = d->macroitem2->action(); + KOMACROTEST_ASSERT(assertActionsEqual(d->testaction,d->action2),true); + + // 3a.comparison - Test if the Variables have the correct number? + KOMACROTEST_ASSERT(d->macroitem2->variables().size(),(sizetypemap)5); + { + // 4a.comparison - Test if the Variables are equal. + KOMACROTEST_ASSERT(assertVariablesEqual(varstring, d->macroitem2->variable("teststring")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varint, d->macroitem2->variable("testint")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbool, d->macroitem2->variable("testbool")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(vardouble, d->macroitem2->variable("testdouble")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbla, d->macroitem2->variable("testbla")), true); + } + } + + // Now convert the parsen macro2 back to a QDomElement and again into macro3 for a better comparison. + const QDomElement elem2 = d->macro2->toXML(); + KOMACROTEST_ASSERT(d->macro3->parseXML(elem2),true); + + // Go down to the MacroItem of macro2. + d->macroitems3 = d->macro3->items(); + // 1b.comparison - Test if the MacroItems have the correct number? + KOMACROTEST_ASSERT(d->macroitems3.size(),(sizetypelist)1); + + { + // 2b.comparison - Test if the Action is correct? + d->macroitem3 = *d->macroitems3.constBegin(); + d->action3 = d->macroitem3->action(); + KOMACROTEST_ASSERT(assertActionsEqual(d->testaction,d->action3),true); + + // 3b.comparison - Test if the Variables have the correct number? + KOMACROTEST_ASSERT(d->macroitem3->variables().size(),(sizetypemap)5); + { + // 4b.comparison - Test if the Variables are equal. + KOMACROTEST_ASSERT(assertVariablesEqual(varstring, d->macroitem3->variable("teststring")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varint, d->macroitem3->variable("testint")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbool, d->macroitem3->variable("testbool")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(vardouble, d->macroitem3->variable("testdouble")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbla, d->macroitem3->variable("testbla")), true); + } + } +} + + +// 5.Test - XML-document with wrong macro-xmlversion. +void XMLHandlerTests2::testWrongVersion() +{ + // Clear macroitems in the macros. + d->macro->clearItems(); + d->macro2->clearItems(); + d->macro3->clearItems(); + + // Part 1: From XML to a Macro. + // Test-XML-document with normal allocated variables. + const QString xml = QString("<!DOCTYPE macros>" + "<maro xmlversion=\"2\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" >0</variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" >0.6</variable>" + "</item>" + "</maro>"); + // Set the XML-document with the above string. + QDomDocument doomdocument; + doomdocument.setContent(xml); + const QDomElement elem = doomdocument.documentElement(); + + // Create a MacroItem with the TestAction for macro2 and add it to macro. + d->macroitem = new KoMacro::MacroItem(); + d->macro->addItem(d->macroitem); + + d->macroitem->setAction(d->testaction); + + // Push the Variables into the macroitem. + KSharedPtr<KoMacro::Variable> varstring = d->macroitem->addVariable("teststring",QVariant("test_string")); + KSharedPtr<KoMacro::Variable> varint = d->macroitem->addVariable("testint",QVariant(0)); + KSharedPtr<KoMacro::Variable> varbool = d->macroitem->addVariable("testbool",QVariant(true)); + KSharedPtr<KoMacro::Variable> vardouble = d->macroitem->addVariable("testdouble",QVariant(0.6)); + + // Is our XML parseable into a 2. Macro by calling parseXML()? + KOMACROTEST_XASSERT(d->macro2->parseXML(elem),true); +} + + +// 6.Test - XML-document if it has a wrong structure like wrong parathesis +// or missing end tag. +void XMLHandlerTests2::testWrongXMLStruct() +{ + // Clear macroitems in the macros. + d->macro->clearItems(); + d->macro2->clearItems(); + d->macro3->clearItems(); + + // Part 1: From XML to a Macro. + // Test-XML-document with normal allocated variables. + const QString xml = QString("<!DOCTYPE macros>" + "maro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" >0</variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" >0.6</variable>" + "</item>" + "</maro>"); + // Set the XML-document with the above string. + QDomDocument doomdocument; + doomdocument.setContent(xml); + const QDomElement elem = doomdocument.documentElement(); + + // Create a MacroItem with the TestAction for macro2 and add it to macro. + d->macroitem = new KoMacro::MacroItem(); + d->macro->addItem(d->macroitem); + + d->macroitem->setAction(d->testaction); + + // Push the Variables into the macroitem. + KSharedPtr<KoMacro::Variable> varstring = d->macroitem->addVariable("teststring",QVariant("test_string")); + KSharedPtr<KoMacro::Variable> varint = d->macroitem->addVariable("testint",QVariant(0)); + KSharedPtr<KoMacro::Variable> varbool = d->macroitem->addVariable("testbool",QVariant(true)); + KSharedPtr<KoMacro::Variable> vardouble = d->macroitem->addVariable("testdouble",QVariant(0.6)); + + // Is our XML parseable into a 2. Macro by calling parseXML()? + KOMACROTEST_XASSERT(d->macro2->parseXML(elem),true); +} + +// 7.Test-XML-document with maximum field-size. +void XMLHandlerTests2::testMaxNum() +{ + // Clear macroitems in the macros. + d->macro->clearItems(); + d->macro2->clearItems(); + d->macro3->clearItems(); + + // Part 1: From XML to a Macro. + // Test-XML-document with normal allocated variables. + const QString xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" > %1 </variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" > %2 </variable>" + "</item>" + "</macro>").arg(INT_MAX).arg(DBL_MAX); + // Set the XML-document with the above string. + QDomDocument doomdocument; + doomdocument.setContent(xml); + const QDomElement elem = doomdocument.documentElement(); + + // Create a MacroItem with the TestAction for macro2 and add it to macro. + d->macroitem = new KoMacro::MacroItem(); + d->macro->addItem(d->macroitem); + + d->macroitem->setAction(d->testaction); + + // Push the Variables into the macroitem. + KSharedPtr<KoMacro::Variable> varstring = d->macroitem->addVariable("teststring",QVariant("test_string")); + KSharedPtr<KoMacro::Variable> varint = d->macroitem->addVariable("testint",QVariant(INT_MAX)); + KSharedPtr<KoMacro::Variable> varbool = d->macroitem->addVariable("testbool",QVariant(true)); + KSharedPtr<KoMacro::Variable> vardouble = d->macroitem->addVariable("testdouble",QVariant(DBL_MAX)); + + // Is our XML parseable into a 2. Macro by calling parseXML()? + KOMACROTEST_ASSERT(d->macro2->parseXML(elem),true); + + // Go down to the MacroItem of macro2. + d->macroitems2 = d->macro2->items(); + // 1a.comparison - Test if the MacroItems have the correct number? + KOMACROTEST_ASSERT(d->macroitems2.size(),(sizetypelist)1); + + { + // 2a.comparison - Test if the Action is correct? + d->macroitem2 = *d->macroitems2.constBegin(); + d->action2 = d->macroitem2->action(); + KOMACROTEST_ASSERT(assertActionsEqual(d->testaction,d->action2),true); + + // 3a.comparison - Test if the Variables have the correct number? + KOMACROTEST_ASSERT(d->macroitem2->variables().size(),(sizetypemap)4); + { + // 4a.comparison - Test if the Variables are equal. + KOMACROTEST_ASSERT(assertVariablesEqual(varstring, d->macroitem2->variable("teststring")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varint, d->macroitem2->variable("testint")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbool, d->macroitem2->variable("testbool")), true); +// KOMACROTEST_ASSERT(assertVariablesEqual(vardouble, d->macroitem2->variable("testdouble")), true); + } + } + + // Now convert the parsen macro2 back to a QDomElement and again into macro3 for a better comparison. + const QDomElement elem2 = d->macro2->toXML(); + KOMACROTEST_ASSERT(d->macro3->parseXML(elem2),true); + + // Go down to the MacroItem of macro2. + d->macroitems3 = d->macro3->items(); + // 1b.comparison - Test if the MacroItems have the correct number? + KOMACROTEST_ASSERT(d->macroitems3.size(),(sizetypelist)1); + + { + // 2b.comparison - Test if the Action is correct? + d->macroitem3 = *d->macroitems3.constBegin(); + d->action3 = d->macroitem3->action(); + KOMACROTEST_ASSERT(assertActionsEqual(d->testaction,d->action3),true); + + // 3b.comparison - Test if the Variables have the correct number? + KOMACROTEST_ASSERT(d->macroitem3->variables().size(),(sizetypemap)4); + { + // 4b.comparison - Test if the Variables are equal. + KOMACROTEST_ASSERT(assertVariablesEqual(varstring, d->macroitem3->variable("teststring")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varint, d->macroitem3->variable("testint")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbool, d->macroitem3->variable("testbool")), true); +// KOMACROTEST_ASSERT(assertVariablesEqual(vardouble, d->macroitem3->variable("testdouble")),true); + } + } +} + +// 8.Test-XML-document with maximum+1 field-size. +void XMLHandlerTests2::testMaxNum2() +{ + // Clear macroitems in the macros. + d->macro->clearItems(); + d->macro2->clearItems(); + d->macro3->clearItems(); + + // Part 1: From XML to a Macro. + // Test-XML-document with normal allocated variables. + const QString xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" > %1 </variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" > %2 </variable>" + "</item>" + "</macro>").arg(INT_MAX+1).arg(DBL_MAX+1); + // Set the XML-document with the above string. + QDomDocument doomdocument; + doomdocument.setContent(xml); + const QDomElement elem = doomdocument.documentElement(); + + // Create a MacroItem with the TestAction for macro2 and add it to macro. + d->macroitem = new KoMacro::MacroItem(); + d->macro->addItem(d->macroitem); + + d->macroitem->setAction(d->testaction); + + // Push the Variables into the macroitem. + KSharedPtr<KoMacro::Variable> varstring = d->macroitem->addVariable("teststring",QVariant("test_string")); + KSharedPtr<KoMacro::Variable> varint = d->macroitem->addVariable("testint",QVariant(INT_MAX+1)); + KSharedPtr<KoMacro::Variable> varbool = d->macroitem->addVariable("testbool",QVariant(true)); + KSharedPtr<KoMacro::Variable> vardouble = d->macroitem->addVariable("testdouble",QVariant(DBL_MAX+1)); + + // Is our XML parseable into a 2. Macro by calling parseXML()? + KOMACROTEST_ASSERT(d->macro2->parseXML(elem),true); + + // Go down to the MacroItem of macro2. + d->macroitems2 = d->macro2->items(); + // 1a.comparison - Test if the MacroItems have the correct number? + KOMACROTEST_ASSERT(d->macroitems2.size(),(sizetypelist)1); + + { + // 2a.comparison - Test if the Action is correct? + d->macroitem2 = *d->macroitems2.constBegin(); + d->action2 = d->macroitem2->action(); + KOMACROTEST_ASSERT(assertActionsEqual(d->testaction,d->action2),true); + + // 3a.comparison - Test if the Variables have the correct number? + KOMACROTEST_ASSERT(d->macroitem2->variables().size(),(sizetypemap)4); + { + // 4a.comparison - Test if the Variables are equal. + KOMACROTEST_ASSERT(assertVariablesEqual(varstring, d->macroitem2->variable("teststring")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varint, d->macroitem2->variable("testint")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbool, d->macroitem2->variable("testbool")), true); +// KOMACROTEST_ASSERT(assertVariablesEqual(vardouble, d->macroitem2->variable("testdouble")),true); + } + } + + // Now convert the parsen macro2 back to a QDomElement and again into macro3 for a better comparison. + const QDomElement elem2 = d->macro2->toXML(); + KOMACROTEST_ASSERT(d->macro3->parseXML(elem2),true); + + // Go down to the MacroItem of macro2. + d->macroitems3 = d->macro3->items(); + // 1b.comparison - Test if the MacroItems have the correct number? + KOMACROTEST_ASSERT(d->macroitems3.size(),(sizetypelist)1); + + { + // 2b.comparison - Test if the Action is correct? + d->macroitem3 = *d->macroitems3.constBegin(); + d->action3 = d->macroitem3->action(); + KOMACROTEST_ASSERT(assertActionsEqual(d->testaction,d->action3),true); + + // 3b.comparison - Test if the Variables have the correct number? + KOMACROTEST_ASSERT(d->macroitem3->variables().size(),(sizetypemap)4); + { + // 4b.comparison - Test if the Variables are equal. + KOMACROTEST_ASSERT(assertVariablesEqual(varstring, d->macroitem3->variable("teststring")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varint, d->macroitem3->variable("testint")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbool, d->macroitem3->variable("testbool")), true); +// KOMACROTEST_ASSERT(assertVariablesEqual(vardouble, d->macroitem3->variable("testdouble")),true); + } + } +} + +// 9.Test-XML-document with minimum field-size. +void XMLHandlerTests2::testMinNum() +{ + // Clear macroitems in the macros. + d->macro->clearItems(); + d->macro2->clearItems(); + d->macro3->clearItems(); + + // Part 1: From XML to a Macro. + // Test-XML-document with normal allocated variables. + const QString xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" > %1 </variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" > %2 </variable>" + "</item>" + "</macro>").arg(INT_MIN).arg(DBL_MIN); + // Set the XML-document with the above string. + QDomDocument doomdocument; + doomdocument.setContent(xml); + const QDomElement elem = doomdocument.documentElement(); + + // Create a MacroItem with the TestAction for macro2 and add it to macro. + d->macroitem = new KoMacro::MacroItem(); + d->macro->addItem(d->macroitem); + + d->macroitem->setAction(d->testaction); + + // Push the Variables into the macroitem. + KSharedPtr<KoMacro::Variable> varstring = d->macroitem->addVariable("teststring",QVariant("test_string")); + KSharedPtr<KoMacro::Variable> varint = d->macroitem->addVariable("testint",QVariant(INT_MIN)); + KSharedPtr<KoMacro::Variable> varbool = d->macroitem->addVariable("testbool",QVariant(true)); + KSharedPtr<KoMacro::Variable> vardouble = d->macroitem->addVariable("testdouble",QVariant(DBL_MIN)); + + // Is our XML parseable into a 2. Macro by calling parseXML()? + KOMACROTEST_ASSERT(d->macro2->parseXML(elem),true); + + // Go down to the MacroItem of macro2. + d->macroitems2 = d->macro2->items(); + // 1a.comparison - Test if the MacroItems have the correct number? + KOMACROTEST_ASSERT(d->macroitems2.size(),(sizetypelist)1); + + { + // 2a.comparison - Test if the Action is correct? + d->macroitem2 = *d->macroitems2.constBegin(); + d->action2 = d->macroitem2->action(); + KOMACROTEST_ASSERT(assertActionsEqual(d->testaction,d->action2),true); + + // 3a.comparison - Test if the Variables have the correct number? + KOMACROTEST_ASSERT(d->macroitem2->variables().size(),(sizetypemap)4); + { + // 4a.comparison - Test if the Variables are equal. + KOMACROTEST_ASSERT(assertVariablesEqual(varstring, d->macroitem2->variable("teststring")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varint, d->macroitem2->variable("testint")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbool, d->macroitem2->variable("testbool")), true); +// KOMACROTEST_ASSERT(assertVariablesEqual(vardouble, d->macroitem2->variable("testdouble")),true); + } + } + + // Now convert the parsen macro2 back to a QDomElement and again into macro3 for a better comparison. + const QDomElement elem2 = d->macro2->toXML(); + KOMACROTEST_ASSERT(d->macro3->parseXML(elem2),true); + + // Go down to the MacroItem of macro2. + d->macroitems3 = d->macro3->items(); + // 1b.comparison - Test if the MacroItems have the correct number? + KOMACROTEST_ASSERT(d->macroitems3.size(),(sizetypelist)1); + + { + // 2b.comparison - Test if the Action is correct? + d->macroitem3 = *d->macroitems3.constBegin(); + d->action3 = d->macroitem3->action(); + KOMACROTEST_ASSERT(assertActionsEqual(d->testaction,d->action3),true); + + // 3b.comparison - Test if the Variables have the correct number? + KOMACROTEST_ASSERT(d->macroitem3->variables().size(),(sizetypemap)4); + { + // 4b.comparison - Test if the Variables are equal. + KOMACROTEST_ASSERT(assertVariablesEqual(varstring, d->macroitem3->variable("teststring")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varint, d->macroitem3->variable("testint")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbool, d->macroitem3->variable("testbool")), true); +// KOMACROTEST_ASSERT(assertVariablesEqual(vardouble, d->macroitem3->variable("testdouble")),true); + } + } +} + +// 10.Test-XML-document with minimum+1 field-size. +void XMLHandlerTests2::testMinNum2() +{ + // Clear macroitems in the macros. + d->macro->clearItems(); + d->macro2->clearItems(); + d->macro3->clearItems(); + + // Part 1: From XML to a Macro. + // Test-XML-document with normal allocated variables. + const QString xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" > %1 </variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" > %2 </variable>" + "</item>" + "</macro>").arg(INT_MIN-1).arg(DBL_MIN-1); + // Set the XML-document with the above string. + QDomDocument doomdocument; + doomdocument.setContent(xml); + const QDomElement elem = doomdocument.documentElement(); + + // Create a MacroItem with the TestAction for macro2 and add it to macro. + d->macroitem = new KoMacro::MacroItem(); + d->macro->addItem(d->macroitem); + + d->macroitem->setAction(d->testaction); + + // Push the Variables into the macroitem. + KSharedPtr<KoMacro::Variable> varstring = d->macroitem->addVariable("teststring",QVariant("test_string")); + KSharedPtr<KoMacro::Variable> varint = d->macroitem->addVariable("testint",QVariant(INT_MIN-1)); + KSharedPtr<KoMacro::Variable> varbool = d->macroitem->addVariable("testbool",QVariant(true)); + KSharedPtr<KoMacro::Variable> vardouble = d->macroitem->addVariable("testdouble",QVariant(DBL_MIN-1)); + + // Is our XML parseable into a 2. Macro by calling parseXML()? + KOMACROTEST_ASSERT(d->macro2->parseXML(elem),true); + + // Go down to the MacroItem of macro2. + d->macroitems2 = d->macro2->items(); + // 1a.comparison - Test if the MacroItems have the correct number? + KOMACROTEST_ASSERT(d->macroitems2.size(),(sizetypelist)1); + + { + // 2a.comparison - Test if the Action is correct? + d->macroitem2 = *d->macroitems2.constBegin(); + d->action2 = d->macroitem2->action(); + KOMACROTEST_ASSERT(assertActionsEqual(d->testaction,d->action2),true); + + // 3a.comparison - Test if the Variables have the correct number? + KOMACROTEST_ASSERT(d->macroitem2->variables().size(),(sizetypemap)4); + { + // 4a.comparison - Test if the Variables are equal. + KOMACROTEST_ASSERT(assertVariablesEqual(varstring, d->macroitem2->variable("teststring")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varint, d->macroitem2->variable("testint")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbool, d->macroitem2->variable("testbool")), true); +// KOMACROTEST_ASSERT(assertVariablesEqual(vardouble, d->macroitem2->variable("testdouble")),true); + } + } + + // Now convert the parsen macro2 back to a QDomElement and again into macro3 for a better comparison. + const QDomElement elem2 = d->macro2->toXML(); + KOMACROTEST_ASSERT(d->macro3->parseXML(elem2),true); + + // Go down to the MacroItem of macro2. + d->macroitems3 = d->macro3->items(); + // 1b.comparison - Test if the MacroItems have the correct number? + KOMACROTEST_ASSERT(d->macroitems3.size(),(sizetypelist)1); + + { + // 2b.comparison - Test if the Action is correct? + d->macroitem3 = *d->macroitems3.constBegin(); + d->action3 = d->macroitem3->action(); + KOMACROTEST_ASSERT(assertActionsEqual(d->testaction,d->action3),true); + + // 3b.comparison - Test if the Variables have the correct number? + KOMACROTEST_ASSERT(d->macroitem3->variables().size(),(sizetypemap)4); + { + // 4b.comparison - Test if the Variables are equal. + KOMACROTEST_ASSERT(assertVariablesEqual(varstring, d->macroitem3->variable("teststring")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varint, d->macroitem3->variable("testint")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbool, d->macroitem3->variable("testbool")), true); +// KOMACROTEST_ASSERT(assertVariablesEqual(vardouble, d->macroitem3->variable("testdouble")),true); + } + } +} + +// 11.Test - With a to big number. +void XMLHandlerTests2::testBigNumber() +{ + // Clear macroitems in the macros. + d->macro->clearItems(); + d->macro2->clearItems(); + d->macro3->clearItems(); + + // Part 1: From XML to a Macro. + // Test-XML-document with normal allocated variables. + const QString xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" >0123456789012345678901234567890123456789</variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" >0.6</variable>" + "</item>" + "</macro>"); + // Set the XML-document with the above string. + QDomDocument doomdocument; + doomdocument.setContent(xml); + const QDomElement elem = doomdocument.documentElement(); + + // Create a MacroItem with the TestAction for macro2 and add it to macro. + d->macroitem = new KoMacro::MacroItem(); + d->macro->addItem(d->macroitem); + + d->macroitem->setAction(d->testaction); + + // Push the Variables into the macroitem. + KSharedPtr<KoMacro::Variable> varstring = d->macroitem->addVariable("teststring",QVariant("test_string")); + //TODO //KSharedPtr<KoMacro::Variable> varint = d->macroitem->addVariable("testint",QVariant(0123456789012345678901234567890123456789)); + KSharedPtr<KoMacro::Variable> varbool = d->macroitem->addVariable("testbool",QVariant(true)); + KSharedPtr<KoMacro::Variable> vardouble = d->macroitem->addVariable("testdouble",QVariant(0.6)); + + // Is our XML parseable into a 2. Macro by calling parseXML()? + KOMACROTEST_ASSERT(d->macro2->parseXML(elem),true); + + // Go down to the MacroItem of macro2. + d->macroitems2 = d->macro2->items(); + // 1a.comparison - Test if the MacroItems have the correct number? + KOMACROTEST_ASSERT(d->macroitems2.size(),(sizetypelist)1); + + { + // 2a.comparison - Test if the Action is correct? + d->macroitem2 = *d->macroitems2.constBegin(); + d->action2 = d->macroitem2->action(); + KOMACROTEST_ASSERT(assertActionsEqual(d->testaction,d->action2),true); + + // 3a.comparison - Test if the Variables have the correct number? + KOMACROTEST_ASSERT(d->macroitem2->variables().size(),(sizetypemap)4); + { + // 4a.comparison - Test if the Variables are equal. + KOMACROTEST_ASSERT(assertVariablesEqual(varstring, d->macroitem2->variable("teststring")), true); + //KOMACROTEST_ASSERT(assertVariablesEqual(varint, d->macroitem2->variable("testint")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbool, d->macroitem2->variable("testbool")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(vardouble, d->macroitem2->variable("testdouble")), true); + } + } + + // Now convert the parsen macro2 back to a QDomElement and again into macro3 for a better comparison. + const QDomElement elem2 = d->macro2->toXML(); + KOMACROTEST_ASSERT(d->macro3->parseXML(elem2),true); + + // Go down to the MacroItem of macro2. + d->macroitems3 = d->macro3->items(); + // 1b.comparison - Test if the MacroItems have the correct number? + KOMACROTEST_ASSERT(d->macroitems3.size(),(sizetypelist)1); + + { + // 2b.comparison - Test if the Action is correct? + d->macroitem3 = *d->macroitems3.constBegin(); + d->action3 = d->macroitem3->action(); + KOMACROTEST_ASSERT(assertActionsEqual(d->testaction,d->action3),true); + + // 3b.comparison - Test if the Variables have the correct number? + KOMACROTEST_ASSERT(d->macroitem3->variables().size(),(sizetypemap)4); + { + // 4b.comparison - Test if the Variables are equal. + KOMACROTEST_ASSERT(assertVariablesEqual(varstring, d->macroitem3->variable("teststring")), true); + //KOMACROTEST_ASSERT(assertVariablesEqual(varint, d->macroitem3->variable("testint")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbool, d->macroitem3->variable("testbool")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(vardouble, d->macroitem3->variable("testdouble")), true); + } + } +} + +// 12.Test - With two MacroItems. +void XMLHandlerTests2::testTwoMacroItems() +{ + // Clear macroitems in the macros. + d->macro->clearItems(); + d->macro2->clearItems(); + d->macro3->clearItems(); + + // Part 1: From XML to a Macro. + // Test-XML-document with normal allocated variables. + const QString xml = QString("<!DOCTYPE macros>" + "<macro xmlversion=\"1\">" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >test_string</variable>" + "<variable name=\"testint\" >0</variable>" + "<variable name=\"testbool\" >true</variable>" + "<variable name=\"testdouble\" >0.6</variable>" + "<variable name=\"testbla\" >somethingwrong</variable>" + "</item>" + "<item action=\"testaction\" >" + "<variable name=\"teststring\" >testString2</variable>" + "<variable name=\"testint\" >4</variable>" + "<variable name=\"testbool\" >false</variable>" + "<variable name=\"testdouble\" >0.7</variable>" + "<variable name=\"testbla\" >somethingwrong2</variable>" + "</item>" + "</macro>"); + // Set the XML-document with the above string. + QDomDocument doomdocument; + doomdocument.setContent(xml); + const QDomElement elem = doomdocument.documentElement(); + + // Create a MacroItem with the TestAction for macro2 and add it to macro. + d->macroitem = new KoMacro::MacroItem(); + d->macroitem_2 = new KoMacro::MacroItem(); + d->macro->addItem(d->macroitem); + d->macro->addItem(d->macroitem_2); + + d->macroitem->setAction(d->testaction); + d->macroitem_2->setAction(d->testaction_2); + + // Push the Variables into the macroitem. + KSharedPtr<KoMacro::Variable> varstring = d->macroitem->addVariable("teststring",QVariant("test_string")); + KSharedPtr<KoMacro::Variable> varint = d->macroitem->addVariable("testint",QVariant(0)); + KSharedPtr<KoMacro::Variable> varbool = d->macroitem->addVariable("testbool",QVariant(true)); + KSharedPtr<KoMacro::Variable> vardouble = d->macroitem->addVariable("testdouble",QVariant(0.6)); + KSharedPtr<KoMacro::Variable> varbla = d->macroitem->addVariable("testbla","somethingwrong"); + + // Push the Variables into the macroitem4. + KSharedPtr<KoMacro::Variable> varstring_2 = d->macroitem_2->addVariable("teststring",QVariant("testString2")); + KSharedPtr<KoMacro::Variable> varint_2 = d->macroitem_2->addVariable("testint",QVariant(4)); + KSharedPtr<KoMacro::Variable> varbool_2 = d->macroitem_2->addVariable("testbool",QVariant(false)); + KSharedPtr<KoMacro::Variable> vardouble_2 = d->macroitem_2->addVariable("testdouble",QVariant(0.7)); + KSharedPtr<KoMacro::Variable> varbla_2 = d->macroitem_2->addVariable("testbla","somethingwrong2"); + + // Is our XML parseable into a 2. Macro by calling parseXML()? + KOMACROTEST_ASSERT(d->macro2->parseXML(elem),true); + + // Go down to the MacroItem of macro2. + d->macroitems2 = d->macro2->items(); + // 1a.comparison - Test if the MacroItems have the correct number? + KOMACROTEST_ASSERT(d->macroitems2.size(),(sizetypelist)2); + + { + QValueList<KSharedPtr<KoMacro::MacroItem > >::ConstIterator mit2(d->macroitems2.constBegin()); + // 2a.comparison - Test if the Action is correct? + d->macroitem2 = *mit2; + mit2++; + d->macroitem2_2 = *mit2; + d->action2 = d->macroitem2->action(); + d->action2_2 = d->macroitem2_2->action(); + KOMACROTEST_ASSERT(assertActionsEqual(d->testaction,d->action2),true); + KOMACROTEST_ASSERT(assertActionsEqual(d->testaction_2,d->action2_2),true); + + // 3a.comparison - Test if the Variables have the correct number? + KOMACROTEST_ASSERT(d->macroitem2->variables().size(),(sizetypemap)5); + KOMACROTEST_ASSERT(d->macroitem2_2->variables().size(),(sizetypemap)5); + { + // 4a.comparison - Test if the Variables are equal. + KOMACROTEST_ASSERT(assertVariablesEqual(varstring, d->macroitem2->variable("teststring")),true); + KOMACROTEST_ASSERT(assertVariablesEqual(varint, d->macroitem2->variable("testint")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbool, d->macroitem2->variable("testbool")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(vardouble, d->macroitem2->variable("testdouble")),true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbla, d->macroitem2->variable("testbla")),true); + + KOMACROTEST_ASSERT(assertVariablesEqual(varstring_2,d->macroitem2_2->variable("teststring")),true); + KOMACROTEST_ASSERT(assertVariablesEqual(varint_2, d->macroitem2_2->variable("testint")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbool_2, d->macroitem2_2->variable("testbool")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(vardouble_2,d->macroitem2_2->variable("testdouble")),true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbla_2, d->macroitem2_2->variable("testbla")),true); + } + } + + // Now convert the parsen macro2 back to a QDomElement and again into macro3 for a better comparison. + const QDomElement elem2 = d->macro2->toXML(); + KOMACROTEST_ASSERT(d->macro3->parseXML(elem2),true); + + // Go down to the MacroItem of macro2. + d->macroitems3 = d->macro3->items(); + // 1b.comparison - Test if the MacroItems have the correct number? + KOMACROTEST_ASSERT(d->macroitems3.size(),(sizetypelist)2); + + { + QValueList<KSharedPtr<KoMacro::MacroItem > >::ConstIterator mit3(d->macroitems3.constBegin()); + // 2b.comparison - Test if the Action is correct? + d->macroitem3 = *mit3; + mit3++; + d->macroitem3_2 = *mit3; + d->action3 = d->macroitem3->action(); + d->action3_2 = d->macroitem3_2->action(); + KOMACROTEST_ASSERT(assertActionsEqual(d->testaction,d->action3),true); + KOMACROTEST_ASSERT(assertActionsEqual(d->testaction,d->action3_2),true); + + // 3b.comparison - Test if the Variables have the correct number? + KOMACROTEST_ASSERT(d->macroitem3->variables().size(),(sizetypemap)5); + KOMACROTEST_ASSERT(d->macroitem3_2->variables().size(),(sizetypemap)5); + { + // 4b.comparison - Test if the Variables are equal. + KOMACROTEST_ASSERT(assertVariablesEqual(varstring, d->macroitem3->variable("teststring")),true); + KOMACROTEST_ASSERT(assertVariablesEqual(varint, d->macroitem3->variable("testint")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbool, d->macroitem3->variable("testbool")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(vardouble, d->macroitem3->variable("testdouble")),true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbla, d->macroitem3->variable("testbla")),true); + + KOMACROTEST_ASSERT(assertVariablesEqual(varstring_2,d->macroitem3_2->variable("teststring")),true); + KOMACROTEST_ASSERT(assertVariablesEqual(varint_2, d->macroitem3_2->variable("testint")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbool_2, d->macroitem3_2->variable("testbool")), true); + KOMACROTEST_ASSERT(assertVariablesEqual(vardouble_2,d->macroitem3_2->variable("testdouble")),true); + KOMACROTEST_ASSERT(assertVariablesEqual(varbla_2, d->macroitem3_2->variable("testbla")),true); + } + } +} + +/*************************************************************************** +* End of Sub-methos of testParseAndToXML2(). +***************************************************************************/ + +bool XMLHandlerTests2::assertActionsEqual(KSharedPtr<KoMacro::Action> action, + KSharedPtr<KoMacro::Action> action2) +{ + return action->name() == action2->name(); +} + +bool XMLHandlerTests2::assertVariablesEqual(KSharedPtr<KoMacro::Variable> var, + KSharedPtr<KoMacro::Variable> var2) +{ + if ( var->variant() != var2->variant() ) kdDebug() << "Variable1: " << var->variant() << " and Variable2: " << var2->variant() << endl; + return var->variant() == var2->variant(); +} + +#include "xmlhandlertests2.moc" diff --git a/kexi/plugins/macros/tests/xmlhandlertests2.h b/kexi/plugins/macros/tests/xmlhandlertests2.h new file mode 100644 index 00000000..0a3fee3a --- /dev/null +++ b/kexi/plugins/macros/tests/xmlhandlertests2.h @@ -0,0 +1,132 @@ +/*************************************************************************** + * This file is part of the KDE project + * 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 KOMACROTEST_XMLHandlerTests2_H +#define KOMACROTEST_XMLHandlerTests2_H + +#include <kunittest/tester.h> +#include "../lib/macro.h" + +namespace KoMacroTest { + + /** + * The common testsuite used to test common @a KoMacro + * functionality. + */ + class XMLHandlerTests2 : public KUnitTest::SlotTester + { + Q_OBJECT + public: + + /** + * Constructor. + */ + XMLHandlerTests2(); + + /** + * Destructor. + */ + virtual ~XMLHandlerTests2(); + + public slots: + + /** + * This slot got called by KUnitTest before testing + * starts. + */ + void setUp(); + + /** + * This slot got called by KUnitTest after all tests + * are done. + */ + void tearDown(); + + /** + * Test the @a KoMacro::XMLHandler parseXML()-function. + */ + void testParseAndToXML(); + + private: + /// @internal d-pointer class. + class Private; + /// @internal d-pointer instance. + Private* const d; + + typedef QMap<QString,KoMacro::Variable>::size_type sizetypemap; + typedef QValueList<KSharedPtr<KoMacro::MacroItem > >::size_type sizetypelist; + + /** + * Compares a XML-Element with a Macro. Call sub-asserts. + * @p macro The parsen @a Macro. + * @p domelement The given @a QDomElement which is parsen. + * @p isitemsempty Bool for expectation of an empty @a MacroItem -List. + * @p isactionset Bool for expectation that the @a Action -names are equal. + * @p isvariableok QMap of Bools for comparing each @a Variable . + */ +/* void assertMacroContentEqToXML(const KSharedPtr<KoMacro::Macro> macro, + const QDomElement& elem, + const bool isitemsempty, + const bool isactionset, + const QMap<QString, bool> isvariableok); + + // Prints a QMap of Variables to kdDebug(). + void printMvariables(const QMap<QString, KSharedPtr<KoMacro::Variable > > mvariables, const QString s); +*/ + /** + * Sub-methods of testParseXML() and testToXML(). + * Test the correct parsing of a @a QDomElement into a @a Macro + * respectively expected failure of parsing. Then transform it + * back and compare it. + */ + // 1.Test - Correct DomElement. + void testCorrectDomElement(); + // 2.Test - XML-document with bad root element. + void testBadRoot(); + // 3.Test - XML-document with a missing Variable. + void testMissingVariable(); + // 4.Test - One more Variable in XML-Document. + void testMoreVariables(); + // 5.Test - XML-document with wrong macro-xmlversion. + void testWrongVersion(); + // 6.Test - XML-document if it has a wrong structure like + // wrong parathesis or missing end tag. + void testWrongXMLStruct(); + // 7.Test-XML-document with maximum field-size. + void testMaxNum(); + // 8.Test-XML-document with maximum+1 field-size. + void testMaxNum2(); + // 9.Test-XML-document with minimum field-size. + void testMinNum(); + // 10.Test-XML-document with minimum-1 field-size. + void testMinNum2(); + // 11.Test - With a to big number. + void testBigNumber(); + // 12.Test - With two MacroItems. + void testTwoMacroItems(); + + + bool assertActionsEqual(KSharedPtr<KoMacro::Action> action, + KSharedPtr<KoMacro::Action> action2); + + bool assertVariablesEqual(KSharedPtr<KoMacro::Variable> var, + KSharedPtr<KoMacro::Variable> var2); + }; +} + +#endif |