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 /kspread/plugins/scripting | |
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 'kspread/plugins/scripting')
22 files changed, 2664 insertions, 0 deletions
diff --git a/kspread/plugins/scripting/Makefile.am b/kspread/plugins/scripting/Makefile.am new file mode 100644 index 00000000..61f9561a --- /dev/null +++ b/kspread/plugins/scripting/Makefile.am @@ -0,0 +1,23 @@ +#SUBDIRS = kspreadcore samples +SUBDIRS = kspreadcore scripts + +INCLUDES = -I$(top_builddir)/lib/kross/main \ + -I$(top_srcdir)/kspread \ + $(KROSS_INCLUDES) \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + +kspreadscripting_la_SOURCES = scripting.cc + +kde_module_LTLIBRARIES = kspreadscripting.la +noinst_HEADERS = scripting.h + +kspreadscripting_la_METASOURCES = AUTO + +kspreadscripting_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +kspreadscripting_la_LIBADD = $(top_builddir)/kspread/libkspreadcommon.la $(top_builddir)/lib/kross/main/libkrossmain.la + +kde_services_DATA = kspreadscripting.desktop + +kspreadrcdir = $(kde_datadir)/kspread/kpartplugins +kspreadrc_DATA = scripting.rc diff --git a/kspread/plugins/scripting/kspreadcore/CMakeLists.txt b/kspread/plugins/scripting/kspreadcore/CMakeLists.txt new file mode 100644 index 00000000..50cd0a73 --- /dev/null +++ b/kspread/plugins/scripting/kspreadcore/CMakeLists.txt @@ -0,0 +1,56 @@ + + +include_directories( ${CMAKE_SOURCE_DIR}/core ${CMAKE_SOURCE_DIR}/kspread ${KDE4_INCLUDES} ) + + +########### next target ############### + +set(krosskspreadcore_PART_SRCS + kspreadcoremodule.cpp + krs_doc.cpp + krs_sheet.cpp + krs_cell.cpp ) + +kde4_automoc(${krosskspreadcore_PART_SRCS}) + +kde4_add_plugin(krosskspreadcore ${krosskspreadcore_PART_SRCS}) + +kde4_install_libtool_file( ${PLUGIN_INSTALL_DIR} krosskspreadcore ) + +target_link_libraries(krosskspreadcore ${KDE4_KDECORE_LIBS} krossapi krossmain kspreadcommon ) + +install(TARGETS krosskspreadcore DESTINATION ${PLUGIN_INSTALL_DIR}) + + +########### install files ############### + + + + + + +#original Makefile.am contents follow: + +#INCLUDES = -I$(top_srcdir)/core \ +# -I$(top_srcdir)/kspread $(KOFFICECORE_INCLUDES) $(KSTORE_INCLUDES) \ +# $(KOFFICEUI_INCLUDES) $(KROSS_INCLUDES) \ +# $(all_includes) +# +#kde_module_LTLIBRARIES = krosskspreadcore.la +# +#krosskspreadcore_la_SOURCES = kspreadcoremodule.cpp krs_doc.cpp krs_sheet.cpp krs_cell.cpp krs_color.cpp +# +#krosskspreadcore_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module +#krosskspreadcore_la_LIBADD = \ +# $(LIB_QT) \ +# $(LIB_KDECORE) \ +# $(top_builddir)/lib/kross/api/libkrossapi.la \ +# $(top_builddir)/lib/kross/main/libkrossmain.la \ +# $(top_builddir)/kspread/libkspreadcommon.la +# +#METASOURCES = AUTO +#SUBDIRS = . +# +#KDE_CXXFLAGS = $(USE_EXCEPTIONS) +# +#noinst_HEADERS = krs_doc.h krs_sheet.h krs_cell.h krs_color.h diff --git a/kspread/plugins/scripting/kspreadcore/Makefile.am b/kspread/plugins/scripting/kspreadcore/Makefile.am new file mode 100644 index 00000000..1538610d --- /dev/null +++ b/kspread/plugins/scripting/kspreadcore/Makefile.am @@ -0,0 +1,23 @@ +INCLUDES = -I$(top_srcdir)/core \ + -I$(top_srcdir)/kspread $(KOFFICECORE_INCLUDES) $(KSTORE_INCLUDES) \ + $(KOFFICEUI_INCLUDES) $(KROSS_INCLUDES) \ + $(all_includes) + +kde_module_LTLIBRARIES = krosskspreadcore.la + +krosskspreadcore_la_SOURCES = kspreadcoremodule.cpp krs_doc.cpp krs_sheet.cpp krs_cell.cpp + +krosskspreadcore_la_LDFLAGS = $(all_libraries) $(KDE_PLUGIN) -module +krosskspreadcore_la_LIBADD = \ + $(LIB_QT) \ + $(LIB_KDECORE) \ + $(top_builddir)/lib/kross/api/libkrossapi.la \ + $(top_builddir)/lib/kross/main/libkrossmain.la \ + $(top_builddir)/kspread/libkspreadcommon.la + +METASOURCES = AUTO +SUBDIRS = . + +KDE_CXXFLAGS = $(USE_EXCEPTIONS) + +noinst_HEADERS = krs_doc.h krs_sheet.h krs_cell.h diff --git a/kspread/plugins/scripting/kspreadcore/krs_cell.cpp b/kspread/plugins/scripting/kspreadcore/krs_cell.cpp new file mode 100644 index 00000000..cabf0c50 --- /dev/null +++ b/kspread/plugins/scripting/kspreadcore/krs_cell.cpp @@ -0,0 +1,211 @@ +/* + * Copyright (c) 2005 Cyrille Berger <[email protected]> + * Copyright (c) 2006 Isaac Clerencia <[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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "krs_cell.h" + +#include "manipulator.h" +#include "manipulator_data.h" + +namespace Kross { namespace KSpreadCore { + +Cell::Cell(KSpread::Cell* cell, KSpread::Sheet* sheet, uint col, uint row) + : Kross::Api::Class<Cell>("KSpreadCell"), m_cell(cell), m_sheet(sheet), m_col(col), m_row(row) +{ + this->addFunction0< Kross::Api::Variant >("value", this, &Cell::value); + this->addFunction1< Kross::Api::Variant, Kross::Api::Variant >("setValue", this, &Cell::setValue); + + this->addFunction0< Kross::Api::Variant >("column", this, &Cell::column); + this->addFunction0< Kross::Api::Variant >("row", this, &Cell::row); + + this->addFunction0< Cell >("previousCell", this, &Cell::previousCell); + this->addFunction0< Cell >("nextCell", this, &Cell::nextCell); + this->addFunction1< void, Cell >("setPreviousCell", this, &Cell::setPreviousCell); + this->addFunction1< void, Cell >("setNextCell", this, &Cell::setNextCell); + + this->addFunction0< Kross::Api::Variant >("name", this, &Cell::name); + this->addFunction0< Kross::Api::Variant >("fullName", this, &Cell::fullName); + + this->addFunction0< Kross::Api::Variant >("comment", this, &Cell::comment); + this->addFunction1< void, Kross::Api::Variant >("setComment", this, &Cell::setComment); + + this->addFunction0< Kross::Api::Variant >("getFormatString", this, &Cell::getFormatString); + this->addFunction1< void, Kross::Api::Variant >("setFormatString", this, &Cell::setFormatString); + + this->addFunction0< Kross::Api::Variant >("text", this, &Cell::text); + this->addFunction1< void, Kross::Api::Variant >("setText", this, &Cell::setText); + + this->addFunction0< Kross::Api::Variant >("textColor", this, &Cell::textColor); + this->addFunction1< void, Kross::Api::Variant >("setTextColor", this, &Cell::setTextColor); + this->addFunction0< Kross::Api::Variant >("backgroundColor", this, &Cell::backgroundColor); + this->addFunction1< void, Kross::Api::Variant >("setBackgroundColor", this, &Cell::setBackgroundColor); +} + +Cell::~Cell() { +} + +const QString Cell::getClassName() const { + return "Kross::KSpreadCore::KSpreadCell"; +} + +QVariant Cell::toVariant(const KSpread::Value& value) const +{ + //Should we use following value-format enums here? + //fmt_None, fmt_Boolean, fmt_Number, fmt_Percent, fmt_Money, fmt_DateTime, fmt_Date, fmt_Time, fmt_String + + switch(value.type()) { + case KSpread::Value::Empty: + return QVariant(); + case KSpread::Value::Boolean: + return QVariant( value.asBoolean() ); + case KSpread::Value::Integer: + return static_cast<Q_LLONG>(value.asInteger()); + case KSpread::Value::Float: + return (float)value.asFloat(); + case KSpread::Value::String: + return value.asString(); + case KSpread::Value::Array: { + QValueList<QVariant> colarray; + for(uint j = 0; j < value.rows(); j++) { + QValueList<QVariant> rowarray; + for( uint i = 0; i < value.columns(); i++) { + KSpread::Value v = value.element(i,j); + rowarray.append( toVariant(v) ); + } + colarray.append(rowarray); + } + return colarray; + } break; + case KSpread::Value::CellRange: + //FIXME: not yet used + return QVariant(); + case KSpread::Value::Error: + return QVariant(); + } + return QVariant(); +} + +QVariant Cell::value() const { + return toVariant( m_cell->value() ); +} + +bool Cell::setValue(const QVariant& value) { + KSpread::Value v = m_cell->value(); + switch(value.type()) { + case QVariant::Bool: v.setValue( value.toBool() ); break; + case QVariant::ULongLong: v.setValue( (long)value.toLongLong() ); break; + case QVariant::Int: v.setValue( value.toInt() ); break; + case QVariant::Double: v.setValue( value.toDouble() ); break; + case QVariant::String: v.setValue( value.toString() ); break; + case QVariant::Date: v.setValue( value.toDate() ); break; + case QVariant::Time: v.setValue( value.toTime() ); break; + case QVariant::DateTime: v.setValue( value.toDateTime() ); break; + default: return false; + } + return true; +} + +int Cell::column() const { + return m_cell->column(); +} + +int Cell::row() const { + return m_cell->row(); +} + +Cell* Cell::previousCell() const { + KSpread::Cell* c = m_cell->previousCell(); + return c ? new Cell(c,c->sheet(),c->column(),c->row()) : 0; +} + +Cell* Cell::nextCell() const { + KSpread::Cell* c = m_cell->nextCell(); + return c ? new Cell(c,c->sheet(),c->column(),c->row()) : 0; +} + +void Cell::setPreviousCell(Cell* c) { + return m_cell->setPreviousCell(c->m_cell); +} + +void Cell::setNextCell(Cell* c) { + return m_cell->setNextCell(c->m_cell); +} + +const QString Cell::name() const { + return m_cell->name(); +} + +const QString Cell::fullName() const { + return m_cell->fullName(); +} + +const QString Cell::comment() const { + return m_cell->format()->comment(m_col, m_row); +} + +void Cell::setComment(const QString& c) { + return m_cell->format()->setComment(c); +} + +const QString Cell::getFormatString() const { + return m_cell->format()->getFormatString(m_col, m_row); +} + +void Cell::setFormatString(const QString& format) { + m_cell->format()->setFormatString(format); +} + +const QString Cell::text() const { + return m_cell->text(); +} + +bool Cell::setText(const QString& text) { + KSpread::ProtectedCheck prot; + prot.setSheet (m_sheet); + prot.add (QPoint (m_col, m_row)); + if (prot.check()) + return false; + + KSpread::DataManipulator *dm = new KSpread::DataManipulator (); + dm->setSheet (m_sheet); + dm->setValue (text); + dm->setParsing (true); + dm->add (QPoint (m_col, m_row)); + dm->execute (); + + return true; +} + +const QString Cell::textColor() { + return m_cell->format()->textColor(m_col, m_row).name(); +} + +void Cell::setTextColor(const QString& textcolor) { + m_cell->format()->setTextColor( QColor(textcolor) ); +} + +const QString Cell::backgroundColor() { + return m_cell->format()->bgColor(m_col, m_row).name(); +} + +void Cell::setBackgroundColor(const QString& backgroundcolor) { + m_cell->format()->setBgColor( QColor(backgroundcolor) ); +} + +} +} diff --git a/kspread/plugins/scripting/kspreadcore/krs_cell.h b/kspread/plugins/scripting/kspreadcore/krs_cell.h new file mode 100644 index 00000000..5f3f221d --- /dev/null +++ b/kspread/plugins/scripting/kspreadcore/krs_cell.h @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2005 Cyrille Berger <[email protected]> + * Copyright (c) 2006 Isaac Clerencia <[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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KROSS_KSPREADCOREKRSCELL_H +#define KROSS_KSPREADCOREKRSCELL_H + +#include <kspread_sheet.h> +#include <kspread_cell.h> +#include <kspread_value.h> + +#include <api/class.h> + +#include <qstring.h> +#include <qcolor.h> + +namespace Kross { namespace KSpreadCore { + +/** + * For every cell in the spread sheet there is a Cell object. + * + * Cell contains format information and algorithm and it + * contains the calculation algorithm. + * + * Example (in Ruby) : + * @code + * doc = krosskspreadcore::get("KSpreadDocument") + * sheet = doc.currentSheet() + * cellA1 = sheet.cell(0, 0) + * cellA2 = sheet.cell(0, 1) + * cellA2.setValue( cellA1.value() ) + * cellA2.setTextColor( "#ff0000" ) + * @endcode + */ +class Cell : public Kross::Api::Class<Cell> +{ + public: + Cell(KSpread::Cell* cell, KSpread::Sheet* sheet, uint col, uint row); + virtual ~Cell(); + virtual const QString getClassName() const; + private: + + /** + * Return the value of the cell. + */ + QVariant value() const; + /** + * Set the value the cell has. + */ + bool setValue(const QVariant& value); + + /** + * Return the column number. + */ + int column() const; + /** + * Return the row number. + */ + int row() const; + + /** + * Return the previous cell if there is any. + */ + Cell* previousCell() const; + /** + * Return the next cell if there is any. + */ + Cell* nextCell() const; + /** + * Set the previous cell. + */ + void setPreviousCell(Cell* c); + /** + * Set the next cell. + */ + void setNextCell(Cell* c); + + /** + * Returns the name of the cell. For example, the cell in first column + * and first row is "A1". + */ + const QString name() const; + /** + * Returns the full name of the cell, i.e. including the worksheet name. + * Example: "Sheet1!A1" + */ + const QString fullName() const; + + /** + * Returns the comment for the cell. + */ + const QString comment() const; + /** + * Set the comment for the cell. + */ + void setComment(const QString& c); + +#if 0 + bool isFormula() const; + Formula *formula () const; +#endif + + /** + * Returns the format of the cell, e.g. #.##0.00, dd/mmm/yyyy,... + */ + const QString getFormatString() const; + /** + * Sets the format of the cell, e.g. #.##0.00, dd/mmm/yyyy,... + */ + void setFormatString(const QString& format); + + /** + * Return the text of the cell (the formula if there is one, + * the value otherwise). This could be a value (e.g. "14.03") + * or a formula (e.g. "=SUM(A1:A10)") + */ + const QString text() const; + /** + * Set the text of the cell. the text + * will be handled as string + */ + bool setText(const QString& text); + + /** + * Return the textcolor as RGB-value in the format "#RRGGBB". + */ + const QString textColor(); + /** + * Set the textcolor to the RGB-value in the format "#RRGGBB" + * where each of R, G, and B is a single hex digit. + */ + void setTextColor(const QString& textcolor); + + /** + * Return the backgroundcolor as RGB-value in the format "#RRGGBB". + */ + const QString backgroundColor(); + /** + * Set the backgroundcolor to the RGB-value in the format "#RRGGBB" + * where each of R, G, and B is a single hex digit. + */ + void setBackgroundColor(const QString& backgroundcolor); + + private: + KSpread::Cell* m_cell; + KSpread::Sheet* m_sheet; + uint m_col, m_row; + + QVariant toVariant(const KSpread::Value& value) const; +}; +} +} + + +#endif diff --git a/kspread/plugins/scripting/kspreadcore/krs_doc.cpp b/kspread/plugins/scripting/kspreadcore/krs_doc.cpp new file mode 100644 index 00000000..37c87efd --- /dev/null +++ b/kspread/plugins/scripting/kspreadcore/krs_doc.cpp @@ -0,0 +1,135 @@ +/* + * Copyright (c) 2005 Cyrille Berger <[email protected]> + * Copyright (c) 2006 Isaac Clerencia <[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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "krs_doc.h" +#include "krs_sheet.h" + +#include <kspread_map.h> +#include <kspread_sheet.h> + +namespace Kross { namespace KSpreadCore { + +Doc::Doc(KSpread::Doc* doc) + : Kross::Api::Class<Doc>("KSpreadDocument"), m_doc(doc) +{ + this->addFunction0< Sheet >("currentSheet", this, &Doc::currentSheet); + this->addFunction1< Sheet, Kross::Api::Variant >("sheetByName", this, &Doc::sheetByName); + this->addFunction0< Kross::Api::Variant >("sheetNames", this, &Doc::sheetNames); + + this->addFunction1< Kross::Api::Variant, Kross::Api::Variant >("addSheet", this, &Doc::addSheet); + this->addFunction1< Kross::Api::Variant, Kross::Api::Variant >("removeSheet", this, &Doc::removeSheet); + + this->addFunction1< Kross::Api::Variant, Kross::Api::Variant >("loadNativeXML", this, &Doc::loadNativeXML); + this->addFunction0< Kross::Api::Variant >("saveNativeXML", this, &Doc::saveNativeXML); + + this->addFunction1< Kross::Api::Variant, Kross::Api::Variant >("openUrl", this, &Doc::openUrl); + this->addFunction1< Kross::Api::Variant, Kross::Api::Variant >("saveUrl", this, &Doc::saveUrl); + this->addFunction1< Kross::Api::Variant, Kross::Api::Variant >("import", this, &Doc::import); + this->addFunction1< Kross::Api::Variant, Kross::Api::Variant >("exp0rt", this, &Doc::exp0rt); + +} + +Doc::~Doc() { + +} + +const QString Doc::getClassName() const { + return "Kross::KSpreadCore::Doc"; +} + +Sheet* Doc::currentSheet() +{ + return new Sheet(m_doc->displaySheet(), m_doc); +} + +Sheet* Doc::sheetByName(const QString& name) +{ + QPtrListIterator<KSpread::Sheet> it (m_doc->map()->sheetList()); + for( ; it.current(); ++it ) + if(it.current()->sheetName() == name) + return new Sheet(it.current(), m_doc); + return 0; +} + +QStringList Doc::sheetNames() +{ + QStringList names; + QPtrListIterator<KSpread::Sheet> it (m_doc->map()->sheetList()); + for( ; it.current(); ++it ) + names.append( it.current()->sheetName() ); + return names; +} + +bool Doc::addSheet(const QString& sheetname) +{ + KSpread::Sheet* sheet = m_doc->map()->createSheet(); + if(sheet) { + if(! sheet->setSheetName(sheetname)) { + delete sheet; + return false; + } + m_doc->map()->addSheet(sheet); + return true; + } + return false; +} + +bool Doc::removeSheet(const QString& sheetname) +{ + KSpread::Sheet* sheet = m_doc->map()->findSheet(sheetname); + if(sheet) { + m_doc->map()->takeSheet(sheet); + return true; + } + return false; +} + +bool Doc::loadNativeXML(const QString& xml) { + QDomDocument doc; + if(! doc.setContent(xml, true)) + return false; + return m_doc->loadXML(0, doc); +} + +QString Doc::saveNativeXML() { + return m_doc->saveXML().toString(2); +} + +bool Doc::openUrl(const QString& url) +{ + return m_doc->openURL(url); +} + +bool Doc::saveUrl(const QString& url) +{ + return m_doc->saveAs(url); +} + +bool Doc::import(const QString& url) +{ + return m_doc->import(url); +} + +bool Doc::exp0rt(const QString& url) +{ + return m_doc->exp0rt(url); +} + +}} + diff --git a/kspread/plugins/scripting/kspreadcore/krs_doc.h b/kspread/plugins/scripting/kspreadcore/krs_doc.h new file mode 100644 index 00000000..28c69845 --- /dev/null +++ b/kspread/plugins/scripting/kspreadcore/krs_doc.h @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2005 Cyrille Berger <[email protected]> + * Copyright (c) 2006 Isaac Clerencia <[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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KSPREAD_KROSS_KRS_DOC_H_ +#define KSPREAD_KROSS_KRS_DOC_H_ + +#include <kspread_doc.h> + +#include <api/class.h> + +#include <qstring.h> +#include <qstringlist.h> +#include <qdom.h> + +namespace Kross { namespace KSpreadCore { + +class Sheet; + +/** + * The KSpread document. + * + * Example (in Ruby) : + * @code + * doc = krosskspreadcore::get("KSpreadDocument") + * @endcode + */ +class Doc : public Kross::Api::Class<Doc> +{ + public: + explicit Doc(KSpread::Doc* doc); + virtual ~Doc(); + virtual const QString getClassName() const; + private: + + /** + * This function returns the Sheet currently active in this + * document. + * + * Example (in Ruby) : + * @code + * doc = krosskspreadcore::get("KSpreadDocument") + * sheet = doc.currentSheet() + * @endcode + */ + Sheet* currentSheet(); + + /** + * This function returns a Sheet by name. + * + * Example (in Ruby) : + * @code + * doc = krosskspreadcore::get("KSpreadDocument") + * sheet = doc.sheetByName("foosheet") + * @endcode + */ + Sheet* sheetByName(const QString& name); + + /** + * This function returns an array with the sheet names + * + * Example (in Ruby) : + * @code + * doc = krosskspreadcore::get("KSpreadDocument") + * sheetnames = doc.sheetNames() + * sheet = doc.sheetByName( sheetnames[0] ) + * @endcode + */ + QStringList sheetNames(); + + /** + * Add a new sheet named @p sheetname to the document. + */ + bool addSheet(const QString& sheetname); + + /** + * Remove the sheet named @p sheetname from the document. + */ + bool removeSheet(const QString& sheetname); + + /** + * Loads the native XML document. + */ + bool loadNativeXML(const QString& xml); + /** + * Save and return the to a native document saved XML. + */ + QString saveNativeXML(); + +#if 0 + bool loadOpenDocXML(const QString& xml); + QString saveOpenDocXML(); +#endif + + bool openUrl(const QString& url); + bool saveUrl(const QString& url); + bool import(const QString& url); + bool exp0rt(const QString& url); + + private: + KSpread::Doc* m_doc; +}; +} +} + + +#endif diff --git a/kspread/plugins/scripting/kspreadcore/krs_sheet.cpp b/kspread/plugins/scripting/kspreadcore/krs_sheet.cpp new file mode 100644 index 00000000..694037ed --- /dev/null +++ b/kspread/plugins/scripting/kspreadcore/krs_sheet.cpp @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2005 Cyrille Berger <[email protected]> + * Copyright (c) 2006 Isaac Clerencia <[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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "krs_cell.h" +#include "krs_sheet.h" +#include "krs_doc.h" + +#include <kspread_doc.h> +#include <kspread_sheet.h> +#include <kspread_cell.h> +#include <kspread_value.h> + +namespace Kross { namespace KSpreadCore { + +Sheet::Sheet(KSpread::Sheet* sheet, KSpread::Doc *doc) : Kross::Api::Class<Sheet>("KSpreadSheet"), m_sheet(sheet), m_doc(doc) { + + this->addFunction0< Kross::Api::Variant >("name", this, &Sheet::name); + this->addFunction1< void, Kross::Api::Variant >("setName", this, &Sheet::setName); + + this->addFunction0< Kross::Api::Variant >("maxColumn", this, &Sheet::maxColumn); + this->addFunction0< Kross::Api::Variant >("maxRow", this, &Sheet::maxRow); + + this->addFunction0< Cell >("firstCell", this, &Sheet::firstCell); + + this->addFunction2< Cell, Kross::Api::Variant, Kross::Api::Variant >("cell", this, &Sheet::cell); + + this->addFunction1< Kross::Api::Variant, Kross::Api::Variant >("insertRow", this, &Sheet::insertRow); + this->addFunction1< Kross::Api::Variant, Kross::Api::Variant >("insertColumn", this, &Sheet::insertColumn); + + this->addFunction1< void, Kross::Api::Variant >("removeRow", this, &Sheet::removeRow); + this->addFunction1< void, Kross::Api::Variant >("removeColumn", this, &Sheet::removeColumn); +} + +Sheet::~Sheet() { +} + +const QString Sheet::getClassName() const { + return "Kross::KSpreadCore::Sheet"; +} + +const QString Sheet::name() const +{ + return m_sheet->sheetName(); +} + +void Sheet::setName(const QString& name) +{ + m_sheet->setSheetName(name); +} + +int Sheet::maxColumn() const { + return m_sheet->maxColumn(); +} + +int Sheet::maxRow() const { + return m_sheet->maxRow(); +} + +Cell* Sheet::firstCell() const { + KSpread::Cell* c = m_sheet->firstCell(); + return c ? new Cell(c,c->sheet(),c->column(),c->row()) : 0; +} + +Cell* Sheet::cell(uint col, uint row) { + uint c = QMAX(uint(1), col); + uint r = QMAX(uint(1), row); + return new Cell(m_sheet->cellAt(c,r),m_sheet,c,r); +} + +bool Sheet::insertRow(uint row) { + return m_sheet->insertRow(row); +} + +bool Sheet::insertColumn(uint col) { + return m_sheet->insertColumn(col); +} + +void Sheet::removeRow(uint row) { + m_sheet->removeRow( QMAX(uint(1), row) ); +} + +void Sheet::removeColumn(uint col) { + m_sheet->removeColumn( QMAX(uint(1), col) ); +} + +} +} diff --git a/kspread/plugins/scripting/kspreadcore/krs_sheet.h b/kspread/plugins/scripting/kspreadcore/krs_sheet.h new file mode 100644 index 00000000..a96e758e --- /dev/null +++ b/kspread/plugins/scripting/kspreadcore/krs_sheet.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2005 Cyrille Berger <[email protected]> + * Copyright (c) 2006 Isaac Clerencia <[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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KROSS_KSPREADCOREKRSSHEET_H +#define KROSS_KSPREADCOREKRSSHEET_H + +#include <kspread_sheet.h> +#include <kspread_value.h> + +#include <api/class.h> + +namespace Kross { namespace KSpreadCore { + +class Cell; + +/** + * A sheet in a document. + * + * Example (in Ruby) : + * @code + * doc = krosskspreadcore::get("KSpreadDocument") + * sheet1 = doc.sheetByName("Sheet1") + * sheet2 = doc.sheetByName("Sheet2") + * cell1 = sheet1.firstCell() + * while cell1 + * colnr = cell1.column() + * rownr = cell1.row() + * cell2 = sheet2.cell(colnr, rownr) + * cell2.setValue( cell1.value() ) + * cell1 = cell1.nextCell() + * end + * @endcode + */ +class Sheet : public Kross::Api::Class<Sheet> +{ + public: + Sheet(KSpread::Sheet* sheet, KSpread::Doc* doc = 0); + virtual ~Sheet(); + virtual const QString getClassName() const; + private: + + /** + * Return the name of the sheet. + */ + const QString name() const; + /** + * Set the name of the sheet. + */ + void setName(const QString& name); + + /** + * Return the currently maximum defined number of columns. + */ + int maxColumn() const; + /** + * Return the currently maximum defined number of rows. + */ + int maxRow() const; + + /** + * Return the first cell. Use the firstCell() and nextCell() + * methods as outlined in the example to iterate only through + * filled cells (aka cells with content). + * + * Example (in Python) : + * @code + * import krosskspreadcore + * doc = krosskspreadcore.get("KSpreadDocument") + * sheet = doc.currentSheet() + * cell = sheet.firstCell() + * while cell: + * print "Cell col=%s row=%s value=%s" % (cell.column(),cell.row(),cell.value()) + * cell = cell.nextCell() + * @endcode + */ + Cell* firstCell() const; + + /** + * Return the given cell. The first parameter is the column-number + * while the second defines the rownumber. The first cell starts + * with 0,0. If you like to iterate over all cells that have content, + * use the firstCell() and nextCell() methods which is much faster + * cause empty cells are ignored. + * + * Example (in Python) : + * @code + * import krosskspreadcore + * doc = krosskspreadcore.get("KSpreadDocument") + * sheet = doc.currentSheet() + * for colnr in range( sheet.maxColumn() ): + * for rownr in range( sheet.maxRow() ): + * cell = sheet.cell(colnr, rownr) + * if cell.value() != None: + * print "Cell col=%s row=%s value=%s" % (colnr,rownr,cell.value()) + * @endcode + */ + Cell* cell(uint col, uint row); + + /** + * Add a new row. + */ + bool insertRow(uint row); + /** + * Add a new column. + */ + bool insertColumn(uint col); + + /** + * Remove a row. + */ + void removeRow(uint row); + /** + * Remove a column. + */ + void removeColumn(uint col); + + private: + KSpread::Sheet* m_sheet; + KSpread::Doc* m_doc; +}; +} +} + +#endif diff --git a/kspread/plugins/scripting/kspreadcore/kspreadcoremodule.cpp b/kspread/plugins/scripting/kspreadcore/kspreadcoremodule.cpp new file mode 100644 index 00000000..acfd0b2b --- /dev/null +++ b/kspread/plugins/scripting/kspreadcore/kspreadcoremodule.cpp @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2005 Cyrille Berger <[email protected]> + * Copyright (c) 2006 Isaac Clerencia <[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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include "kspreadcoremodule.h" + +#include <kdebug.h> + +//#include <api/variant.h> +#include <api/qtobject.h> +#include <main/manager.h> + +#include "krs_doc.h" + +extern "C" +{ + /** + * Exported an loadable function as entry point to use + * the \a KexiAppModule. + */ + Kross::Api::Object* init_module(Kross::Api::Manager* manager) + { + return new Kross::KSpreadCore::KSpreadCoreModule(manager); + } +} + + +using namespace Kross::KSpreadCore; + +KSpreadCoreModule::KSpreadCoreModule(Kross::Api::Manager* manager) + : Kross::Api::Module("kspreadcore") , m_manager(manager) +{ + QMap<QString, Object::Ptr> children = manager->getChildren(); + kdDebug() << " there are " << children.size() << endl; + for(QMap<QString, Object::Ptr>::const_iterator it = children.begin(); it != children.end(); it++) + { + kdDebug() << it.key() << " " << it.data() << endl; + } + + // Wrap doc + Kross::Api::Object::Ptr kspreaddocument = manager->getChild("KSpreadDocument"); + if(! kspreaddocument) { + KSpread::Doc* doc = new KSpread::Doc(); + addChild( new Kross::KSpreadCore::Doc(doc) ); + } + else { + Kross::Api::QtObject* kspreaddocumentqt = dynamic_cast< Kross::Api::QtObject* >( kspreaddocument.data() ); + if(kspreaddocumentqt) { + KSpread::Doc* document = dynamic_cast< ::KSpread::Doc* >( kspreaddocumentqt->getObject() ); + if(document) { + addChild( new Doc(document) ); + } else { + throw Kross::Api::Exception::Ptr( new Kross::Api::Exception("There was no 'KSpreadDocument' published.") ); + } + } + } +} + +KSpreadCoreModule::~KSpreadCoreModule() +{ +} + + +const QString KSpreadCoreModule::getClassName() const +{ + return "Kross::KSpreadCore::KSpreadCoreModule"; +} diff --git a/kspread/plugins/scripting/kspreadcore/kspreadcoremodule.h b/kspread/plugins/scripting/kspreadcore/kspreadcoremodule.h new file mode 100644 index 00000000..ffc998cc --- /dev/null +++ b/kspread/plugins/scripting/kspreadcore/kspreadcoremodule.h @@ -0,0 +1,82 @@ +/* + * Copyright (c) 2005 Cyrille Berger <[email protected]> + * Copyright (c) 2006 Isaac Clerencia <[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; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef KSPREAD_KROSS_KSPREADCOREMODULE_H +#define KSPREAD_KROSS_KSPREADCOREMODULE_H + +#include <qstring.h> +#include <qvariant.h> + +#define KROSS_MAIN_EXPORT KDE_EXPORT + +#include <api/module.h> +#include <api/event.h> + +namespace Kross { namespace Api { + class Manager; +}} + +namespace Kross { namespace KSpreadCore { + + /** + * The KSpreadCoreModule class implements a Kross::Api::Module to + * provide access to the KSpread functionality. + * + * Example (in Ruby) : + * @code + * doc = krosskspreadcore::get("KSpreadDocument") + * sheet = doc.currentSheet() + * cell = sheet.cell(0, 0) + * cell.setValue("Hello World") + * @endcode + */ + class KSpreadCoreModule : public Kross::Api::Module + { + public: + KSpreadCoreModule(Kross::Api::Manager* manager); + virtual ~KSpreadCoreModule(); + virtual const QString getClassName() const; + //virtual Kross::Api::Object::Ptr call(const QString& name, Kross::Api::List::Ptr arguments); + private: + +#if 0 + /** + * This function return a new Color with the given RGB triplet + * It takes three arguments : + * - red color (0 to 255) + * - blue color (0 to 255) + * - green color (0 to 255) + * + * For example (in ruby) : + * @code + * Krosskritacore::newRGBColor(255,0,0) # create a red color + * Krosskritacore::newRGBColor(255,255,255) # create a white color + * @endcode + */ + Kross::Api::Object::Ptr newRGBColor(Kross::Api::List::Ptr); +#endif + + private: + Kross::Api::Manager* m_manager; + }; + +}} + +#endif + diff --git a/kspread/plugins/scripting/kspreadscripting.desktop b/kspread/plugins/scripting/kspreadscripting.desktop new file mode 100644 index 00000000..2a22f10b --- /dev/null +++ b/kspread/plugins/scripting/kspreadscripting.desktop @@ -0,0 +1,80 @@ +[Desktop Entry] +Name=Scripting plugin +Name[bg]=Приставка за скриптове +Name[ca]=Connector de seqüenciació +Name[da]=Scriptplugin +Name[de]=Skripting-Modul +Name[el]=Πρόσθετο γραφής σεναρίων +Name[eo]=Skriptad-kromaĵo +Name[es]=Complemento para guiones +Name[et]=Skriptiplugin +Name[fa]=وصلۀ دستنوشته +Name[fr]=Module de scriptage +Name[fy]=Skriptplugin +Name[ga]=Breiseán scriptithe +Name[gl]=Plugin de programación +Name[he]=תוסף לתסריטים +Name[hu]=Szkript modul +Name[is]=Skriftu íforrit +Name[it]=Plugin di scripting +Name[ja]=スクリプトプラグイン +Name[km]=កម្មវិធីជំនួយសម្រាប់ស្គ្រីប +Name[nb]=Programtillegg for skripting +Name[nds]=Skriptmoduul +Name[ne]=प्लगइन स्क्रिप्ट गर्दै +Name[nl]=Scriptplugin +Name[pl]=Wtyczka obsługi języków skryptowych +Name[pt]='Plugin' de programação +Name[pt_BR]=Plugin de programação +Name[ru]=Модуль поддержки сценариев +Name[sk]=Modul pre skripty +Name[sl]=Vstavek za skripte +Name[sr]=Прикључак за скриптовање +Name[sr@Latn]=Priključak za skriptovanje +Name[sv]=Skriptinsticksprogram +Name[uk]=Втулок для скриптів +Name[uz]=Skriptlash plagini +Name[uz@cyrillic]=Скриптлаш плагини +Name[zh_CN]=脚本插件 +Name[zh_TW]=命令稿外掛程式 +Comment=Allow execution of scripts +Comment[bg]=Изпълнение на скриптове +Comment[ca]=Permet l'execució de seqüències +Comment[da]=Tillad kørsel af script +Comment[de]=Ermöglicht das Ausführen von Skripten +Comment[el]=Επιτρέπει την εκτέλεση σεναρίων +Comment[eo]=Permesi ruligon de skriptoj +Comment[es]=Permite la ejecución de guiones +Comment[et]=Võimaldab skriptide käivitamist +Comment[fa]=اجازۀ اجرای دستنوشتهها +Comment[fr]=Permet d'exécuter des scripts +Comment[fy]=Hjirmei kinne skripts útfierd wurde +Comment[gl]=Permite executar guións +Comment[he]=אפשרות להרצת תסריטים +Comment[hu]=Lehetővé teszi szkriptek végrehajtását +Comment[is]=Leyfa að skriftur séu keyrðar +Comment[it]=Permette di eseguire script +Comment[ja]=スクリプトの実行を可能にします +Comment[km]=អនុញ្ញាតឲ្យប្រតិបត្តិស្គ្រីប +Comment[lv]=Atļaut skriptu izpildi +Comment[nb]=Tillater skriptkjøring +Comment[nds]=Skripten utföhren +Comment[ne]=स्क्रिप्टको कार्यान्वयनलाई अनुमति दिनुहोस् +Comment[nl]=Hiermee kunnen scripts uitgevoerd worden +Comment[pl]=Zezwala na wykonywanie skryptów +Comment[pt]=Permitir executar programas ou 'scripts' +Comment[pt_BR]=Permitir executar programas ou 'scripts' +Comment[ru]=Возможность выполнения сценариев +Comment[sk]=Povoliť vykonávanie skriptov +Comment[sl]=Dovoli izvedbo skriptov +Comment[sr]=Омогући извршавање скрипти +Comment[sr@Latn]=Omogući izvršavanje skripti +Comment[sv]=Tillåt körning av skript +Comment[uk]=Дає змогу виконувати скрипти +Comment[uz]=Skriptlarni ishga tushirishga ruxsat berish +Comment[uz@cyrillic]=Скриптларни ишга туширишга рухсат бериш +Comment[zh_CN]=允许执行脚本 +Comment[zh_TW]=允許執行命令稿 +Type=Service +X-KDE-Library=kspreadscripting +X-KDE-Version=1 diff --git a/kspread/plugins/scripting/scripting.cc b/kspread/plugins/scripting/scripting.cc new file mode 100644 index 00000000..96cd1baf --- /dev/null +++ b/kspread/plugins/scripting/scripting.cc @@ -0,0 +1,84 @@ +/* + * This file is part of the KSpread project + * + * Copyright (c) 2005 Cyrille Berger <[email protected]> + * Copyright (c) 2006 Isaac Clerencia <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include "scripting.h" + +#include <qapplication.h> + +#include <kdebug.h> +#include <kgenericfactory.h> +#include <kstandarddirs.h> + +#define KROSS_MAIN_EXPORT KDE_EXPORT +#include <main/manager.h> +#include <main/scriptguiclient.h> +#include <main/wdgscriptsmanager.h> + +#include <kspread_doc.h> +#include <kspread_view.h> + +typedef KGenericFactory<Scripting> KSpreadScriptingFactory; +K_EXPORT_COMPONENT_FACTORY( kspreadscripting, KSpreadScriptingFactory( "kspreadscripting" ) ) + +Scripting::Scripting(QObject *parent, const char *name, const QStringList &) + : KParts::Plugin(parent, name) +{ + setInstance(KSpreadScriptingFactory::instance()); + + kdDebug() << "Scripting plugin. Class: " + << metaObject()->className() + << ", Parent: " + << parent->metaObject()->className() + << "\n"; + + if ( parent->inherits("KSpread::View") ) + { + setInstance(Scripting::instance()); + m_view = (KSpread::View*) parent; + m_scriptguiclient = new Kross::Api::ScriptGUIClient( m_view, m_view ); +// m_scriptguiclient ->setXMLFile(locate("data","kspreadplugins/scripting.rc"), true); + kdDebug() << "Setup actions for scripting !" << endl; + + setXMLFile(locate("data","kspread/kpartplugins/scripting.rc"), true); + + new KAction(i18n("Execute Script File..."), 0, 0, m_scriptguiclient, SLOT(executeScriptFile()), actionCollection(), "executescriptfile"); + new KAction(i18n("Script Manager..."), 0, 0, m_scriptguiclient, SLOT(showScriptManager()), actionCollection(), "configurescripts"); + + KAction* scriptmenuaction = m_scriptguiclient->action("installedscripts"); + actionCollection()->insert(scriptmenuaction); + + connect(m_scriptguiclient, SIGNAL(executionFinished( const Kross::Api::ScriptAction* )), this, SLOT(executionFinished(const Kross::Api::ScriptAction*))); + + Kross::Api::Manager::scriptManager()->addQObject(m_view->doc(), "KSpreadDocument"); + Kross::Api::Manager::scriptManager()->addQObject(m_view, "KSpreadView"); + } + +} + +Scripting::~Scripting() +{ +} + +void Scripting::executionFinished(const Kross::Api::ScriptAction*) +{ + QApplication::restoreOverrideCursor(); +} + +#include "scripting.moc" diff --git a/kspread/plugins/scripting/scripting.h b/kspread/plugins/scripting/scripting.h new file mode 100644 index 00000000..1d08bd9f --- /dev/null +++ b/kspread/plugins/scripting/scripting.h @@ -0,0 +1,49 @@ +/* + * This file is part of KSpread + * + * Copyright (c) 2005 Cyrille Berger <[email protected]> + * Copyright (c) 2006 ISaac Clerencia <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef SCRIPTING_H +#define SCRIPTING_H + +#include <kparts/plugin.h> +#include <kspread_view.h> + +namespace Kross { + namespace Api { + class ScriptGUIClient; + class ScriptAction; + } +} + +class Scripting : public KParts::Plugin +{ + Q_OBJECT + public: + Scripting(QObject *parent, const char *name, const QStringList &); + virtual ~Scripting(); + private slots: + void executionFinished(const Kross::Api::ScriptAction*); + private: + KSpread::View * m_view; + Kross::Api::ScriptGUIClient* m_scriptguiclient; +}; + + +#endif diff --git a/kspread/plugins/scripting/scripting.rc b/kspread/plugins/scripting/scripting.rc new file mode 100644 index 00000000..7388099a --- /dev/null +++ b/kspread/plugins/scripting/scripting.rc @@ -0,0 +1,13 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui name="KSpreadPluginScripting" library="kspreadscripting" version="3"> + <MenuBar> + <Menu name="tools"><text>&Tools</text> + <Separator/> + <!-- + <Action name="executescriptfile"/> + //--> + <Action name="configurescripts"/> + <Action name="installedscripts"/> + </Menu> + </MenuBar> +</kpartgui> diff --git a/kspread/plugins/scripting/scripts/Makefile.am b/kspread/plugins/scripting/scripts/Makefile.am new file mode 100644 index 00000000..3dc0ae8e --- /dev/null +++ b/kspread/plugins/scripting/scripts/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = exporthtml scripteditor diff --git a/kspread/plugins/scripting/scripts/exporthtml/ExportHtml.py b/kspread/plugins/scripting/scripts/exporthtml/ExportHtml.py new file mode 100755 index 00000000..2e2dfc31 --- /dev/null +++ b/kspread/plugins/scripting/scripts/exporthtml/ExportHtml.py @@ -0,0 +1,179 @@ +""" +KSpread Kross Python Script. + +Export to HTML File. + +Description: +This script exports data from KSpread to a HTML file. + +Author: +Sebastian Sauer <[email protected]> + +Copyright: +Dual-licensed under LGPL v2+higher and the BSD license. +""" + +import os, sys + +try: + import qt +except (ImportError): + raise "Failed to import the required PyQt python module." + +class Dialog(qt.QDialog): + def __init__(self, scriptpath, parent): + self.scriptpath = scriptpath + + import krosskspreadcore + self.doc = krosskspreadcore.get("KSpreadDocument") + + import qt + qt.QDialog.__init__(self, parent, "Dialog", 1, qt.Qt.WDestructiveClose) + self.setCaption("Export to HTML File") + layout = qt.QVBoxLayout(self) + box = qt.QVBox(self) + box.setMargin(10) + box.setSpacing(10) + layout.addWidget(box) + + sheetbox = qt.QHBox(box) + sheetbox.setSpacing(6) + sheetlabel = qt.QLabel("Sheet:",sheetbox) + self.sheetcombo = qt.QComboBox(sheetbox) + currentsheetname = self.doc.currentSheet().name() + for sheetname in self.doc.sheetNames(): + self.sheetcombo.insertItem(sheetname) + if sheetname == currentsheetname: + self.sheetcombo.setCurrentItem(self.sheetcombo.count() - 1) + sheetlabel.setBuddy(self.sheetcombo) + sheetbox.setStretchFactor(self.sheetcombo,1) + + self.styles = { + "Paper" : + "html { background-color:#efefef; }" + "body { background-color:#fafafa; color:#303030; margin:1em; padding:1em; border:#606060 1px solid; }" + , + "Plain" : + "html { background-color:#ffffff; color:#000; }" + "body { margin:1em; }" + , + "Seawater" : + "html { background-color:#0000aa; }" + "body { background-color:#000066; color:#efefff; margin:1em; padding:1em; border:#00f 1px solid; }" + "h1 { color:#0000ff; }" + "th { color:#6666ff; }" + , + } + + stylebox = qt.QHBox(box) + stylebox.setSpacing(6) + stylelabel = qt.QLabel("Style:",stylebox) + self.stylecombo = qt.QComboBox(stylebox) + stylenames = self.styles.keys() + stylenames.sort() + for stylename in stylenames: + self.stylecombo.insertItem(stylename) + stylelabel.setBuddy(self.stylecombo) + stylebox.setStretchFactor(self.stylecombo,1) + + filebox = qt.QHBox(box) + filebox.setSpacing(6) + filelabel = qt.QLabel("File:",filebox) + self.fileedit = qt.QLineEdit(self.getDefaultFile(),filebox) + btn = qt.QPushButton("...",filebox) + qt.QObject.connect(btn, qt.SIGNAL("clicked()"),self.browseClicked) + filelabel.setBuddy(self.fileedit) + filebox.setStretchFactor(self.fileedit,1) + + btnbox = qt.QHBox(box) + btnbox.setSpacing(6) + okbtn = qt.QPushButton(btnbox) + okbtn.setText("Export") + okbtn.setDefault(True) + qt.QObject.connect(okbtn,qt.SIGNAL("clicked()"),self.startExport) + cancelbtn = qt.QPushButton(btnbox) + cancelbtn.setText("Cancel") + qt.QObject.connect(cancelbtn,qt.SIGNAL("clicked()"),self.close) + + box.setMinimumWidth(480) + + def browseClicked(self): + import qt + filename = str( qt.QFileDialog.getSaveFileName(str(self.fileedit.text()),"*.htm *.html *.xhtml;;*", self) ) + if filename != "": self.fileedit.setText(filename) + + def getDefaultFile(self): + import os + try: + homepath = os.getenv("HOME") + if not homepath: + import pwd + user = os.getenv("USER") or os.getenv("LOGNAME") + if not user: + pwent = pwd.getpwuid(os.getuid()) + else: + pwent = pwd.getpwnam(user) + homepath = pwent[6] + except (KeyError, ImportError): + homepath = os.curdir + return os.path.join(homepath, "kspreadexport.html") + + def startExport(self): + import qt + + sheetname = str( self.sheetcombo.currentText() ) + sheet = self.doc.sheetByName( sheetname ) + print "sheetname=%s sheet=%s" % (sheetname,sheet) + + filename = str( self.fileedit.text() ) + try: + file = open(filename, "w") + except IOError, (errno, strerror): + qt.QMessageBox.critical(self,"Error","<qt>Failed to create HTML file \"%s\"<br><br>%s</qt>" % (filename,strerror)) + return + + file.write("<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n") + file.write("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n") + file.write("<html xmlns=\"http://www.w3.org/1999/xhtml\" xml:lang=\"en\">\n") + file.write("<head><title>%s</title>\n" % sheetname) + + file.write("<style type=\"text/css\">\n<!--\n") + file.write( self.styles[ str(self.stylecombo.currentText()) ] ) + file.write("\n//-->\n</style>\n") + + file.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\" />\n") + file.write("</head><body><h1>%s</h1>\n" % sheetname) + + file.write("<table border=\"1\">\n") + cell = sheet.firstCell() + prevrow = -1 + while cell: + #print "Cell col=%s row=%s value=%s" % (cell.column(),cell.row(),cell.value()) + + row = cell.row() + if row != prevrow: + prevrow = row + file.write("<tr>") + file.write("<th>%s</th>" % row) + + file.write("<td>%s</td>" % cell.value()) + + cell = cell.nextCell() + if cell == None or cell.row() != prevrow: + file.write("</tr>\n") + + file.write("</table>\n") + file.write("</body></html>\n") + + file.close() + self.close() + +if __name__ == "__main__": + scriptpath = os.getcwd() + qtapp = qt.QApplication(sys.argv) +else: + scriptpath = os.path.dirname(__name__) + qtapp = qt.qApp + +dialog = Dialog(scriptpath, qtapp.mainWidget()) +dialog.exec_loop() diff --git a/kspread/plugins/scripting/scripts/exporthtml/ExportHtml.rc b/kspread/plugins/scripting/scripts/exporthtml/ExportHtml.rc new file mode 100755 index 00000000..8ec7b290 --- /dev/null +++ b/kspread/plugins/scripting/scripts/exporthtml/ExportHtml.rc @@ -0,0 +1,9 @@ +<KrossScripting> + <ScriptAction + name="exporthtml" + version="1" + text="Export to HTML File..." + icon="fileexport" + interpreter="python" + file="ExportHtml.py" /> +</KrossScripting> diff --git a/kspread/plugins/scripting/scripts/exporthtml/Makefile.am b/kspread/plugins/scripting/scripts/exporthtml/Makefile.am new file mode 100644 index 00000000..aa65c3e5 --- /dev/null +++ b/kspread/plugins/scripting/scripts/exporthtml/Makefile.am @@ -0,0 +1,2 @@ +scriptsdir = $(kde_datadir)/kspread/scripts/exporthtml +scripts_SCRIPTS = ExportHtml.py ExportHtml.rc diff --git a/kspread/plugins/scripting/scripts/scripteditor/Makefile.am b/kspread/plugins/scripting/scripts/scripteditor/Makefile.am new file mode 100644 index 00000000..a1885476 --- /dev/null +++ b/kspread/plugins/scripting/scripts/scripteditor/Makefile.am @@ -0,0 +1,2 @@ +scriptsdir = $(kde_datadir)/kspread/scripts/scripteditor +scripts_SCRIPTS = ScriptEditor.py ScriptEditor.rc diff --git a/kspread/plugins/scripting/scripts/scripteditor/ScriptEditor.py b/kspread/plugins/scripting/scripts/scripteditor/ScriptEditor.py new file mode 100755 index 00000000..f015a5f1 --- /dev/null +++ b/kspread/plugins/scripting/scripts/scripteditor/ScriptEditor.py @@ -0,0 +1,1089 @@ +""" +Kross Script Editor + +Description: +This script provides a in python written script editor. + +Author: +Sebastian Sauer <[email protected]> + +Copyright: +Dual-licensed under LGPL v2+higher and the BSD license. +""" + +import os, sys + +try: + import qt +except (ImportError): + raise "Failed to import the required PyQt python module." + +#################################################################################### +# Samples. + +class Widget(qt.QHBox): + def __init__(self, parentwidget, label = None): + self.parentwidget = parentwidget + import qt + qt.QHBox.__init__(self, parentwidget) + self.setMargin(4) + self.setSpacing(4) + if label != None: qt.QLabel(label, self) + def value(self): + return None + +class ListWidget(Widget): + def __init__(self, parentwidget, label): + import qt + global Widget + Widget.__init__(self, parentwidget, label) + self.combo = qt.QComboBox(self) + self.combo.setEditable(True) + self.setStretchFactor(self.combo,1) + def value(self): + return self.combo.currentText() + +class EditWidget(Widget): + def __init__(self, parentwidget, label): + import qt + global Widget + Widget.__init__(self, parentwidget, label) + self.edit = qt.QLineEdit(self) + self.setStretchFactor(self.edit,1) + def value(self): + return self.edit.text() + +class FileWidget(Widget): + def __init__(self, parentwidget, label, filtermask, openfiledialog = True): + self.filtermask = filtermask + self.openfiledialog = openfiledialog + import qt + global Widget + Widget.__init__(self, parentwidget, label) + self.edit = qt.QLineEdit(self) + self.setStretchFactor(self.edit,1) + btn = qt.QPushButton("...",self) + qt.QObject.connect(btn, qt.SIGNAL("clicked()"), self.btnClicked) + def btnClicked(self): + import qt + text = str( self.edit.text() ) + if self.openfiledialog: + filename = str( qt.QFileDialog.getOpenFileName(text, self.filtermask, self.parentwidget) ) + else: + filename = qt.QFileDialog.getSaveFileName(text, self.filtermask, self.parentwidget) + if filename != "": self.edit.setText( filename ) + def value(self): + return self.edit.text() + +class Samples: + + #################################################################################### + # KexiDB + + class KexiDB: + def __init__(self, parentwidget): + self.parentwidget = parentwidget + + class _ProjectWidget(FileWidget): + def __init__(self, parentwidget): + global FileWidget + FileWidget.__init__(self, parentwidget, "Project File:", "*.kexi *.kexis *.kexic;;*") + + class _DriverWidget(ListWidget): + def __init__(self, parentwidget): + global ListWidget + ListWidget.__init__(self, parentwidget, "Driver:") + import krosskexidb + for driver in krosskexidb.DriverManager().driverNames(): + self.combo.insertItem(driver) + + class _TableWidget(ListWidget): + def __init__(self, parentwidget): + global ListWidget + ListWidget.__init__(self, parentwidget, "Table:") + + class PrintDriverDetails: + """ Print a the list of available KexiDB drivers and print details about one of them. """ + name = "Details about a driver" + def __init__(self, parent): + self.widgets = { + "DriverName" : Samples.KexiDB._DriverWidget( parent.parentwidget ), + } + def getCode(self): + return ( + 'import krosskexidb', + 'drivermanager = krosskexidb.DriverManager()', + 'print "drivernames: %s" % drivermanager.driverNames()', + '', + 'driver = drivermanager.driver( \"{DriverName}\" )', + 'print "driver: {DriverName}"', + 'print "version=%s.%s" % (driver.versionMajor(),driver.versionMinor())', + 'print "mimetype=%s" % driver.fileDBDriverMimeType()', + 'print "filedriver=%s" % driver.isFileDriver()', + ) + + class ConnectWithFile: + """ Connect with a KexiDB database by using a Kexi Connection Project File. """ + name = "Connect with file" + def __init__(self, parent): + self.widgets = { + "ProjectFile" : Samples.KexiDB._ProjectWidget( parent.parentwidget ), + } + def getCode(self): + return ( + '# Import the KexiDB module.', + 'import krosskexidb', + 'drivermanager = krosskexidb.DriverManager()', + '', + '# Get the connectiondata from the project file.', + 'connectiondata = drivermanager.createConnectionDataByFile( "{ProjectFile}" )', + 'print "Connectiondata: %s" % connectiondata.serverInfoString()', + '', + '# Create the driver for the database backend.', + 'driver = drivermanager.driver( connectiondata.driverName() )', + '', + '# Create and establish the connection to the database.', + 'connection = driver.createConnection(connectiondata)', + 'if not connection.isConnected():', + ' if not connection.connect():', + ' raise "Failed to connect"', + '', + '# Open the database for usage.', + 'print "Databases: %s" % connection.databaseNames()', + 'if not connection.isDatabaseUsed():', + ' if not connection.useDatabase( connectiondata.databaseName() ):', + ' if not connection.useDatabase( connectiondata.fileName() ):', + ' raise "Failed to use database"', + '', + '# Print some infos.', + 'print "All tables: %s" % connection.allTableNames()', + 'print "Tables: %s" % connection.tableNames()', + 'print "Queries: %s" % connection.queryNames()', + ) + + class IterateThroughTable: + """ Iterate through a table within a connected KexiDB database. """ + name = "Iterate through table" + def __init__(self, parent): + self.widgets = { + "ProjectFile" : Samples.KexiDB._ProjectWidget( parent.parentwidget ), + "TableName" : Samples.KexiDB._TableWidget( parent.parentwidget ), + } + def getCode(self): + return ( + '# Import the KexiDB module.', + 'import krosskexidb', + 'drivermanager = krosskexidb.DriverManager()', + '', + '# Get the connectiondata from the project file.', + 'connectiondata = drivermanager.createConnectionDataByFile( "{ProjectFile}" )', + 'print "Connectiondata: %s" % connectiondata.serverInfoString()', + '', + '# Create the driver for the database backend.', + 'driver = drivermanager.driver( connectiondata.driverName() )', + '', + '# Create and establish the connection to the database.', + 'connection = driver.createConnection(connectiondata)', + 'if not connection.isConnected():', + ' if not connection.connect():', + ' raise "Failed to connect"', + '', + '# Open the database for usage.', + 'if not connection.isDatabaseUsed():', + ' if not connection.useDatabase( connectiondata.databaseName() ):', + ' if not connection.useDatabase( connectiondata.fileName() ):', + ' raise "Failed to use database"', + '', + '# Get the table and create a query for it.', + 'table = connection.tableSchema( \"{TableName}\" )', + 'query = table.query()', + '', + '# Create a cursor to walk through the records.', + 'cursor = connection.executeQuerySchema( query )', + 'if not cursor:', + ' raise "Failed to create cursor."', + '', + '# Iterate through the records.', + 'if not cursor.moveFirst():', + ' raise "The cursor has no records to read from."', + 'while not cursor.eof():', + ' for i in range( cursor.fieldCount() ):', + ' print "%s" % cursor.value(i)', + ' cursor.moveNext()', + ) + + #################################################################################### + # KSpread + + class KSpread: + def __init__(self, parentwidget): + self.parentwidget = parentwidget + + class _SheetWidget(ListWidget): + def __init__(self, parentwidget, label = "Sheet:"): + global ListWidget + ListWidget.__init__(self, parentwidget, label) + + try: + import krosskspreadcore + document = krosskspreadcore.get("KSpreadDocument") + for sheetname in document.sheetNames(): + self.combo.insertItem(sheetname) + except: + import traceback + trace = "".join( traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2]) ) + print trace + + class _CellsWidget(ListWidget): + def __init__(self, parentwidget): + global ListWidget + ListWidget.__init__(self, parentwidget, "Cells (col1:row1 - col2:row2):") + self.combo.insertItem( "1:1 - %s:%s" % (5,10) ) + self.combo.insertItem( "1:1 - %s:%s" % (256,256) ) + self.combo.insertItem( "1:1 - %s:%s" % (32767,32767) ) + def value(self): + return [ [ int(i) for i in item.split(':') ] for item in str( ListWidget.value(self) ).split('-') ] + + class _ValueWidget(EditWidget): + def __init__(self, parentwidget): + global EditWidget + EditWidget.__init__(self, parentwidget, "Value:") + self.edit.setText("Some text") + + class _ColorWidget(EditWidget): + def __init__(self, parentwidget,label,color): + global EditWidget + EditWidget.__init__(self, parentwidget, "%s (RGB):" % label) + self.edit.setText(color) + def value(self): + return "#%s" % EditWidget.value(self) + + class SetTextOfCells: + """ Set the text of the defined cells. """ + name = "Set text of cells" + def __init__(self, parent): + pass + self.widgets = { + "SheetName" : Samples.KSpread._SheetWidget( parent.parentwidget ), + "Cells" : Samples.KSpread._CellsWidget( parent.parentwidget ), + "Value" : Samples.KSpread._ValueWidget( parent.parentwidget ), + } + def getCode(self): + return ( + '# Import the KSpread module.', + 'import krosskspreadcore', + '', + '# Get the current document.', + 'document = krosskspreadcore.get("KSpreadDocument")', + '', + '# Get the sheet defined by the sheetname.', + 'sheet = document.sheetByName( \"{SheetName}\" )', + 'if not sheet:', + ' raise "No such sheet {SheetName} %s" % document.sheetNames()', + '', + '( (col1,row1),(col2,row2) ) = {Cells}', + 'for c in range(col1,col2):', + ' for r in range(row1,row2):', + ' cell = sheet.cell(c,r)', + ' print "cell c=%s r=%s v=%s" % (c,r,cell.value())', + ' cell.setText( \"{Value}\" )', + ) + + class SetColorsOfCells: + """ Set the colors of the defined cells. """ + name = "Set colors of cells" + def __init__(self, parent): + pass + self.widgets = { + "SheetName" : Samples.KSpread._SheetWidget( parent.parentwidget), + "Cells" : Samples.KSpread._CellsWidget( parent.parentwidget ), + "TextColor" : Samples.KSpread._ColorWidget( parent.parentwidget, "Textcolor", "ff0000" ), + "BackgroundColor" : Samples.KSpread._ColorWidget( parent.parentwidget, "Backgroundcolor", "c0c0c0" ), + } + def getCode(self): + return ( + '# Import the KSpread module.', + 'import krosskspreadcore', + '', + '# Get the current document.', + 'document = krosskspreadcore.get("KSpreadDocument")', + '', + '# Get the sheet defined by the sheetname.', + 'sheet = document.sheetByName( \"{SheetName}\" )', + 'if not sheet:', + ' raise "No such sheet {SheetName} %s" % document.sheetNames()', + '', + '( (col1,row1),(col2,row2) ) = {Cells}', + 'for c in range(col1,col2):', + ' for r in range(col1,col2):', + ' cell = sheet.cell(c,r)', + ' cell.setTextColor( \"{TextColor}\" )', + ' cell.setBackgroundColor( \"{BackgroundColor}\" )', + ) + + class IterateThroughCellsWithContent: + """ Iterate over all cells in a sheet that have content (aka that are not empty). """ + name = "Iterate through cells" + def __init__(self, parent): + pass + self.widgets = { + "SheetName" : Samples.KSpread._SheetWidget( parent.parentwidget ), + } + def getCode(self): + return ( + '# Import the KSpread module.', + 'import krosskspreadcore', + '', + '# Get the current document.', + 'document = krosskspreadcore.get("KSpreadDocument")', + '', + '# Get the sheet defined by the sheetname.', + 'sheet = document.sheetByName( \"{SheetName}\" )', + 'if not sheet:', + ' raise "No such sheet {SheetName} %s" % document.sheetNames()', + '', + '# Iterate through the cells that have content (aka that are not empty).', + 'cell = sheet.firstCell()', + 'while cell:', + ' print "col=%s row=%s value=%s" % (cell.column(),cell.row(),cell.value())', + ' cell = cell.nextCell()', + ) + + class PrintSheetDetails: + """ Print details about the current sheet. """ + name = "Details about a sheet" + def __init__(self, parent): + self.widgets = { + "SheetName" : Samples.KSpread._SheetWidget( parent.parentwidget ), + } + def getCode(self): + return ( + '# Import the KSpread module.', + 'import krosskspreadcore', + '', + '# Get the current document.', + 'document = krosskspreadcore.get("KSpreadDocument")', + '', + '# Get the sheet defined by the sheetname.', + 'sheet = document.sheetByName( \"{SheetName}\" )', + 'if not sheet:', + ' raise "No such sheet {SheetName} %s" % document.sheetNames()', + '', + 'print "name=%s" % sheet.name()', + 'print "maxcolumns=%s maxrows=%s" % (sheet.maxColumn(),sheet.maxRow())', + ) + + class LoadDocFromNativeXML: + """ Load the document from a native XML file. """ + name = "Load document from native XML File" + def __init__(self, parent): + global FileWidget + self.widgets = { + "FileName" : FileWidget( parent.parentwidget, "XML File:", "*.xml;;*" ), + } + def getCode(self): + return ( + '# Import the PyQt module.', + 'import qt', + '', + 'def loadFile(filename):', + ' # Import the krosskspreadcore module.', + ' import krosskspreadcore', + ' # Try to read the file.', + ' try:', + ' file = open(filename, "r")', + ' xml = file.read()', + ' file.close()', + ' except IOError, (errno, strerror):', + ' qt.QMessageBox.critical(self,"Error","<qt>Failed to read file %s<br><br>%s</qt>" % (filename,strerror))', + ' return', + '', + ' # Get the current document.', + ' document = krosskspreadcore.get("KSpreadDocument")', + ' # Load the document from the native XML string.', + ' ok = document.loadNativeXML( xml )', + '', + '# Show the openfile dialog', + 'filename = "{FileName}"', + 'openfilename = qt.QFileDialog.getOpenFileName(filename,"*.xml;;*", self)', + 'if str(openfilename) != "":', + ' loadFile( openfilename )', + ) + + class SaveDocToNativeXML: + """ Save the document to a native XML file. """ + name = "Save document to native XML File" + def __init__(self, parent): + global FileWidget + self.widgets = { + "FileName" : FileWidget( parent.parentwidget, "XML File:", "*.xml;;*", False ), + } + def getCode(self): + return ( + '# Import the PyQt module.', + 'import qt', + '', + 'def saveFile(filename):', + ' # Import the krosskspreadcore module.', + ' import krosskspreadcore', + ' # Try to open the file for writting.', + ' try:', + ' file = open(filename, "w")', + ' except IOError, (errno, strerror):', + ' qt.QMessageBox.critical(self,"Error","<qt>Failed to create file %s<br><br>%s</qt>" % (filename,strerror))', + ' return', + ' # Get the current document.', + ' document = krosskspreadcore.get("KSpreadDocument")', + ' # Get the native XML string.', + ' xml = document.saveNativeXML()', + ' # Write the XML string to the file.', + ' file.write( xml )', + ' # Close the file.', + ' file.close()', + '', + '# Show the savefile dialog', + 'filename = "{FileName}"', + 'savefilename = qt.QFileDialog.getSaveFileName(filename,"*.xml;;*", self)', + 'if str(savefilename) != "":', + ' saveFile( savefilename )', + ) + + class CopySheets: + """ Copy the text-content from one sheet to another. """ + name = "Copy sheets" + def __init__(self, parent): + self.widgets = { + "SourceSheet" : Samples.KSpread._SheetWidget( parent.parentwidget, "Source sheet:" ), + "TargetSheet" : Samples.KSpread._SheetWidget( parent.parentwidget, "Target sheet:" ), + } + def getCode(self): + return ( + '# Import the KSpread module.', + 'import krosskspreadcore', + '# Get the current document.', + 'document = krosskspreadcore.get("KSpreadDocument")', + '# Get the source sheet.', + 'fromsheet = document.sheetByName( "{SourceSheet}" )', + 'if not fromsheet: raise "No such sheet {SourceSheet} %s" % document.sheetNames()', + '# Get the target sheet.', + 'tosheet = document.sheetByName( "{TargetSheet}" )', + 'if not fromsheet: raise "No such sheet {TargetSheet} %s" % document.sheetNames()', + '# Copy the cells.', + 'fromcell = fromsheet.firstCell()', + 'while fromcell:', + ' tocell = tosheet.cell( fromcell.column(), fromcell.row() )', + ' tocell.setText( fromcell.text() )', + ' #tocell.setValue( fromcell.value() )', + ' fromcell = fromcell.nextCell()', + ) + + class LoadSheetFromCSV: + """ Load the content of a CSV file into a KSpread sheet. """ + name = "Load data from CSV file into sheet" + def __init__(self, parent): + self.widgets = { + "Sheet" : Samples.KSpread._SheetWidget( parent.parentwidget ), + "FileName" : FileWidget( parent.parentwidget, "CSV File:", "*.csv;;*", True ), + } + def getCode(self): + return ( + '# Import the KSpread module.', + 'import krosskspreadcore', + '# Get the current document and the sheet.', + 'document = krosskspreadcore.get("KSpreadDocument")', + 'sheet = document.sheetByName( "{Sheet}" )', + 'if not sheet: raise "No such sheet {Sheet} %s" % document.sheetNames()', + '', + 'filename = "{FileName}"', + 'try:', + ' file = open(filename, "r")', + 'except IOError:', + ' raise "Failed to open CSV File: %s" % filename', + '', + 'import csv', + 'csvparser = csv.reader(file)', + 'row = 1', + 'while True:', + ' try:', + ' record = csvparser.next()', + ' except StopIteration:', + ' break', + ' col = 1', + ' for item in record:', + ' sheet.cell(col,row).setText( item )', + ' col += 1', + ' row += 1', + 'file.close()', + ) + + class SaveSheetToCSV: + """ Save the content of a KSpread sheet into a CSV file. """ + name = "Save data from a sheet into a CSV file" + def __init__(self, parent): + self.widgets = { + "Sheet" : Samples.KSpread._SheetWidget( parent.parentwidget ), + "FileName" : FileWidget( parent.parentwidget, "CSV File:", "*.csv;;*", False ), + } + def getCode(self): + return ( + 'filename = "{FileName}"', + 'try:', + ' file = open(filename, "w")', + 'except IOError:', + ' raise "Failed to write CSV File: %s" % filename', + '# Prepare CSV-writer', + 'import csv', + 'csvwriter = csv.writer(file)', + '# Import the KSpread module.', + 'import krosskspreadcore', + '# Get the current document and the sheet.', + 'document = krosskspreadcore.get("KSpreadDocument")', + 'sheet = document.sheetByName( "{Sheet}" )', + 'if not sheet: raise "No such sheet {Sheet} %s" % document.sheetNames()', + '# Iterate over the cells.', + 'cell = sheet.firstCell()', + 'record = []', + 'while cell:', + ' record.append( cell.text() )', + ' if cell.column() == 1 or not cell.nextCell():', + ' csvwriter.writerow( record )', + ' record = []', + ' cell = cell.nextCell()', + 'file.close()', + ) + + + #################################################################################### + # PyQt + + class PyQt: + def __init__(self, parentwidget): + self.parentwidget = parentwidget + + class OpenFileDialog: + """ Show the usage of the openfile dialog with QFileDialog. """ + name = "Open File Dialog" + def __init__(self, parent): + pass + self.widgets = { + "FileName" : FileWidget( parent.parentwidget, "Open File:", "*.txt *.html;;*" ), + } + def getCode(self): + return ( + 'import qt', + 'openfilename = qt.QFileDialog.getOpenFileName("{FileName}","*.txt *.html;;*", self)', + 'print "openfile=%s" % openfilename', + ) + + class SaveFileDialog: + """ Show the usage of the savefile dialog with QFileDialog. """ + name = "Save File Dialog" + def __init__(self, parent): + pass + self.widgets = { + "FileName" : FileWidget( parent.parentwidget, "Save File:", "*.txt *.html;;*", False ), + } + def getCode(self): + return ( + 'import qt', + 'savefilename = qt.QFileDialog.getSaveFileName("{FileName}","*.txt *.html;;*", self)', + 'print "savefile=%s" % savefilename', + ) + + class CustomDialog: + """ Show a custom dialog that inherits a QDialog. """ + name = "Custom Dialog" + def __init__(self, parent): + pass + self.widgets = { + } + def getCode(self): + return ( + 'import qt', + '', + 'class MyDialog(qt.QDialog):', + ' def __init__(self, parent):', + ' import qt', + ' qt.QDialog.__init__(self, parent, "MyDialog", 1, qt.Qt.WDestructiveClose)', + ' self.setCaption("My Dialog")', + ' btn = qt.QPushButton("Click me",self)', + ' qt.QObject.connect(btn, qt.SIGNAL("clicked()"), self.buttonClicked)', + ' def buttonClicked(self):', + ' import qt', + ' qt.QMessageBox.information(self, "The Caption", "This is the message string.")', + '', + 'dialog = MyDialog(self)', + 'dialog.exec_loop()', + ) + + class InputDialog: + """ Show how to use a QInputDialog. """ + name = "Input Dialog" + def __init__(self, parent): + global EditWidget + self.widgets = { + "Caption" : EditWidget( parent.parentwidget, "Caption" ), + "Message" : EditWidget( parent.parentwidget, "Message" ), + } + def getCode(self): + return ( + 'import qt', + '', + 'text, ok = qt.QInputDialog.getText("{Caption}", "{Message}", qt.QLineEdit.Normal, "")', + 'if ok:', + ' print "Text defined: %s" % text', + 'else:', + ' print "Dialog aborted."', + ) + + #################################################################################### + # DCOP + + class DCOP: + def __init__(self, parentwidget): + self.parentwidget = parentwidget + + class PrintClipboard: + """ Print the content from the clipper via DCOP. """ + name = "Clipboard content" + def __init__(self, parent): + self.widgets = { + } + def getCode(self): + return ( + 'import qt, kdecore, dcop, dcopext', + 'dcopclient = kdecore.KApplication.dcopClient()', + 'apps = [ app for app in dcopclient.registeredApplications() if str(app).startswith("klipper") ]', + 'd = dcopext.DCOPApp(apps[0], dcopclient)', + 'result,typename,data = d.appclient.call(apps[0],"klipper","getClipboardContents()","")', + 'ds = qt.QDataStream(data, qt.IO_ReadOnly)', + 'print "Clipboard content:\\n%s" % kdecore.dcop_next(ds, "QString")', + ) + + class AmarokCollectionInfos: + """ Fetch some collection informations from the amarok collection via DCOP. """ + name = "amarok collection infos" + def __init__(self, parent): + self.widgets = { + } + def getCode(self): + return ( + 'import qt, kdecore, dcop, dcopext', + '', + 'dcopclient = kdecore.KApplication.dcopClient()', + 'apps = [ app for app in dcopclient.registeredApplications() if str(app).startswith("amarok") ]', + 'app = apps[0]', + 'd = dcopext.DCOPApp(app, dcopclient)', + '', + 'def dataToList(data, types = []):', + ' import qt, kdecore', + ' ds = qt.QDataStream(data, qt.IO_ReadOnly)', + ' return [ kdecore.dcop_next(ds, t) for t in types ]', + '', + 'for funcname in ["totalAlbums","totalArtists","totalCompilations","totalGenres","totalTracks"]:', + ' result,replytype,replydata = d.appclient.call("amarok", "collection", "%s()" % funcname,"")', + ' print "%s: %s" % ( funcname, dataToList(replydata,["int"])[0] )', + ) + + class KopeteContacts: + """ Print the names of all contacts Kopete knows via DCOP. """ + name = "Kopete contacts" + def __init__(self, parent): + self.widgets = { + } + def getCode(self): + return ( + 'import qt, kdecore, dcop, dcopext', + '', + 'dcopclient = kdecore.KApplication.dcopClient()', + 'apps = [ app for app in dcopclient.registeredApplications() if str(app).startswith("kopete") ]', + 'app = apps[0]', + 'd = dcopext.DCOPApp(app, dcopclient)', + '', + '(state,rtype,rdata) = d.appclient.call("kopete", "KopeteIface", "contacts()","")', + 'if not state: raise "Failed to call the kopete contacts-function"', + '', + 'ds = qt.QDataStream(rdata.data(), qt.IO_ReadOnly)', + 'sl = kdecore.dcop_next (ds, "QStringList")', + 'print "contacts=%s" % [ str(s) for s in sl ]', + ) + + class KWordSelectedText: + """ Get the selected text from a KWord instance via DCOP. """ + name = "KWord selected text" + def __init__(self, parent): + self.widgets = { + } + def getCode(self): + return ( + 'import qt, kdecore, dcop, dcopext', + '', + 'def dataToList(data, types = []):', + ' import qt, kdecore', + ' ds = qt.QDataStream(data, qt.IO_ReadOnly)', + ' return [ kdecore.dcop_next(ds, t) for t in types ]', + 'def listToData(listdict):', + ' import qt, kdecore', + ' ba= qt.QByteArray()', + ' ds = qt.QDataStream(ba, qt.IO_WriteOnly)', + ' for (typename,value) in listdict:', + ' kdecore.dcop_add (ds, value, typename)', + ' return ba', + '', + '# Get the KWord DCOP client.', + 'dcopclient = kdecore.KApplication.dcopClient()', + 'apps = [ app for app in dcopclient.registeredApplications() if str(app).startswith("kword") ]', + 'if len(apps) < 1: raise "No KWord instance is running. Please start KWord before!"', + 'appname = apps[0]', + 'd = dcopext.DCOPApp(appname, dcopclient)', + '', + '# Call the getDocuments() function.', + '(state,rtype,rdata) = d.appclient.call(appname, "KoApplicationIface", "getDocuments()","")', + 'if not state: raise "%s: Failed to call getDocuments-function" % appname', + 'documents = dataToList(rdata,["QValueList<DCOPRef>"])[0]', + 'print "documents=%s" % [ str( doc.obj() ) for doc in documents ]', + 'document = documents[0] # Let\'s just take the first document.', + '', + '# Get the frameset.', + 'ba = listToData( [ ("int",0) ] )', + '(state,rtype,rdata) = d.appclient.call(appname, document.obj(), "textFrameSet(int)", ba)', + 'if not state: raise "%s: Failed to call frameSet-function" % appname', + 'frameset = dataToList( rdata,["DCOPRef"] )[0] # Let\'s just take the first textframe.', + '', + '# Get the selected text.', + '(state,rtype,rdata) = d.appclient.call(appname, frameset.obj(), "selectedText()", "")', + 'print "Selected Text: %s" % dataToList( rdata,["QString"] )[0]', + ) + +#################################################################################### +# Dialog implementations. + +class SampleDialog(qt.QDialog): + def __init__(self, parent, sampleclazz, samplechildclazz): + import qt + qt.QDialog.__init__(self, parent, "SampleDialog", 1) + + layout = qt.QVBoxLayout(self) + box = qt.QVBox(self) + box.setMargin(4) + box.setSpacing(10) + layout.addWidget(box) + + self.scrollview = qt.QScrollView(box) + self.scrollview.setResizePolicy(qt.QScrollView.AutoOne) + #self.scrollview.setFrameStyle(qt.QFrame.NoFrame); + self.scrollview.setResizePolicy(qt.QScrollView.AutoOneFit); + self.scrollview.viewport().setPaletteBackgroundColor(self.paletteBackgroundColor()) + mainbox = qt.QVBox( self.scrollview.viewport() ) + mainbox.setMargin(6) + mainbox.setSpacing(6) + desclabel = qt.QLabel(mainbox) + qt.QFrame(mainbox).setFrameStyle( qt.QFrame.HLine | qt.QFrame.Sunken ) + + self.sample = sampleclazz( mainbox ) + self.samplechild = samplechildclazz( self.sample ) + + desclabel.setText( "<qt>%s</qt>" % self.samplechild.__doc__ ) + mainbox.setStretchFactor(qt.QWidget(mainbox), 1) + mainbox.show() + self.scrollview.addChild(mainbox) + + btnbox = qt.QHBox(box) + btnbox.setMargin(6) + btnbox.setSpacing(6) + okbtn = qt.QPushButton(btnbox) + okbtn.setText("Ok") + qt.QObject.connect(okbtn, qt.SIGNAL("clicked()"), self.okClicked) + cancelbtn = qt.QPushButton(btnbox) + cancelbtn.setText("Cancel") + qt.QObject.connect(cancelbtn, qt.SIGNAL("clicked()"), self.close) + + self.setCaption(self.samplechild.name) + box.setMinimumSize(qt.QSize(500,340)) + + def okClicked(self): + self.code = self.samplechild.getCode() + self.close() + + def getCode(self): + if not hasattr(self,"code"): return None + code = "\n".join( self.code ) + for widgetname in self.samplechild.widgets.keys(): + print ".............. %s" % widgetname + widget = self.samplechild.widgets[widgetname] + value = widget.value() + if value != None: + code = code.replace("{%s}" % widgetname, str(value)) + return code + +class MainDialog(qt.QDialog): + def __init__(self, scriptpath, parent): + self.scriptpath = scriptpath + if not hasattr(__main__,"scripteditorfilename"): + __main__.scripteditorfilename = self.getFileName("myscript.py") + + import krosskspreadcore + self.doc = krosskspreadcore.get("KSpreadDocument") + + import os, qt + qt.QDialog.__init__(self, parent, "MainDialog", 1, qt.Qt.WDestructiveClose) + self.setCaption("Script Editor") + + layout = qt.QVBoxLayout(self) + box = qt.QVBox(self) + box.setMargin(4) + box.setSpacing(10) + layout.addWidget(box) + + menu = qt.QMenuBar(box) + + splitter = qt.QSplitter(box) + splitter.setOrientation(qt.Qt.Vertical) + + self.scripttext = qt.QMultiLineEdit(splitter) + self.scripttext.setWordWrap( qt.QTextEdit.NoWrap ) + self.scripttext.setTextFormat( qt.Qt.PlainText ) + qt.QObject.connect(self.scripttext, qt.SIGNAL("cursorPositionChanged(int,int)"),self.cursorPositionChanged) + + self.console = qt.QTextBrowser(splitter) + splitter.setResizeMode(self.console, qt.QSplitter.KeepSize) + + statusbar = qt.QStatusBar(box) + self.messagestatus = qt.QLabel(statusbar) + statusbar.addWidget(self.messagestatus,1) + self.cursorstatus = qt.QLabel(statusbar) + statusbar.addWidget(self.cursorstatus) + self.cursorPositionChanged() + + box.setMinimumSize( qt.QSize(680,540) ) + + filemenu = qt.QPopupMenu(menu) + menu.insertItem("&File", filemenu) + + newaction = qt.QAction("New", qt.QKeySequence("CTRL+N"), self) + qt.QObject.connect(newaction, qt.SIGNAL("activated()"), self.newFile) + newaction.addTo(filemenu) + + openaction = qt.QAction("Open...", qt.QKeySequence("CTRL+O"), self) + qt.QObject.connect(openaction, qt.SIGNAL("activated()"), self.openFileAs) + openaction.addTo(filemenu) + + saveaction = qt.QAction("Save", qt.QKeySequence("CTRL+S"), self) + qt.QObject.connect(saveaction, qt.SIGNAL("activated()"), self.saveFile) + saveaction.addTo(filemenu) + + saveasaction = qt.QAction("Save as...", qt.QKeySequence("CTRL+A"), self) + qt.QObject.connect(saveasaction, qt.SIGNAL("activated()"), self.saveFileAs) + saveasaction.addTo(filemenu) + + filemenu.insertSeparator() + + quitaction = qt.QAction("Quit", qt.QKeySequence("CTRL+Q"), self) + qt.QObject.connect(quitaction, qt.SIGNAL("activated()"), self.close) + quitaction.addTo(filemenu) + + editmenu = qt.QPopupMenu(menu) + menu.insertItem("&Edit", editmenu) + + undoaction = qt.QAction("Undo", qt.QKeySequence("CTRL+Z"), self) + qt.QObject.connect(undoaction, qt.SIGNAL("activated()"), self.scripttext.undo) + undoaction.addTo(editmenu) + + redoaction = qt.QAction("Redo", qt.QKeySequence("CTRL+Shift+Z"), self) + qt.QObject.connect(redoaction, qt.SIGNAL("activated()"), self.scripttext.redo) + redoaction.addTo(editmenu) + + editmenu.insertSeparator() + + cutaction = qt.QAction("Cut", qt.QKeySequence("CTRL+X"), self) + qt.QObject.connect(cutaction, qt.SIGNAL("activated()"), self.scripttext.cut) + cutaction.addTo(editmenu) + + copyaction = qt.QAction("Copy", qt.QKeySequence("CTRL+C"), self) + qt.QObject.connect(copyaction, qt.SIGNAL("activated()"), self.scripttext.copy) + copyaction.addTo(editmenu) + + pasteaction = qt.QAction("Paste", qt.QKeySequence("CTRL+V"), self) + qt.QObject.connect(pasteaction, qt.SIGNAL("activated()"), self.scripttext.paste) + pasteaction.addTo(editmenu) + + clearaction = qt.QAction("Clear", qt.QKeySequence("CTRL+Shift+X"), self) + qt.QObject.connect(clearaction, qt.SIGNAL("activated()"), self.scripttext.clear) + clearaction.addTo(editmenu) + + editmenu.insertSeparator() + + selallaction = qt.QAction("Select All", 0, self) + qt.QObject.connect(selallaction, qt.SIGNAL("activated()"), self.scripttext.selectAll) + selallaction.addTo(editmenu) + + scriptmenu = qt.QPopupMenu(menu) + menu.insertItem("&Script", scriptmenu) + + compileaction = qt.QAction("Compile", qt.QKeySequence("F9"), self) + qt.QObject.connect(compileaction, qt.SIGNAL("activated()"), self.compileScript) + compileaction.addTo(scriptmenu) + + executeaction = qt.QAction("Execute", qt.QKeySequence("F10"), self) + qt.QObject.connect(executeaction, qt.SIGNAL("activated()"), self.executeScript) + executeaction.addTo(scriptmenu) + + self.samplemenu = qt.QPopupMenu(menu) + menu.insertItem("&Samples", self.samplemenu) + itemid = 500 + global Samples + for samplename in dir(Samples): + if samplename.startswith("_"): continue + itemid += 1 + menu = qt.QPopupMenu(self.samplemenu) + qt.QObject.connect(menu, qt.SIGNAL("activated(int)"), self.sampleActivated) + self.samplemenu.insertItem(samplename, menu, -1, self.samplemenu.count() - 1) + attr = getattr(Samples,samplename) + for a in dir(attr): + if a.startswith("_"): continue + itemid += 1 + child = getattr(attr,a) + itemid = menu.insertItem(child.name, itemid) + menu.setWhatsThis(itemid,"%s/%s" % (samplename,a)) + + if os.path.exists(__main__.scripteditorfilename): + self.openFile(__main__.scripteditorfilename) + + def getFileName(self, filename): + import os + try: + homepath = os.getenv("HOME") + if not homepath: + import pwd + user = os.getenv("USER") or os.getenv("LOGNAME") + if not user: + pwent = pwd.getpwuid(os.getuid()) + else: + pwent = pwd.getpwnam(user) + homepath = pwent[6] + except (KeyError, ImportError): + homepath = os.curdir + return os.path.join(homepath, filename) + + def cursorPositionChanged(self,para = 0,pos = 0): + self.cursorstatus.setText( "Line: %s Col: %s" % (para+1,pos+1) ) + + def sampleActivated(self, index): + global Samples + sampleid = str( self.sender().whatsThis(index) ) + sampleidlist = sampleid.split('/') + sampleclazz = getattr( Samples,sampleidlist[0] ) + samplechildclazz = getattr( sampleclazz, sampleidlist[1] ) + + global SampleDialog + dialog = SampleDialog(self, sampleclazz, samplechildclazz) + dialog.exec_loop() + code = dialog.getCode() + if code != None: + self.scripttext.append( code ) + + def execCode(self,function): + import sys, StringIO + codeOut = StringIO.StringIO() + codeErr = StringIO.StringIO() + sys.stdout = codeOut + sys.stderr = codeErr + + try: + function(self) + except: + import traceback + trace = "".join( traceback.format_exception(sys.exc_info()[0],sys.exc_info()[1],sys.exc_info()[2]) ) + sys.stderr.write(trace) + try: + # this is a bit tricky. we need to go to steps back to know where the exception really happened. + tb = sys.exc_info()[2] + while hasattr(tb,"tb_next") and tb.tb_next: + tb = tb.tb_next + lineno = tb.tb_lineno + print "EXCEPTION: lineno=%s" % lineno + self.scripttext.setCursorPosition( lineno - 1, 0 ) + except: + pass + + sys.stdout = sys.__stdout__ + sys.stderr = sys.__stderr__ + + s = codeErr.getvalue() + if s: + print "ERROR:\n%s\n" % s + self.console.append(s) + + s = codeOut.getvalue() + if s: + print s + self.console.append(s) + + codeOut.close() + codeErr.close() + + def compileScript(self): + self.console.clear() + code = str( self.scripttext.text() ) + def docompile(self): + compile(code, __main__.scripteditorfilename, 'exec') + self.execCode(docompile) + self.console.append("<b>Compiled!</b>") + + def executeScript(self): + self.console.clear() + def doexecute(self): + code = str( self.scripttext.text() ) + exec code in globals(), locals() + self.execCode(doexecute) + self.console.append("<b>Execution done!</b>") + + def newFile(self): + self.console.clear() + #if qt.QMessageBox.warning(self,"Remove?","Remove the selected item?",qt.QMessageBox.Yes,qt.QMessageBox.Cancel) != qt.QMessageBox.Yes: + self.scripttext.clear() + + def openFile(self, filename): + __main__.scripteditorfilename = None + try: + file = open(filename, "r") + self.scripttext.setText( str( file.read() ) ) + file.close() + __main__.scripteditorfilename = filename + except IOError, (errno, strerror): + qt.QMessageBox.critical(self,"Error","<qt>Failed to open script file \"%s\"<br><br>%s</qt>" % (filename,strerror)) + + def openFileAs(self): + import qt + self.console.clear() + filename = str( qt.QFileDialog.getOpenFileName(__main__.scripteditorfilename,"*.py;;*", self) ) + if filename == "": return + self.openFile(filename) + + def saveFile(self): + try: + file = open(__main__.scripteditorfilename, "w") + file.write( str( self.scripttext.text() ) ) + file.close() + except IOError, (errno, strerror): + qt.QMessageBox.critical(self,"Error","<qt>Failed to open script file \"%s\"<br><br>%s</qt>" % (__main__.scripteditorfilename,strerror)) + + def saveFileAs(self): + import qt + filename = str( qt.QFileDialog.getSaveFileName(__main__.scripteditorfilename,"*.py;;*", self) ) + if filename == "": return + __main__.scripteditorfilename = filename + self.saveFile() + +#################################################################################### +# Show the main dialog. + +if __name__ == "__main__": + scriptpath = os.getcwd() + qtapp = qt.QApplication(sys.argv) +else: + scriptpath = os.path.dirname(__name__) + qtapp = qt.qApp + +dialog = MainDialog(scriptpath, qtapp.mainWidget()) +dialog.exec_loop() diff --git a/kspread/plugins/scripting/scripts/scripteditor/ScriptEditor.rc b/kspread/plugins/scripting/scripts/scripteditor/ScriptEditor.rc new file mode 100755 index 00000000..8be0fe8d --- /dev/null +++ b/kspread/plugins/scripting/scripts/scripteditor/ScriptEditor.rc @@ -0,0 +1,9 @@ +<KrossScripting> + <ScriptAction + name="scripteditor" + version="3" + text="Script Editor" + icon="edit" + interpreter="python" + file="ScriptEditor.py" /> +</KrossScripting> |