From 46f817437df4dcf62921f91bec18e0311779233f Mon Sep 17 00:00:00 2001 From: ishmal Date: Sun, 15 Apr 2007 01:18:55 +0000 Subject: [PATCH] Rearrange bindings to use PyCXX --- src/extension/script/InkscapePython.cpp | 355 +++++++++++++++++++++--- src/extension/script/InkscapePython.h | 18 +- src/extension/script/InkscapeScript.cpp | 10 +- 3 files changed, 337 insertions(+), 46 deletions(-) diff --git a/src/extension/script/InkscapePython.cpp b/src/extension/script/InkscapePython.cpp index f7cfe81db..186d7c664 100644 --- a/src/extension/script/InkscapePython.cpp +++ b/src/extension/script/InkscapePython.cpp @@ -21,6 +21,12 @@ #include +#include +#include +#include + +//only for sp_help_about() +#include "help.h" namespace Inkscape { @@ -30,46 +36,152 @@ namespace Script { + + //######################################################################## -//# I N K S C A P E +//# D I A L O G M A N A G E R //######################################################################## class PyDialogManager : public Py::PythonExtension { public: + PyDialogManager(Inkscape::UI::Dialog::DialogManager *dm) : + dialogManager(dm) + { + } + + virtual ~PyDialogManager() + { + } + + virtual Py::Object getattr(const char *name) + { + /* + if (strcmp(name, "activeDesktop")==0) + { + PyDesktop obj(SP_ACTIVE_DESKTOP); + return obj; + } + */ + return getattr_methods(name); + } + + virtual Py::Object showAbout(const Py::Tuple &args) + { + sp_help_about(); + return Py::Nothing(); + } + + + static void init_type() + { + behaviors().name("DialogManager"); + behaviors().doc("dialogManager objects: "); + behaviors().supportRepr(); + behaviors().supportGetattr(); + add_varargs_method("showAbout", &PyDialogManager::showAbout, + "Shows a silly dialog"); + } private: + Inkscape::UI::Dialog::DialogManager *dialogManager; }; +//######################################################################## +//# D E S K T O P +//######################################################################## + class PyDesktop : public Py::PythonExtension { public: + PyDesktop(SPDesktop *dt) : desktop(dt) + { + } + + virtual ~PyDesktop() + { + } + + virtual Py::Object getattr(const char *name) + { + if (strcmp(name, "dialogManager")==0) + { + Py::Object obj(Py::asObject( + new PyDialogManager(desktop->_dlg_mgr))); + return obj; + } + return getattr_methods(name); + } + + static void init_type() + { + behaviors().name("Desktop"); + behaviors().doc("desktop objects: dialogManager"); + behaviors().supportRepr(); + behaviors().supportGetattr(); + } + private: + SPDesktop *desktop; + }; +//######################################################################## +//# D O C U M E N T +//######################################################################## + + class PyDocument : public Py::PythonExtension { public: + PyDocument(SPDocument *doc) : document(doc) + { + } + virtual ~PyDocument() + { + } + + virtual Py::Object getattr(const char *name) + { + return getattr_methods(name); + } + + + static void init_type() + { + behaviors().name("Document"); + behaviors().doc("document objects: "); + behaviors().supportRepr(); + behaviors().supportGetattr(); + } private: + SPDocument *document; }; + + +//######################################################################## +//# I N K S C A P E +//######################################################################## + + class PyInkscape : public Py::PythonExtension { public: @@ -88,12 +200,15 @@ public: { if (strcmp(name, "activeDesktop")==0) { + Py::Object obj(Py::asObject( + new PyDesktop(SP_ACTIVE_DESKTOP))); + return obj; } else if (strcmp(name, "activeDocument")==0) { - } - else if (strcmp(name, "dialogManager")==0) - { + Py::Object obj(Py::asObject( + new PyDocument(SP_ACTIVE_DOCUMENT))); + return obj; } return getattr_methods(name); } @@ -101,15 +216,25 @@ public: virtual Py::Object exit(const Py::Tuple &args) { //exit(); + return Py::Nothing(); //like a void + } + + virtual Py::Object hello(const Py::Tuple &args) + { + //exit(); + //throw Py::RuntimeError("some error message"); + return Py::String("Hello, world!"); } static void init_type() { - behaviors().name("inkscape"); - behaviors().doc("inkscape objects: activeDesktop activeDocument dialogManager"); + behaviors().name("Inkscape"); + behaviors().doc("inkscape objects: activeDesktop activeDocument"); behaviors().supportRepr(); behaviors().supportGetattr(); + add_varargs_method("hello", &PyInkscape::hello, + "Does a hello, world"); add_varargs_method("exit", &PyInkscape::exit, "exit from the current application"); } @@ -124,67 +249,231 @@ private: //######################################################################## -//# M A I N +//# O U T P U T S //######################################################################## +static InkscapePython *inkscapePython = NULL; -bool InkscapePython::initialize() + +class PyStdOut : public Py::PythonExtension { - if (initialized) - return true; +public: - Py_Initialize(); - - + PyStdOut() + { + } + + virtual ~PyStdOut() + { + } + + virtual Py::Object write(const Py::Tuple &args) + { + g_message("PyStdOut"); + if (inkscapePython) + { + for(unsigned int i=0 ; iwriteStdOut(str.as_std_string()); + } + } + return Py::Nothing(); + } - initialized = true; - return true; -} + static void init_type() + { + behaviors().name("PyStdOut"); + add_varargs_method("write", &PyStdOut::write, + "redirects stdout"); + } -/* +}; + + + + +class PyStdErr : public Py::PythonExtension +{ +public: + + PyStdErr() + { + } + + virtual ~PyStdErr() + { + } + + + virtual Py::Object write(const Py::Tuple &args) + { + g_message("PyStdErr"); + if (inkscapePython) + { + for(unsigned int i=0 ; iwriteStdErr(str.as_std_string()); + } + } + return Py::Nothing(); + } + + static void init_type() + { + behaviors().name("PyStdErr"); + + add_varargs_method("write", &PyStdErr::write, + "redirects stderr"); + } + + +}; + + + +//######################################################################## +//# M O D U L E +//######################################################################## + + + +class PyInkscapeModule : public Py::ExtensionModule +{ +public: + PyInkscapeModule() + : Py::ExtensionModule( "PyInkscapeModule" ) + { + //# Init our module's classes + PyInkscape::init_type(); + PyDocument::init_type(); + PyDesktop::init_type(); + PyDialogManager::init_type(); + PyStdOut::init_type(); + PyStdErr::init_type(); + + add_varargs_method("getInkscape", + &PyInkscapeModule::getInkscape, "returns global inkscape app"); + add_varargs_method("getStdOut", + &PyInkscapeModule::getStdOut, "gets redirected output"); + add_varargs_method("getStdErr", + &PyInkscapeModule::getStdErr, "gets redirected output"); + + initialize( "main Inkscape module" ); + } + + virtual ~PyInkscapeModule() + { + } + + virtual Py::Object getInkscape(const Py::Tuple &args) + { + Py::Object obj(Py::asObject(new PyInkscape())); + return obj; + } + virtual Py::Object getStdOut(const Py::Tuple &args) + { + Py::Object obj(Py::asObject(new PyStdOut())); + return obj; + } + virtual Py::Object getStdErr(const Py::Tuple &args) + { + Py::Object obj(Py::asObject(new PyStdErr())); + return obj; + } + + +}; + + + +//######################################################################## +//# M A I N +//######################################################################## + + + + +/** * Interpret an in-memory string */ bool InkscapePython::interpretScript(const Glib::ustring &script, Glib::ustring &output, Glib::ustring &error) { - if (!initialize()) - return false; - char *codeStr = (char *)script.raw().c_str(); - //PyRun_SimpleString(inkscape_module_script); - //PyRun_SimpleString("inkscape = _inkscape_py.getInkscape()\n"); - //PyRun_SimpleString(codeStr); + inkscapePython = this; + + stdOut.clear(); + stdErr.clear(); + + //## First bind our classes + Py_Initialize(); + + + //# Init our custom objects + PyInkscapeModule inkscapeModule; + + PyObject *globalMod = PyImport_AddModule("__main__"); + PyObject *globalDict = PyModule_GetDict(globalMod); + PyObject *localDict = inkscapeModule.moduleDictionary().ptr(); + + Glib::ustring buf = + "import sys\n" + "sys.stdout = getStdOut()\n" + "sys.stderr = getStdErr()\n" + "\n" + "inkscape = getInkscape()\n" + "\n"; + buf.append(script); + + + char *codeStr = (char *)buf.c_str(); + PyRun_String(codeStr, Py_file_input, globalDict, localDict); + + output = stdOut; + //output = "hello, world\n"; + error = stdErr; + //## Check for errors if (PyErr_Occurred()) { - PyObject *errobj = NULL; - PyObject *errdata = NULL; + PyObject *errtype = NULL; + PyObject *errval = NULL; PyObject *errtraceback = NULL; - PyErr_Fetch(&errobj, &errdata, &errtraceback); + PyErr_Fetch(&errtype, &errval, &errtraceback); //PyErr_Clear(); - if (errobj && PyString_Check(errobj)) + if (errval && PyString_Check(errval)) { - PyObject *pystring = PyObject_Str(errobj); - char *errStr = PyString_AsString(pystring); - error = errStr; + PyObject *pystring = PyObject_Str(errval); + char *errStr = PyString_AsString(pystring); + int line = ((PyTracebackObject*)errtraceback)->tb_lineno; + //error = "Line "; + //error.append(line); + //error.append(" : "); + error.append(errStr); Py_XDECREF(pystring); } else { error = "Error occurred"; } - Py_XDECREF(errobj); - Py_XDECREF(errdata); + Py_XDECREF(errtype); + Py_XDECREF(errval); Py_XDECREF(errtraceback); + Py_Finalize(); return false; } - //Py_Finalize(); + + + Py_Finalize(); + return true; } diff --git a/src/extension/script/InkscapePython.h b/src/extension/script/InkscapePython.h index 76739c152..a97c945c8 100644 --- a/src/extension/script/InkscapePython.h +++ b/src/extension/script/InkscapePython.h @@ -37,7 +37,6 @@ public: */ InkscapePython() { - initialized = false; } @@ -58,17 +57,20 @@ public: Glib::ustring &error); + virtual void writeStdOut(const Glib::ustring &txt) + { + stdOut.append(txt); + } + virtual void writeStdErr(const Glib::ustring &txt) + { + stdErr.append(txt); + } private: - /** - * First-time call to set things up - */ - bool initialize(); - - bool initialized; - + Glib::ustring stdOut; + Glib::ustring stdErr; }; diff --git a/src/extension/script/InkscapeScript.cpp b/src/extension/script/InkscapeScript.cpp index f403a3db0..dfdbabcc5 100644 --- a/src/extension/script/InkscapeScript.cpp +++ b/src/extension/script/InkscapeScript.cpp @@ -83,21 +83,21 @@ bool InkscapeScript::interpretScript(const Glib::ustring &script, } else { - g_error("interpretScript: Unknown Script Language type: %d\n", + g_warning("interpretScript: Unknown Script Language type: %d\n", language); return false; } if (!interp) { - g_error("interpretScript: error starting Language '%s'\n", + g_warning("interpretScript: error starting Language '%s'\n", langname); return false; } if (!interp->interpretScript(script, output, error)) { - g_error("interpretScript: error in executing %s script\n", + g_warning("interpretScript: error in executing %s script\n", langname); return false; } @@ -135,7 +135,7 @@ bool InkscapeScript::interpretUri(const Glib::ustring &uri, } else { - g_error("interpretUri: Unknown Script Language type:%d\n", + g_warning("interpretUri: Unknown Script Language type:%d\n", language); return false; } @@ -145,7 +145,7 @@ bool InkscapeScript::interpretUri(const Glib::ustring &uri, if (!interp->interpretUri(uri, output, error)) { - g_error("interpretUri: error in executing script '%s'\n", + g_warning("interpretUri: error in executing script '%s'\n", uri.raw().c_str()); return false; } -- 2.30.2