Code

Rearrange bindings to use PyCXX
authorishmal <ishmal@users.sourceforge.net>
Sun, 15 Apr 2007 01:18:55 +0000 (01:18 +0000)
committerishmal <ishmal@users.sourceforge.net>
Sun, 15 Apr 2007 01:18:55 +0000 (01:18 +0000)
src/extension/script/InkscapePython.cpp
src/extension/script/InkscapePython.h
src/extension/script/InkscapeScript.cpp

index f7cfe81db2d55859aac3a2d923de653e51844b06..186d7c664efc68667b3658537bb224d9726779ed 100644 (file)
 
 
 #include <inkscape.h>
+#include <desktop.h>
+#include <document.h>
+#include <ui/dialog/dialog-manager.h>
+
+//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<PyDialogManager>
 {
 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<PyDesktop>
 {
 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<PyDocument>
 {
 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<PyInkscape>
 {
 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<PyStdOut>
 {
-    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 ; i<args.length() ; i++)
+                {
+                Py::String str(args[i]);
+                inkscapePython->writeStdOut(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<PyStdErr>
+{
+public:
+
+    PyStdErr()
+        {
+        }
+        
+    virtual ~PyStdErr()
+        {
+        }
+
+        
+    virtual Py::Object write(const Py::Tuple &args)
+        {
+        g_message("PyStdErr");
+        if (inkscapePython)
+            {
+            for(unsigned int i=0 ; i<args.length() ; i++)
+                {
+                Py::String str(args[i]);
+                inkscapePython->writeStdErr(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<PyInkscapeModule>
+{
+public:
+    PyInkscapeModule()
+        : Py::ExtensionModule<PyInkscapeModule>( "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;
 }
 
index 76739c15243d74f1d23dc408643d01a77e1c4e72..a97c945c8dbd008f0e992cafc6c8afd469b43e8c 100644 (file)
@@ -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;
 
 };
 
index f403a3db0bb05f1018efa85d4bcdbb2e5732f9d2..dfdbabcc569d03c242f212e952e1a39db2cd47a0 100644 (file)
@@ -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;
         }