summaryrefslogtreecommitdiffstats
path: root/kexi/plugins/macros/kexipart
diff options
context:
space:
mode:
Diffstat (limited to 'kexi/plugins/macros/kexipart')
-rw-r--r--kexi/plugins/macros/kexipart/Makefile.am32
-rw-r--r--kexi/plugins/macros/kexipart/keximacrodesignview.cpp497
-rw-r--r--kexi/plugins/macros/kexipart/keximacrodesignview.h129
-rw-r--r--kexi/plugins/macros/kexipart/keximacroerror.cpp130
-rw-r--r--kexi/plugins/macros/kexipart/keximacroerror.h89
-rw-r--r--kexi/plugins/macros/kexipart/keximacroerrorbase.ui213
-rw-r--r--kexi/plugins/macros/kexipart/keximacrohandler.desktop81
-rw-r--r--kexi/plugins/macros/kexipart/keximacropart.cpp172
-rw-r--r--kexi/plugins/macros/kexipart/keximacropart.h95
-rw-r--r--kexi/plugins/macros/kexipart/keximacroproperty.cpp626
-rw-r--r--kexi/plugins/macros/kexipart/keximacroproperty.h186
-rw-r--r--kexi/plugins/macros/kexipart/keximacrotextview.cpp90
-rw-r--r--kexi/plugins/macros/kexipart/keximacrotextview.h77
-rw-r--r--kexi/plugins/macros/kexipart/keximacroview.cpp175
-rw-r--r--kexi/plugins/macros/kexipart/keximacroview.h140
15 files changed, 2732 insertions, 0 deletions
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 <[email protected]>
+
+ 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 <[email protected]>
+
+ 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 ([email protected])
+ * copyright (C) 2006 by Bernd Steindorff ([email protected])
+ * copyright (C) 2006 by Sascha Kupper ([email protected])
+ * copyright (C) 2006 by Sebastian Sauer ([email protected])
+ *
+ * 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 ([email protected])
+ * copyright (C) 2006 by Bernd Steindorff ([email protected])
+ * copyright (C) 2006 by Sascha Kupper ([email protected])
+ * copyright (C) 2006 by Sebastian Sauer ([email protected])
+ *
+ * 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 <[email protected]>
+
+ 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 <[email protected]>
+
+ 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 <[email protected]>
+
+ 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 <[email protected]>
+
+ 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 <[email protected]>
+
+ 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 <[email protected]>
+
+ 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 <[email protected]>
+
+ 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 <[email protected]>
+
+ 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