Code

Added missing (and very important) file.
[inkscape.git] / src / extension / implementation / script.cpp
index 1f6d973c33e8b065d3f4415239b275ab974bc5af..eabf147f64980afa2acbb18027dc682c961da6a3 100644 (file)
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
 
-/*
-TODO:
-FIXME:
-  After Inkscape makes a formal requirement for a GTK version above 2.11.4, please
-  replace all the instances of ink_ext_XXXXXX in this file that represent
-  svg files with ink_ext_XXXXXX.svg . Doing so will prevent errors in extensions
-  that call inkscape to manipulate the file.
-
-  "** (inkscape:5848): WARNING **: Format autodetect failed. The file is being opened as SVG."
-
-  references:
-  http://www.gtk.org/api/2.6/glib/glib-File-Utilities.html#g-mkstemp
-  http://ftp.gnome.org/pub/gnome/sources/glib/2.11/glib-2.11.4.changes
-  http://developer.gnome.org/doc/API/2.0/glib/glib-File-Utilities.html#g-mkstemp
-
-  --Aaron Spike
-*/
 #define __INKSCAPE_EXTENSION_IMPLEMENTATION_SCRIPT_C__
 
 #ifdef HAVE_CONFIG_H
@@ -54,6 +37,8 @@ FIXME:
 #include "script.h"
 #include "dialogs/dialog-events.h"
 #include "application/application.h"
+#include "xml/node.h"
+#include "xml/attribute-record.h"
 
 #include "util/glib-list-iterators.h"
 
@@ -77,19 +62,18 @@ namespace Inkscape {
 namespace Extension {
 namespace Implementation {
 
-void pump_events (void) {
+/** \brief  Make GTK+ events continue to come through a little bit
+       
+       This just keeps coming the events through so that we'll make the GUI
+       update and look pretty.
+*/
+void
+Script::pump_events (void) {
     while( Gtk::Main::events_pending() )
         Gtk::Main::iteration();
     return;
 }
 
-//Interpreter lookup table
-struct interpreter_t {
-        gchar const *identity;
-        gchar const *prefstring;
-        gchar const *defaultval;
-};
-
 
 /** \brief  A table of what interpreters to call for a given language
 
@@ -97,7 +81,7 @@ struct interpreter_t {
     given script.  It also tracks the preference to use to overwrite
     the given interpreter to a custom one per user.
 */
-static interpreter_t const interpreterTab[] = {
+Script::interpreter_t const Script::interpreterTab[] = {
         {"perl",   "perl-interpreter",   "perl"   },
 #ifdef WIN32
         {"python", "python-interpreter", "pythonw" },
@@ -111,12 +95,13 @@ static interpreter_t const interpreterTab[] = {
 
 
 
-/**
- * Look up an interpreter name, and translate to something that
- * is executable
- */
-static Glib::ustring
-resolveInterpreterExecutable(const Glib::ustring &interpNameArg)
+/** \brief Look up an interpreter name, and translate to something that
+           is executable
+    \param interpNameArg  The name of the interpreter that we're looking
+                             for, should be an entry in interpreterTab
+*/
+Glib::ustring
+Script::resolveInterpreterExecutable(const Glib::ustring &interpNameArg)
 {
 
     Glib::ustring interpName = interpNameArg;
@@ -137,7 +122,7 @@ resolveInterpreterExecutable(const Glib::ustring &interpNameArg)
 
     // 1.  Check preferences
     Inkscape::Preferences *prefs = Inkscape::Preferences::get();
-    Glib::ustring prefInterp = prefs->getString("extensions", interp->prefstring);
+    Glib::ustring prefInterp = prefs->getString("/extensions/" + Glib::ustring(interp->prefstring));
 
     if (!prefInterp.empty()) {
         interpName = prefInterp;
@@ -184,8 +169,6 @@ resolveInterpreterExecutable(const Glib::ustring &interpNameArg)
     return interpName;
 }
 
-
-
 /** \brief     This function creates a script object and sets up the
                variables.
     \return    A script object
@@ -199,7 +182,6 @@ Script::Script() :
 {
 }
 
-
 /**
  *   brief     Destructor
  */
@@ -573,7 +555,7 @@ Script::open(Inkscape::Extension::Input *module,
     std::string tempfilename_out;
     int tempfd_out = 0;
     try {
-        tempfd_out = Inkscape::IO::file_open_tmp(tempfilename_out, "ink_ext_XXXXXX");
+        tempfd_out = Inkscape::IO::file_open_tmp(tempfilename_out, "ink_ext_XXXXXX.svg");
     } catch (...) {
         /// \todo Popup dialog here
         return NULL;
@@ -599,7 +581,9 @@ Script::open(Inkscape::Extension::Input *module,
     } // data_read
 
     if (mydoc != NULL) {
-        sp_document_set_uri(mydoc, filenameArg);
+        g_free(mydoc->base);
+        mydoc->base = NULL;
+        sp_document_change_uri_and_hrefs(mydoc, filenameArg);
     }
 
     // make sure we don't leak file descriptors from g_file_open_tmp
@@ -647,7 +631,7 @@ Script::save(Inkscape::Extension::Output *module,
     std::string tempfilename_in;
     int tempfd_in = 0;
     try {
-        tempfd_in = Inkscape::IO::file_open_tmp(tempfilename_in, "ink_ext_XXXXXX");
+        tempfd_in = Inkscape::IO::file_open_tmp(tempfilename_in, "ink_ext_XXXXXX.svg");
     } catch (...) {
         /// \todo Popup dialog here
         return;
@@ -854,8 +838,26 @@ Script::copy_doc (Inkscape::XML::Node * oldroot, Inkscape::XML::Node * newroot)
         }
     }
 
-    oldroot->setAttribute("width", newroot->attribute("width"));
-    oldroot->setAttribute("height", newroot->attribute("height"));
+    {
+        using Inkscape::Util::List;
+        using Inkscape::XML::AttributeRecord;        
+        std::vector<gchar const *> attribs;
+
+        // Make a list of all attributes of the old root node.
+        for (List<AttributeRecord const> iter = oldroot->attributeList(); iter; ++iter) {
+            attribs.push_back(g_quark_to_string(iter->key));
+        }
+
+        // Delete the attributes of the old root nodes.
+        for (std::vector<gchar const *>::const_iterator it = attribs.begin(); it != attribs.end(); it++)
+            oldroot->setAttribute(*it, NULL);
+
+        // Set the new attributes.
+        for (List<AttributeRecord const> iter = newroot->attributeList(); iter; ++iter) {
+            gchar const *name = g_quark_to_string(iter->key);
+            oldroot->setAttribute(name, newroot->attribute(name));
+        }
+    }
 
     /** \todo  Restore correct layer */
     /** \todo  Restore correct selection */