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/kexipart/keximacrodesignview.cpp | |
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/kexipart/keximacrodesignview.cpp')
-rw-r--r-- | kexi/plugins/macros/kexipart/keximacrodesignview.cpp | 497 |
1 files changed, 497 insertions, 0 deletions
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" + |