diff options
Diffstat (limited to 'kexi/plugins/scripting/kexiscripting')
10 files changed, 1105 insertions, 0 deletions
diff --git a/kexi/plugins/scripting/kexiscripting/Makefile.am b/kexi/plugins/scripting/kexiscripting/Makefile.am new file mode 100644 index 00000000..ed3e2264 --- /dev/null +++ b/kexi/plugins/scripting/kexiscripting/Makefile.am @@ -0,0 +1,37 @@ +include $(top_srcdir)/kexi/Makefile.global + +kde_module_LTLIBRARIES = kexihandler_script.la + +kexihandler_script_la_SOURCES = \ + kexiscriptpart.cpp kexiscripteditor.cpp kexiscriptdesignview.cpp + +kexihandler_script_la_LDFLAGS = \ + $(KDE_PLUGIN) -module -no-undefined -Wnounresolved $(all_libraries) $(VER_INFO) + +kexihandler_script_la_LIBADD = \ + $(top_builddir)/lib/kross/main/libkrossmain.la \ + $(top_builddir)/kexi/core/libkexicore.la \ + $(top_builddir)/kexi/widget/libkexiextendedwidgets.la \ + $(top_builddir)/lib/koproperty/libkoproperty.la + +INCLUDES = \ + $(KOFFICE_INCLUDES) \ + -I$(top_srcdir)/lib \ + -I$(top_srcdir)/kexi/core \ + -I$(top_srcdir)/kexi \ + -I$(top_srcdir)/kexi/widget \ + $(all_includes) + +servicesdir=$(kde_servicesdir)/kexi +services_DATA=kexiscripthandler.desktop + +rcdir = $(kde_datadir)/kexi +rc_DATA = kexiscriptpartui.rc kexiscriptpartinstui.rc + +METASOURCES = AUTO + +SUBDIRS = . + +include ../../Makefile.common + +noinst_HEADERS = kexiscriptpart.h kexiscripteditor.h kexiscriptdesignview.h diff --git a/kexi/plugins/scripting/kexiscripting/kexiscriptdesignview.cpp b/kexi/plugins/scripting/kexiscripting/kexiscriptdesignview.cpp new file mode 100644 index 00000000..ff2f93d0 --- /dev/null +++ b/kexi/plugins/scripting/kexiscripting/kexiscriptdesignview.cpp @@ -0,0 +1,337 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Lucijan Busch <lucijan@gmx.at> + Copyright (C) 2004-2005 Jaroslaw Staniek <js@iidea.pl> + Copyright (C) 2005 Cedric Pasteur <cedric.pasteur@free.fr> + Copyright (C) 2005 Sebastian Sauer <mail@dipe.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "kexiscriptdesignview.h" +#include "kexiscripteditor.h" + +#include <kross/main/manager.h> +#include <kross/main/scriptcontainer.h> +#include <kross/main/scriptaction.h> +#include <kross/api/interpreter.h> + +#include <qlayout.h> +#include <qsplitter.h> +#include <qtimer.h> +#include <qdatetime.h> +#include <qdom.h> +#include <qstylesheet.h> +#include <ktextbrowser.h> +#include <kdebug.h> + +#include <kexidialogbase.h> +#include <kexidb/connection.h> + +/// @internal +class KexiScriptDesignViewPrivate +{ + public: + + /** + * The \a Kross::Api::ScriptAction instance which provides + * us access to the scripting framework Kross. + */ + Kross::Api::ScriptAction* scriptaction; + + /// The \a KexiScriptEditor to edit the scripting code. + KexiScriptEditor* editor; + + /// The \a KoProperty::Set used in the propertyeditor. + KoProperty::Set* properties; + + /// Boolean flag to avoid infinite recursion. + bool updatesProperties; + + /// Used to display statusmessages. + KTextBrowser* statusbrowser; +}; + +KexiScriptDesignView::KexiScriptDesignView(KexiMainWindow *mainWin, QWidget *parent, Kross::Api::ScriptAction* scriptaction) + : KexiViewBase(mainWin, parent, "KexiScriptDesignView") + , d( new KexiScriptDesignViewPrivate() ) +{ + d->scriptaction = scriptaction; + d->updatesProperties = false; + + QSplitter* splitter = new QSplitter(this); + splitter->setOrientation(Vertical); + QHBoxLayout* layout = new QHBoxLayout(this); + layout->addWidget(splitter); + + d->editor = new KexiScriptEditor(mainWin, splitter, "ScriptEditor"); + splitter->setFocusProxy(d->editor); + addChildView(d->editor); + setViewWidget(d->editor); + + d->statusbrowser = new KTextBrowser(splitter, "ScriptStatusBrowser"); + d->statusbrowser->setReadOnly(true); + d->statusbrowser->setTextFormat(QTextBrowser::RichText); + //d->browser->setWordWrap(QTextEdit::WidgetWidth); + d->statusbrowser->installEventFilter(this); + splitter->setResizeMode(d->statusbrowser, QSplitter::KeepSize); + + plugSharedAction( "data_execute", this, SLOT(execute()) ); + if(KexiEditor::isAdvancedEditor()) // the configeditor is only in advanced mode avaiable. + plugSharedAction( "script_config_editor", d->editor, SLOT(slotConfigureEditor()) ); + + loadData(); + + d->properties = new KoProperty::Set(this, "KexiScripting"); + connect(d->properties, SIGNAL( propertyChanged(KoProperty::Set&, KoProperty::Property&) ), + this, SLOT( slotPropertyChanged(KoProperty::Set&, KoProperty::Property&) )); + + // To schedule the initialize fixes a crasher in Kate. + QTimer::singleShot(50, this, SLOT( initialize() )); +} + +KexiScriptDesignView::~KexiScriptDesignView() +{ + delete d->properties; + delete d; +} + +Kross::Api::ScriptAction* KexiScriptDesignView::scriptAction() const +{ + return d->scriptaction; +} + +void KexiScriptDesignView::initialize() +{ + updateProperties(); + d->editor->initialize( d->scriptaction ); +} + +void KexiScriptDesignView::updateProperties() +{ + if(d->updatesProperties) + return; + d->updatesProperties = true; + + Kross::Api::Manager* manager = Kross::Api::Manager::scriptManager(); + + QString interpretername = d->scriptaction->getInterpreterName(); + Kross::Api::InterpreterInfo* info = interpretername.isEmpty() ? 0 : manager->getInterpreterInfo(interpretername); + + { + // if interpreter isn't defined or invalid, try to fallback. + QStringList list; + list << "python" << "ruby"; + QStringList::ConstIterator it( list.constBegin() ), end( list.constEnd() ); + while( (! info) && (it != end) ) { + interpretername = (*it); + info = manager->getInterpreterInfo(interpretername); + if(info) + d->scriptaction->setInterpreterName(interpretername); + ++it; + } + } + + if(info) { + d->properties->clear(); + + QStringList interpreters = manager->getInterpreters(); + KoProperty::Property::ListData* proplist = new KoProperty::Property::ListData(interpreters, interpreters); + KoProperty::Property* prop = new KoProperty::Property( + "language", // name + proplist, // ListData + d->scriptaction->getInterpreterName(), // value + i18n("Interpreter"), // caption + i18n("The used scripting interpreter."), // description + KoProperty::List // type + ); + d->properties->addProperty(prop); + + Kross::Api::InterpreterInfo::Option::Map options = info->getOptions(); + Kross::Api::InterpreterInfo::Option::Map::ConstIterator it, end( options.constEnd() ); + for( it = options.constBegin(); it != end; ++it) { + Kross::Api::InterpreterInfo::Option* option = it.data(); + KoProperty::Property* prop = new KoProperty::Property( + it.key().latin1(), // name + d->scriptaction->getOption(it.key(), option->value), // value + option->name, // caption + option->comment, // description + KoProperty::Auto // type + ); + d->properties->addProperty(prop); + } + } + + //propertySetSwitched(); + propertySetReloaded(true); + d->updatesProperties = false; +} + +KoProperty::Set* KexiScriptDesignView::propertySet() +{ + return d->properties; +} + +void KexiScriptDesignView::slotPropertyChanged(KoProperty::Set& /*set*/, KoProperty::Property& property) +{ + if(property.isNull()) + return; + + if(property.name() == "language") { + QString language = property.value().toString(); + kdDebug() << QString("KexiScriptDesignView::slotPropertyChanged() language=%1").arg(language) << endl; + d->scriptaction->setInterpreterName( language ); + // We assume Kross and the HighlightingInterface are using same + // names for the support languages... + d->editor->setHighlightMode( language ); + updateProperties(); + } + else { + bool ok = d->scriptaction->setOption( property.name(), property.value() ); + if(! ok) { + kdWarning() << QString("KexiScriptDesignView::slotPropertyChanged() unknown property '%1'.").arg(property.name()) << endl; + return; + } + } + + setDirty(true); +} + +void KexiScriptDesignView::execute() +{ + d->statusbrowser->clear(); + QTime time; + time.start(); + d->statusbrowser->append( i18n("Execution of the script \"%1\" started.").arg(d->scriptaction->name()) ); + + d->scriptaction->activate(); + if( d->scriptaction->hadException() ) { + QString errormessage = d->scriptaction->getException()->getError(); + d->statusbrowser->append(QString("<b>%2</b><br>").arg(QStyleSheet::escape(errormessage)) ); + + QString tracedetails = d->scriptaction->getException()->getTrace(); + d->statusbrowser->append( QStyleSheet::escape(tracedetails) ); + + long lineno = d->scriptaction->getException()->getLineNo(); + if(lineno >= 0) + d->editor->setLineNo(lineno); + } + else { + d->statusbrowser->append( i18n("Successfully executed. Time elapsed: %1ms").arg(time.elapsed()) ); + } +} + +bool KexiScriptDesignView::loadData() +{ + QString data; + if(! loadDataBlock(data)) { + kexipluginsdbg << "KexiScriptDesignView::loadData(): no DataBlock" << endl; + return false; + } + + QString errMsg; + int errLine; + int errCol; + + QDomDocument domdoc; + bool parsed = domdoc.setContent(data, false, &errMsg, &errLine, &errCol); + + if(! parsed) { + kexipluginsdbg << "KexiScriptDesignView::loadData() XML parsing error line: " << errLine << " col: " << errCol << " message: " << errMsg << endl; + return false; + } + + QDomElement scriptelem = domdoc.namedItem("script").toElement(); + if(scriptelem.isNull()) { + kexipluginsdbg << "KexiScriptDesignView::loadData(): script domelement is null" << endl; + return false; + } + + QString interpretername = scriptelem.attribute("language"); + Kross::Api::Manager* manager = Kross::Api::Manager::scriptManager(); + Kross::Api::InterpreterInfo* info = interpretername.isEmpty() ? 0 : manager->getInterpreterInfo(interpretername); + if(info) { + d->scriptaction->setInterpreterName(interpretername); + + Kross::Api::InterpreterInfo::Option::Map options = info->getOptions(); + Kross::Api::InterpreterInfo::Option::Map::ConstIterator it, end = options.constEnd(); + for( it = options.constBegin(); it != end; ++it) { + QString value = scriptelem.attribute( it.data()->name ); + if(! value.isNull()) { + QVariant v(value); + if( v.cast( it.data()->value.type() ) ) // preserve the QVariant's type + d->scriptaction->setOption(it.data()->name, v); + } + } + } + + d->scriptaction->setCode( scriptelem.text() ); + + return true; +} + +KexiDB::SchemaData* KexiScriptDesignView::storeNewData(const KexiDB::SchemaData& sdata, bool &cancel) +{ + KexiDB::SchemaData *s = KexiViewBase::storeNewData(sdata, cancel); + kexipluginsdbg << "KexiScriptDesignView::storeNewData(): new id:" << s->id() << endl; + + if(!s || cancel) { + delete s; + return 0; + } + + if(! storeData()) { + kdWarning() << "KexiScriptDesignView::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( s->id() ); + delete s; + return 0; + } + + return s; +} + +tristate KexiScriptDesignView::storeData(bool /*dontAsk*/) +{ + kexipluginsdbg << "KexiScriptDesignView::storeData(): " << parentDialog()->partItem()->name() << " [" << parentDialog()->id() << "]" << endl; + + QDomDocument domdoc("script"); + QDomElement scriptelem = domdoc.createElement("script"); + domdoc.appendChild(scriptelem); + + QString language = d->scriptaction->getInterpreterName(); + scriptelem.setAttribute("language", language); + + Kross::Api::InterpreterInfo* info = Kross::Api::Manager::scriptManager()->getInterpreterInfo(language); + if(info) { + Kross::Api::InterpreterInfo::Option::Map defoptions = info->getOptions(); + QMap<QString, QVariant>& options = d->scriptaction->getOptions(); + QMap<QString, QVariant>::ConstIterator it, end( options.constEnd() ); + for( it = options.constBegin(); it != end; ++it) { + if( defoptions.contains(it.key()) ) { // only remember options which the InterpreterInfo knows about... + scriptelem.setAttribute(it.key(), it.data().toString()); + } + } + } + + QDomText scriptcode = domdoc.createTextNode(d->scriptaction->getCode()); + scriptelem.appendChild(scriptcode); + + return storeDataBlock( domdoc.toString() ); +} + +#include "kexiscriptdesignview.moc" + diff --git a/kexi/plugins/scripting/kexiscripting/kexiscriptdesignview.h b/kexi/plugins/scripting/kexiscripting/kexiscriptdesignview.h new file mode 100644 index 00000000..cee1ed76 --- /dev/null +++ b/kexi/plugins/scripting/kexiscripting/kexiscriptdesignview.h @@ -0,0 +1,124 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Lucijan Busch <lucijan@gmx.at> + Copyright (C) 2004-2005 Jaroslaw Staniek <js@iidea.pl> + Copyright (C) 2005 Cedric Pasteur <cedric.pasteur@free.fr> + Copyright (C) 2005 Sebastian Sauer <mail@dipe.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KEXISCRIPTDESIGNVIEW_H +#define KEXISCRIPTDESIGNVIEW_H + +#include <kexiviewbase.h> + +#include <koproperty/set.h> +#include <koproperty/property.h> + +// Forward declarations. +class KexiScriptContainer; +class KexiScriptEditor; +class KexiScriptDesignViewPrivate; + +namespace Kross { namespace Api { + class ScriptAction; +}} + +/** + * The KexiScriptDesignView class provides the \a KexiViewBase to + * manage script modules in the design-view. The design-view + * is used to be able to view and edit the scripting code via + * a \a KexiScriptEditor instance. + */ +class KexiScriptDesignView : public KexiViewBase +{ + Q_OBJECT + + public: + + /** + * Constructor. + */ + KexiScriptDesignView(KexiMainWindow *mainWin, QWidget *parent, Kross::Api::ScriptAction* scriptaction); + + /** + * Destructor. + */ + virtual ~KexiScriptDesignView(); + + /** + * \return the \a Kross::Api::ScriptAction this \a KexiScriptDesignView + * is responsible for. + */ + Kross::Api::ScriptAction* scriptAction() const; + + /** + * \return a property set for this view. + */ + virtual KoProperty::Set* propertySet(); + + /** + * 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); + + private slots: + + /** + * Deferred initialization. + */ + void initialize(); + + /** + * Handle changes in the property editor. + */ + void slotPropertyChanged(KoProperty::Set& set, KoProperty::Property& property); + + /** + * Update the \a KoProperty::Property::Dict propertymap of the + * interpreter-dependent options. + */ + void updateProperties(); + + /** + * Execute the scripting code. + */ + void execute(); + + private: + KexiScriptDesignViewPrivate* d; + + /** + * Load the data from XML source and fill the internally + * used \a Kross::Api::ScriptContainer instance. + */ + bool loadData(); +}; + +#endif diff --git a/kexi/plugins/scripting/kexiscripting/kexiscripteditor.cpp b/kexi/plugins/scripting/kexiscripting/kexiscripteditor.cpp new file mode 100644 index 00000000..a638af36 --- /dev/null +++ b/kexi/plugins/scripting/kexiscripting/kexiscripteditor.cpp @@ -0,0 +1,104 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Lucijan Busch <lucijan@gmx.at> + Copyright (C) 2004-2005 Jaroslaw Staniek <js@iidea.pl> + Copyright (C) 2005 Cedric Pasteur <cedric.pasteur@free.fr> + Copyright (C) 2005 Sebastian Sauer <mail@dipe.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "kexiscripteditor.h" + +#include <kross/main/scriptaction.h> + +#include <kdebug.h> +//#include <kparts/factory.h> +//#include <klibloader.h> +//#include <kmdimainfrm.h> +//#include <kmainwindow.h> +#include <kpopupmenu.h> + +#include <kexidialogbase.h> + +/// \internal d-pointer class +class KexiScriptEditor::Private +{ + public: + Kross::Api::ScriptAction* scriptaction; + Private() : scriptaction(0) {} +}; + +KexiScriptEditor::KexiScriptEditor(KexiMainWindow *mainWin, QWidget *parent, const char *name) + : KexiEditor(mainWin, parent, name) + , d( new Private() ) +{ +} + +KexiScriptEditor::~KexiScriptEditor() +{ + delete d; +} + +bool KexiScriptEditor::isInitialized() const +{ + return d->scriptaction != 0; +} + +void KexiScriptEditor::initialize(Kross::Api::ScriptAction* scriptaction) +{ + d->scriptaction = scriptaction; + Q_ASSERT(d->scriptaction); + + disconnect(this, SIGNAL(textChanged()), this, SLOT(slotTextChanged())); + + QString code = d->scriptaction->getCode(); + if(code.isNull()) { + // If there is no code we just add some information. +///@todo remove after release + code = "# " + QStringList::split("\n", i18n( + "This note will appear for a user in the script's source code " + "as a comment. Keep every row not longer than 60 characters and use '\n.'", + + "This is Technology Preview (BETA) version of scripting\n" + "support in Kexi. The scripting API may change in details\n" + "in the next Kexi version.\n" + "For more information and documentation see\n%1" + ).arg("http://www.kexi-project.org/scripting/"), true).join("\n# ") + "\n"; + } + KexiEditor::setText(code); + // We assume Kross and the HighlightingInterface are using same + // names for the support languages... + setHighlightMode(d->scriptaction->getInterpreterName()); + + clearUndoRedo(); + KexiEditor::setDirty(false); + connect(this, SIGNAL(textChanged()), this, SLOT(slotTextChanged())); +} + +void KexiScriptEditor::slotTextChanged() +{ + KexiScriptEditor::setDirty(true); + if(d->scriptaction) + d->scriptaction->setCode( KexiEditor::text() ); +} + +void KexiScriptEditor::setLineNo(long lineno) +{ + setCursorPosition(lineno, 0); +} + +#include "kexiscripteditor.moc" + diff --git a/kexi/plugins/scripting/kexiscripting/kexiscripteditor.h b/kexi/plugins/scripting/kexiscripting/kexiscripteditor.h new file mode 100644 index 00000000..1ef02ff9 --- /dev/null +++ b/kexi/plugins/scripting/kexiscripting/kexiscripteditor.h @@ -0,0 +1,77 @@ +/* This file is part of the KDE project + Copyright (C) 2003 Lucijan Busch <lucijan@gmx.at> + Copyright (C) 2004-2005 Jaroslaw Staniek <js@iidea.pl> + Copyright (C) 2005 Cedric Pasteur <cedric.pasteur@free.fr> + Copyright (C) 2005 Sebastian Sauer <mail@dipe.org> + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this program; see the file COPYING. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KEXISCRIPTEDITOR_H +#define KEXISCRIPTEDITOR_H + +#include <kexieditor.h> + +namespace Kross { namespace Api { + class ScriptAction; +}} + +/** + * The KexiEditor class embeds text editor + * for editing scripting code. + */ +class KexiScriptEditor : public KexiEditor +{ + Q_OBJECT + + public: + + /** + * Constructor. + */ + KexiScriptEditor(KexiMainWindow *mainWin, QWidget *parent, const char *name = 0); + + /** + * Destructor. + */ + virtual ~KexiScriptEditor(); + + /** + * \returns true if this editor is already initialized (\a initialize was + * called) else false is returned. + */ + bool isInitialized() const; + + /** + * Initializes the editor. Call this if you like to start + * with a clear editor instance. Thinks like the language + * highlighter will be reset, undo/redo are cleared and + * setDirty(false) is set. + */ + void initialize(Kross::Api::ScriptAction* scriptaction); + + public slots: + void slotTextChanged(); + void setLineNo(long); + + private: + /// \internal d-pointer class. + class Private; + /// \internal d-pointer instance. + Private* const d; +}; + +#endif diff --git a/kexi/plugins/scripting/kexiscripting/kexiscripthandler.desktop b/kexi/plugins/scripting/kexiscripting/kexiscripthandler.desktop new file mode 100644 index 00000000..66e5f9fb --- /dev/null +++ b/kexi/plugins/scripting/kexiscripting/kexiscripthandler.desktop @@ -0,0 +1,105 @@ +[Desktop Entry] +Type=Service +ServiceTypes=Kexi/Handler + +GenericName=Scripts +GenericName[bg]=Скриптове +GenericName[br]=Urzhiaouegoù +GenericName[ca]=Seqüències +GenericName[cs]=Skripty +GenericName[cy]=Sgriptiau +GenericName[da]=Scripter +GenericName[de]=Skripte +GenericName[el]=Σενάρια +GenericName[eo]=Skriptoj +GenericName[es]=Guiones +GenericName[et]=Skriptid +GenericName[eu]=Script-ak +GenericName[fa]=دستنوشتهها +GenericName[fi]=Skriptit +GenericName[fy]=Skripts +GenericName[ga]=Scripteanna +GenericName[gl]=Programas +GenericName[he]=תסריטים +GenericName[hr]=Skripte +GenericName[hu]=Szkriptek +GenericName[is]=Skriftur +GenericName[it]=Script +GenericName[ja]=スクリプト +GenericName[km]=ស្គ្រីប +GenericName[lt]=Scenarijai +GenericName[lv]=Skripti +GenericName[ms]=Skrip +GenericName[nb]=Skript +GenericName[nds]=Skripten +GenericName[ne]=स्क्रिप्टहरू +GenericName[nn]=Skript +GenericName[pl]=Skrypty +GenericName[pt]=Programas +GenericName[ru]=Сценарии +GenericName[se]=Skriptat +GenericName[sk]=Skripty +GenericName[sl]=Skripti +GenericName[sr]=Скрипте +GenericName[sr@Latn]=Skripte +GenericName[sv]=Skript +GenericName[uk]=Скрипти +GenericName[uz]=Skriptlar +GenericName[uz@cyrillic]=Скриптлар +GenericName[zh_CN]=脚本 +GenericName[zh_TW]=命令稿 +Name=Scripts +Name[bg]=Скриптове +Name[br]=Urzhiaouegoù +Name[ca]=Seqüències +Name[cs]=Skripty +Name[cy]=Sgriptiau +Name[da]=Scripter +Name[de]=Skripte +Name[el]=Σενάρια +Name[eo]=Skriptoj +Name[es]=Guiones +Name[et]=Skriptid +Name[eu]=Script-ak +Name[fa]=دستنوشتهها +Name[fi]=Skriptit +Name[fy]=Skripts +Name[ga]=Scripteanna +Name[gl]=Programas +Name[he]=תסריטים +Name[hr]=Skripte +Name[hu]=Szkriptek +Name[is]=Skriftur +Name[it]=Script +Name[ja]=スクリプト +Name[km]=ស្គ្រីប +Name[lt]=Scenarijai +Name[lv]=Skripti +Name[ms]=Skrip +Name[nb]=Skript +Name[nds]=Skripten +Name[ne]=स्क्रिप्टहरू +Name[nn]=Skript +Name[pl]=Skrypty +Name[pt]=Programas +Name[ru]=Сценарии +Name[se]=Skriptat +Name[sk]=Skripty +Name[sl]=Skripti +Name[sr]=Скрипте +Name[sr@Latn]=Skripte +Name[sv]=Skript +Name[uk]=Скрипти +Name[uz]=Skriptlar +Name[uz@cyrillic]=Скриптлар +Name[zh_CN]=脚本 +Name[zh_TW]=命令稿 +X-KDE-Library=kexihandler_script +X-KDE-ParentApp=kexi +X-Kexi-PartVersion=2 +X-Kexi-TypeName=script +X-Kexi-TypeMime=kexi/script +X-Kexi-ItemIcon=script +X-Kexi-SupportsExecution=true +X-Kexi-SupportsDataExport=false +X-Kexi-SupportsPrinting=false diff --git a/kexi/plugins/scripting/kexiscripting/kexiscriptpart.cpp b/kexi/plugins/scripting/kexiscripting/kexiscriptpart.cpp new file mode 100644 index 00000000..d650e958 --- /dev/null +++ b/kexi/plugins/scripting/kexiscripting/kexiscriptpart.cpp @@ -0,0 +1,201 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Lucijan Busch <lucijan@kde.org> + Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr> + Copyright (C) 2005 Sebastian Sauer <mail@dipe.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#include "kexiscriptpart.h" +#include "kexiscriptdesignview.h" + +#include "kexiviewbase.h" +#include "keximainwindow.h" +#include "kexiproject.h" + +#include <kross/main/manager.h> +#include <kross/main/scriptaction.h> +#include <kross/main/scriptguiclient.h> + +#include <kgenericfactory.h> +#include <kexipartitem.h> +#include <kxmlguiclient.h> +#include <kexidialogbase.h> +#include <kconfig.h> +#include <kdebug.h> + +/// \internal +class KexiScriptPart::Private +{ + public: + Kross::Api::ScriptGUIClient* scriptguiclient; +}; + +KexiScriptPart::KexiScriptPart(QObject *parent, const char *name, const QStringList &l) + : KexiPart::Part(parent, name, l) + , d( new Private() ) +{ + d->scriptguiclient = 0; + + // REGISTERED ID: + m_registeredPartID = (int)KexiPart::ScriptObjectType; + + 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.", + "script"); + m_names["instanceCaption"] = i18n("Script"); + m_supportedViewModes = Kexi::DesignViewMode; +} + +KexiScriptPart::~KexiScriptPart() +{ + delete d->scriptguiclient; + delete d; +} + +bool KexiScriptPart::execute(KexiPart::Item* item, QObject* sender) +{ + Q_UNUSED(sender); + + if(! item) { + kdWarning() << "KexiScriptPart::execute: Invalid item." << endl; + return false; + } + + KexiDialogBase* dialog = new KexiDialogBase(m_mainWin); + dialog->setId( item->identifier() ); + KexiScriptDesignView* view = dynamic_cast<KexiScriptDesignView*>( createView(dialog, dialog, *item, Kexi::DesignViewMode) ); + if(! view) { + kdWarning() << "KexiScriptPart::execute: Failed to create a view." << endl; + return false; + } + + Kross::Api::ScriptAction* scriptaction = view->scriptAction(); + if(scriptaction) { + + const QString dontAskAgainName = "askExecuteScript"; + KConfig* config = KGlobal::config(); + QString dontask = config->readEntry(dontAskAgainName).lower(); + + bool exec = (dontask == "yes"); + if( !exec && dontask != "no" ) { + exec = KMessageBox::warningContinueCancel(0, + i18n("Do you want to execute the script \"%1\"?\n\nScripts obtained from unknown sources can contain dangerous code.").arg(scriptaction->text()), + i18n("Execute Script?"), KGuiItem(i18n("Execute"), "exec"), + dontAskAgainName, KMessageBox::Notify | KMessageBox::Dangerous + ) == KMessageBox::Continue; + } + + if(exec) { + //QTimer::singleShot(10, scriptaction, SLOT(activate())); + d->scriptguiclient->executeScriptAction( scriptaction ); + } + } + + view->deleteLater(); // not needed any longer. + return true; +} + +void KexiScriptPart::initPartActions() +{ + if(m_mainWin) { + // At this stage the KexiPart::Part::m_mainWin should be defined, so + // that we are able to use it's KXMLGUIClient. + + // Initialize the ScriptGUIClient. + d->scriptguiclient = new Kross::Api::ScriptGUIClient( m_mainWin ); + + // Publish the KexiMainWindow singelton instance. At least the KexiApp + // scripting-plugin depends on this instance and loading the plugin will + // fail if it's not avaiable. + if(! Kross::Api::Manager::scriptManager()->hasChild("KexiMainWindow")) { + Kross::Api::Manager::scriptManager()->addQObject(m_mainWin, "KexiMainWindow"); + + // Add the KAction's provided by the ScriptGUIClient to the + // KexiMainWindow. + //FIXME: fix+use createSharedPartAction() whyever it doesn't work as expected right now... + QPopupMenu* popup = m_mainWin->findPopupMenu("tools"); + if(popup) { + KAction* execscriptaction = d->scriptguiclient->action("executescriptfile"); + if(execscriptaction) + execscriptaction->plug( popup ); + KAction* configscriptaction = d->scriptguiclient->action("configurescripts"); + if(configscriptaction) + configscriptaction->plug( popup ); + KAction* scriptmenuaction = d->scriptguiclient->action("installedscripts"); + if(scriptmenuaction) + scriptmenuaction->plug( popup ); + /* + KAction* execscriptmenuaction = d->scriptguiclient->action("executedscripts"); + if(execscriptmenuaction) + execscriptmenuaction->plug( popup ); + KAction* loadedscriptmenuaction = d->scriptguiclient->action("loadedscripts"); + if(loadedscriptmenuaction) + loadedscriptmenuaction->plug( popup ); + */ + } + } + } +} + +void KexiScriptPart::initInstanceActions() +{ + //createSharedAction(Kexi::DesignViewMode, i18n("Execute Script"), "player_play", 0, "data_execute"); + createSharedAction(Kexi::DesignViewMode, i18n("Configure Editor..."), "configure", 0, "script_config_editor"); +} + +KexiViewBase* KexiScriptPart::createView(QWidget *parent, KexiDialogBase* dialog, KexiPart::Item& item, int viewMode, QMap<QString,QString>*) +{ + QString partname = item.name(); + if( ! partname.isNull() ) { + KexiMainWindow *win = dialog->mainWin(); + if(!win || !win->project() || !win->project()->dbConnection()) + return 0; + + Kross::Api::ScriptActionCollection* collection = d->scriptguiclient->getActionCollection("projectscripts"); + if(! collection) { + collection = new Kross::Api::ScriptActionCollection( i18n("Scripts"), d->scriptguiclient->actionCollection(), "projectscripts" ); + d->scriptguiclient->addActionCollection("projectscripts", collection); + } + + const char* name = partname.latin1(); + Kross::Api::ScriptAction::Ptr scriptaction = collection->action(name); + if(! scriptaction) { + scriptaction = new Kross::Api::ScriptAction(partname); + collection->attach(scriptaction); //TODO remove again on unload! + } + + if(viewMode == Kexi::DesignViewMode) { + return new KexiScriptDesignView(win, parent, scriptaction); + } + } + return 0; +} + +QString KexiScriptPart::i18nMessage(const QCString& englishMessage) const +{ + if (englishMessage=="Design of object \"%1\" has been modified.") + return i18n("Design of script \"%1\" has been modified."); + if (englishMessage=="Object \"%1\" already exists.") + return i18n("Script \"%1\" already exists."); + return englishMessage; +} + +K_EXPORT_COMPONENT_FACTORY( kexihandler_script, KGenericFactory<KexiScriptPart>("kexihandler_script") ) + +#include "kexiscriptpart.moc" diff --git a/kexi/plugins/scripting/kexiscripting/kexiscriptpart.h b/kexi/plugins/scripting/kexiscripting/kexiscriptpart.h new file mode 100644 index 00000000..ddba0d72 --- /dev/null +++ b/kexi/plugins/scripting/kexiscripting/kexiscriptpart.h @@ -0,0 +1,100 @@ +/* This file is part of the KDE project + Copyright (C) 2004 Lucijan Busch <lucijan@kde.org> + Copyright (C) 2004 Cedric Pasteur <cedric.pasteur@free.fr> + Copyright (C) 2005 Sebastian Sauer <mail@dipe.org> + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to + the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301, USA. +*/ + +#ifndef KEXISCRIPTPART_H +#define KEXISCRIPTPART_H + +#include <qdom.h> +#include <qcstring.h> + +#include <kexi.h> +#include <kexipart.h> +#include <kexidialogbase.h> + +/** + * Kexi Scripting Plugin. + */ +class KexiScriptPart : 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. + */ + KexiScriptPart(QObject *parent, const char *name, const QStringList& args); + + /** + * Destructor. + */ + virtual ~KexiScriptPart(); + + /** + * Implementation of the \a KexiPart::Part::execute method used to + * execute the passed \p item instance. + */ + 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/scripting/kexiscripting/kexiscriptpartinstui.rc b/kexi/plugins/scripting/kexiscripting/kexiscriptpartinstui.rc new file mode 100644 index 00000000..16124c34 --- /dev/null +++ b/kexi/plugins/scripting/kexiscripting/kexiscriptpartinstui.rc @@ -0,0 +1,10 @@ +<!DOCTYPE kpartgui> +<kpartgui name="kexiscriptpartinst" version="14"> + + <MenuBar> + <Menu name="settings" noMerge="1"> + <Action name="script_config_editor"/> + </Menu> + </MenuBar> + +</kpartgui> diff --git a/kexi/plugins/scripting/kexiscripting/kexiscriptpartui.rc b/kexi/plugins/scripting/kexiscripting/kexiscriptpartui.rc new file mode 100644 index 00000000..171d643f --- /dev/null +++ b/kexi/plugins/scripting/kexiscripting/kexiscriptpartui.rc @@ -0,0 +1,10 @@ +<!DOCTYPE kpartgui> +<kpartgui name="kexiscriptpart" version="10"> + + <MenuBar> + <Menu name="settings" noMerge="1"> + <Action name="script_config_editor"/> + </Menu> + </MenuBar> + +</kpartgui> |