Code

Cleaned up more of the gboolean to bool janitorial task...great!
[inkscape.git] / src / extension / parameter.cpp
index 7e5d46739b5e2e833db339ebf438a1972d07906a..a034022d9f8a5b2413626569ffa86d35ad516010 100644 (file)
@@ -6,7 +6,7 @@
  * Authors:
  *   Ted Gould <ted@gould.cx>
  *
- * Copyright (C) 2005 Authors
+ * Copyright (C) 2005-2006 Authors
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
 
 #include <glibmm/i18n.h>
 
+#include <xml/node.h>
+
 #include "extension.h"
 #include "prefs-utils.h"
+#include "document-private.h"
+#include "sp-object.h"
 
 #include "parameter.h"
 
 namespace Inkscape {
 namespace Extension {
 
-/*
-template <typename T> class ParamSpecific : public Parameter {
+/** \brief  A description parameter */
+class ParamDescription : public Parameter {
 private:
-    T _value;
+    /** \brief  Internal value. */
+    gchar * _value;
 public:
-    ParamSpecific (const gchar * name, const gchar * guitext, Inkscape::Extension * ext, Inkscape::XML::Node * xml);
-    T get (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node);
-    T set (T in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node);
-    Gtk::Widget * get_widget(void);
-    Glib::ustring * string (void);
+    ParamDescription(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
+    Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);
 };
 
-bool
-ParamSpecific<bool>::get (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node)
-{
-    return _value;
-}
-
-int
-ParamSpecific<int>::get (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node)
-{
-    return _value;
-}
-*/
-
 /** \brief  A boolean parameter */
 class ParamBool : public Parameter {
 private:
     /** \brief  Internal value. */
     bool _value;
 public:
-    ParamBool(const gchar * name, const gchar * guitext, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
+    ParamBool(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
     /** \brief  Returns \c _value */
-    bool get (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node) { return _value; }
-    bool set (bool in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node);
-    Gtk::Widget * get_widget(void);
+    bool get (const SPDocument * doc, const Inkscape::XML::Node * node) { return _value; }
+    bool set (bool in, SPDocument * doc, Inkscape::XML::Node * node);
+    Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);
     Glib::ustring * string (void);
 };
 
 /** \brief  Use the superclass' allocator and set the \c _value */
-ParamBool::ParamBool (const gchar * name, const gchar * guitext, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
-        Parameter(name, guitext, ext), _value(false)
+ParamBool::ParamBool (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
+        Parameter(name, guitext, desc, scope, ext), _value(false)
 {
     const char * defaultval = NULL;
     if (sp_repr_children(xml) != NULL)
@@ -101,19 +90,19 @@ private:
     int _min;
     int _max;
 public:
-    ParamInt (const gchar * name, const gchar * guitext, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
+    ParamInt (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
     /** \brief  Returns \c _value */
-    int get (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node) { return _value; }
-    int set (int in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node);
+    int get (const SPDocument * doc, const Inkscape::XML::Node * node) { return _value; }
+    int set (int in, SPDocument * doc, Inkscape::XML::Node * node);
     int max (void) { return _max; }
     int min (void) { return _min; }
-    Gtk::Widget * get_widget(void);
+    Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);
     Glib::ustring * string (void);
 };
 
 /** \brief  Use the superclass' allocator and set the \c _value */
-ParamInt::ParamInt (const gchar * name, const gchar * guitext, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
-        Parameter(name, guitext, ext), _value(0), _min(0), _max(10)
+ParamInt::ParamInt (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
+        Parameter(name, guitext, desc, scope, ext), _value(0), _min(0), _max(10)
 {
     const char * defaultval = NULL;
     if (sp_repr_children(xml) != NULL)
@@ -155,19 +144,19 @@ private:
     float _min;
     float _max;
 public:
-    ParamFloat (const gchar * name, const gchar * guitext, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
+    ParamFloat (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
     /** \brief  Returns \c _value */
-    float get (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node) { return _value; }
-    float set (float in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node);
+    float get (const SPDocument * doc, const Inkscape::XML::Node * node) { return _value; }
+    float set (float in, SPDocument * doc, Inkscape::XML::Node * node);
     float max (void) { return _max; }
     float min (void) { return _min; }
-    Gtk::Widget * get_widget(void);
+    Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);
     Glib::ustring * string (void);
 };
 
 /** \brief  Use the superclass' allocator and set the \c _value */
-ParamFloat::ParamFloat (const gchar * name, const gchar * guitext, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
-        Parameter(name, guitext, ext), _value(0.0), _min(0.0), _max(10.0)
+ParamFloat::ParamFloat (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
+        Parameter(name, guitext, desc, scope, ext), _value(0.0), _min(0.0), _max(10.0)
 {
     const char * defaultval = NULL;
     if (sp_repr_children(xml) != NULL)
@@ -208,15 +197,48 @@ private:
                 been allocated in memory.  And should be free'd. */
     gchar * _value;
 public:
-    ParamString(const gchar * name, const gchar * guitext, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
+    ParamString(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
     ~ParamString(void);
     /** \brief  Returns \c _value, with a \i const to protect it. */
-    const gchar * get (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node) { return _value; }
-    const gchar * set (const gchar * in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node);
-    Gtk::Widget * get_widget(void);
+    const gchar * get (const SPDocument * doc, const Inkscape::XML::Node * node) { return _value; }
+    const gchar * set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node);
+    Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);
     Glib::ustring * string (void);
 };
 
+class ParamEnum : public Parameter {
+private:
+    class Choice {
+    public:
+        gchar * _gui_name;
+        gchar * _value;
+        Choice(gchar * gui_name, gchar * value) : _gui_name(NULL), _value(NULL) {
+            if (gui_name != NULL)
+                _gui_name = g_strdup(_(gui_name));
+            if (value != NULL)
+                _value = g_strdup(value);
+            return;
+        };
+        ~Choice (void) {
+            g_free(_gui_name);
+            g_free(_value);
+        };
+    }; /* class Choice */
+    /** \brief  Internal value.  This should point to a string that has
+                been allocated in memory.  And should be free'd. */
+    Choice * _current_choice;
+    typedef std::list<Choice *> choice_list_t;
+    choice_list_t _choice_list;
+public:
+    ParamEnum(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
+    ~ParamEnum(void);
+    /** \brief  Returns \c _value, with a \i const to protect it. */
+    const gchar * get (const SPDocument * doc, const Inkscape::XML::Node * node) { return _current_choice != NULL ? _current_choice->_value : NULL; }
+    const gchar * set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node);
+    Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);
+    Glib::ustring * string (void);
+}; /* class ParamEnum */
+
 /**
     \return None
     \brief  This function creates a parameter that can be used later.  This
@@ -246,27 +268,48 @@ Parameter::make (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension *
     const char * name;
     const char * type;
     const char * guitext;
+    const char * desc;
+    const char * scope_str;
+    Parameter::_scope_t scope = Parameter::SCOPE_USER;
 
     name = in_repr->attribute("name");
     type = in_repr->attribute("type");
     guitext = in_repr->attribute("gui-text");
     if (guitext == NULL)
         guitext = in_repr->attribute("_gui-text");
+    desc = in_repr->attribute("gui-description");
+    if (desc == NULL)
+        desc = in_repr->attribute("_gui-description");
+    scope_str = in_repr->attribute("scope");
 
     /* In this case we just don't have enough information */
     if (name == NULL || type == NULL) {
         return NULL;
     }
 
+    if (scope_str != NULL) {
+        if (!strcmp(scope_str, "user")) {
+            scope = Parameter::SCOPE_USER;
+        } else if (!strcmp(scope_str, "document")) {
+            scope = Parameter::SCOPE_DOCUMENT;
+        } else if (!strcmp(scope_str, "node")) {
+            scope = Parameter::SCOPE_NODE;
+        }
+    }
+
     Parameter * param = NULL;
     if (!strcmp(type, "boolean")) {
-        param = new ParamBool(name, guitext, in_ext, in_repr);
+        param = new ParamBool(name, guitext, desc, scope, in_ext, in_repr);
     } else if (!strcmp(type, "int")) {
-        param = new ParamInt(name, guitext, in_ext, in_repr);
+        param = new ParamInt(name, guitext, desc, scope, in_ext, in_repr);
     } else if (!strcmp(type, "float")) {
-        param = new ParamFloat(name, guitext, in_ext, in_repr);
+        param = new ParamFloat(name, guitext, desc, scope, in_ext, in_repr);
     } else if (!strcmp(type, "string")) {
-        param = new ParamString(name, guitext, in_ext, in_repr);
+        param = new ParamString(name, guitext, desc, scope, in_ext, in_repr);
+    } else if (!strcmp(type, "description")) {
+        param = new ParamDescription(name, guitext, desc, scope, in_ext, in_repr);
+    } else if (!strcmp(type, "enum")) {
+        param = new ParamEnum(name, guitext, desc, scope, in_ext, in_repr);
     }
 
     /* Note: param could equal NULL */
@@ -283,7 +326,7 @@ Parameter::make (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension *
     and \c pref_name() are used.
 */
 bool
-ParamBool::set (bool in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
+ParamBool::set (bool in, SPDocument * doc, Inkscape::XML::Node * node)
 {
     _value = in;
 
@@ -304,7 +347,7 @@ ParamBool::set (bool in, Inkscape::XML::Document * doc, Inkscape::XML::Node * no
     and \c pref_name() are used.
 */
 int
-ParamInt::set (int in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
+ParamInt::set (int in, SPDocument * doc, Inkscape::XML::Node * node)
 {
     _value = in;
     if (_value > _max) _value = _max;
@@ -327,7 +370,7 @@ ParamInt::set (int in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node
     and \c pref_name() are used.
 */
 float
-ParamFloat::set (float in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
+ParamFloat::set (float in, SPDocument * doc, Inkscape::XML::Node * node)
 {
     _value = in;
     if (_value > _max) _value = _max;
@@ -354,7 +397,7 @@ ParamFloat::set (float in, Inkscape::XML::Document * doc, Inkscape::XML::Node *
     the passed in value is duplicated using \c g_strdup().
 */
 const gchar *
-ParamString::set (const gchar * in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
+ParamString::set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node)
 {
     if (in == NULL) return NULL; /* Can't have NULL string */
 
@@ -371,7 +414,7 @@ ParamString::set (const gchar * in, Inkscape::XML::Document * doc, Inkscape::XML
 
 /** \brief  Wrapper to cast to the object and use it's function.  */
 bool
-Parameter::get_bool (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node)
+Parameter::get_bool (const SPDocument * doc, const Inkscape::XML::Node * node)
 {
     ParamBool * boolpntr;
     boolpntr = dynamic_cast<ParamBool *>(this);
@@ -382,7 +425,7 @@ Parameter::get_bool (const Inkscape::XML::Document * doc, const Inkscape::XML::N
 
 /** \brief  Wrapper to cast to the object and use it's function.  */
 int
-Parameter::get_int (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node)
+Parameter::get_int (const SPDocument * doc, const Inkscape::XML::Node * node)
 {
     ParamInt * intpntr;
     intpntr = dynamic_cast<ParamInt *>(this);
@@ -393,7 +436,7 @@ Parameter::get_int (const Inkscape::XML::Document * doc, const Inkscape::XML::No
 
 /** \brief  Wrapper to cast to the object and use it's function.  */
 float
-Parameter::get_float (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node)
+Parameter::get_float (const SPDocument * doc, const Inkscape::XML::Node * node)
 {
     ParamFloat * floatpntr;
     floatpntr = dynamic_cast<ParamFloat *>(this);
@@ -404,7 +447,7 @@ Parameter::get_float (const Inkscape::XML::Document * doc, const Inkscape::XML::
 
 /** \brief  Wrapper to cast to the object and use it's function.  */
 const gchar *
-Parameter::get_string (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node)
+Parameter::get_string (const SPDocument * doc, const Inkscape::XML::Node * node)
 {
     ParamString * stringpntr;
     stringpntr = dynamic_cast<ParamString *>(this);
@@ -415,7 +458,7 @@ Parameter::get_string (const Inkscape::XML::Document * doc, const Inkscape::XML:
 
 /** \brief  Wrapper to cast to the object and use it's function.  */
 bool
-Parameter::set_bool (bool in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
+Parameter::set_bool (bool in, SPDocument * doc, Inkscape::XML::Node * node)
 {
     ParamBool * boolpntr;
     boolpntr = dynamic_cast<ParamBool *>(this);
@@ -426,7 +469,7 @@ Parameter::set_bool (bool in, Inkscape::XML::Document * doc, Inkscape::XML::Node
 
 /** \brief  Wrapper to cast to the object and use it's function.  */
 int
-Parameter::set_int (int in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
+Parameter::set_int (int in, SPDocument * doc, Inkscape::XML::Node * node)
 {
     ParamInt * intpntr;
     intpntr = dynamic_cast<ParamInt *>(this);
@@ -437,7 +480,7 @@ Parameter::set_int (int in, Inkscape::XML::Document * doc, Inkscape::XML::Node *
 
 /** \brief  Wrapper to cast to the object and use it's function.  */
 float
-Parameter::set_float (float in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
+Parameter::set_float (float in, SPDocument * doc, Inkscape::XML::Node * node)
 {
     ParamFloat * floatpntr;
     floatpntr = dynamic_cast<ParamFloat *>(this);
@@ -448,7 +491,7 @@ Parameter::set_float (float in, Inkscape::XML::Document * doc, Inkscape::XML::No
 
 /** \brief  Wrapper to cast to the object and use it's function.  */
 const gchar *
-Parameter::set_string (const gchar * in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
+Parameter::set_string (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node)
 {
     ParamString * stringpntr;
     stringpntr = dynamic_cast<ParamString *>(this);
@@ -458,8 +501,8 @@ Parameter::set_string (const gchar * in, Inkscape::XML::Document * doc, Inkscape
 }
 
 /** \brief  Initialize the object, to do that, copy the data. */
-ParamString::ParamString (const gchar * name, const gchar * guitext, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
-    Parameter(name, guitext, ext), _value(NULL)
+ParamString::ParamString (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
+    Parameter(name, guitext, desc, scope, ext), _value(NULL)
 {
     const char * defaultval = NULL;
     if (sp_repr_children(xml) != NULL)
@@ -484,14 +527,23 @@ ParamString::~ParamString(void)
 }
 
 /** \brief  Oop, now that we need a parameter, we need it's name.  */
-Parameter::Parameter (const gchar * name, const gchar * guitext, Inkscape::Extension::Extension * ext) :
-    extension(ext), _name(NULL), _text(NULL)
-{
-    _name = g_strdup(name);
+Parameter::Parameter (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext) :
+    extension(ext), _name(NULL), _desc(NULL), _scope(scope), _text(NULL)
+{
+    if (name != NULL)
+        _name = g_strdup(name);
+    if (desc != NULL) {
+        _desc = g_strdup(desc);
+        // printf("Adding description: '%s' on '%s'\n", _desc, _name);
+    }
+
+
     if (guitext != NULL)
         _text = g_strdup(guitext);
     else
         _text = g_strdup(name);
+
+    return;
 }
 
 /** \brief  Just free the allocated name. */
@@ -509,9 +561,53 @@ Parameter::pref_name (void)
     return g_strdup_printf("%s.%s", extension->get_id(), _name);
 }
 
+Inkscape::XML::Node *
+Parameter::find_child (Inkscape::XML::Node * adult)
+{
+    return sp_repr_lookup_child(adult, "name", _name);
+}
+
+Inkscape::XML::Node *
+Parameter::new_child (Inkscape::XML::Node * parent)
+{
+    Inkscape::XML::Node * retval;
+    retval = sp_repr_new("inkscape:extension-param");
+    retval->setAttribute("name", _name);
+
+    parent->appendChild(retval);
+    return retval;
+}
+
+Inkscape::XML::Node *
+Parameter::document_param_node (SPDocument * doc)
+{
+    Inkscape::XML::Node * defs = SP_OBJECT_REPR(SP_DOCUMENT_DEFS(doc));
+    Inkscape::XML::Node * params = NULL;
+
+    GQuark const name_quark = g_quark_from_string("inkscape:extension-params");
+
+    for (Inkscape::XML::Node * child = defs->firstChild();
+            child != NULL;
+            child = child->next()) {
+        if ((GQuark)child->code() == name_quark &&
+                !strcmp(child->attribute("extension"), extension->get_id())) {
+            params = child;
+            break;
+        }
+    }
+
+    if (params == NULL) {
+        params = sp_repr_new("inkscape:extension-param");
+        params->setAttribute("extension", extension->get_id());
+        defs->appendChild(params);
+    }
+
+    return params;
+}
+
 /** \brief  Basically, if there is no widget pass a NULL. */
 Gtk::Widget *
-Parameter::get_widget (void)
+Parameter::get_widget (SPDocument * doc, Inkscape::XML::Node * node)
 {
     return NULL;
 }
@@ -528,11 +624,13 @@ Parameter::string (void)
 class ParamFloatAdjustment : public Gtk::Adjustment {
     /** The parameter to adjust */
     ParamFloat * _pref;
+    SPDocument * _doc;
+    Inkscape::XML::Node * _node;
 public:
     /** \brief  Make the adjustment using an extension and the string
                 describing the parameter. */
-    ParamFloatAdjustment (ParamFloat * param) :
-            Gtk::Adjustment(0.0, param->min(), param->max(), 0.1), _pref(param) {
+    ParamFloatAdjustment (ParamFloat * param, SPDocument * doc, Inkscape::XML::Node * node) :
+            Gtk::Adjustment(0.0, param->min(), param->max(), 0.1), _pref(param), _doc(doc), _node(node) {
         this->set_value(_pref->get(NULL, NULL) /* \todo fix */);
         this->signal_value_changed().connect(sigc::mem_fun(this, &ParamFloatAdjustment::val_changed));
         return;
@@ -551,7 +649,7 @@ void
 ParamFloatAdjustment::val_changed (void)
 {
     // std::cout << "Value Changed to: " << this->get_value() << std::endl;
-    _pref->set(this->get_value(), NULL /* \todo fix */, NULL);
+    _pref->set(this->get_value(), _doc, _node);
     return;
 }
 
@@ -559,11 +657,13 @@ ParamFloatAdjustment::val_changed (void)
 class ParamIntAdjustment : public Gtk::Adjustment {
     /** The parameter to adjust */
     ParamInt * _pref;
+    SPDocument * _doc;
+    Inkscape::XML::Node * _node;
 public:
     /** \brief  Make the adjustment using an extension and the string
                 describing the parameter. */
-    ParamIntAdjustment (ParamInt * param) :
-            Gtk::Adjustment(0.0, param->min(), param->max(), 1.0), _pref(param) {
+    ParamIntAdjustment (ParamInt * param, SPDocument * doc, Inkscape::XML::Node * node) :
+            Gtk::Adjustment(0.0, param->min(), param->max(), 1.0), _pref(param), _doc(doc), _node(node) {
         this->set_value(_pref->get(NULL, NULL) /* \todo fix */);
         this->signal_value_changed().connect(sigc::mem_fun(this, &ParamIntAdjustment::val_changed));
         return;
@@ -582,7 +682,7 @@ void
 ParamIntAdjustment::val_changed (void)
 {
     // std::cout << "Value Changed to: " << this->get_value() << std::endl;
-    _pref->set((int)this->get_value(), NULL /* \todo fix */, NULL);
+    _pref->set((int)this->get_value(), _doc, _node);
     return;
 }
 
@@ -592,16 +692,16 @@ ParamIntAdjustment::val_changed (void)
     Builds a hbox with a label and a float adjustment in it.
 */
 Gtk::Widget *
-ParamFloat::get_widget (void)
+ParamFloat::get_widget (SPDocument * doc, Inkscape::XML::Node * node)
 {
-    Gtk::HBox * hbox = new Gtk::HBox();
+    Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
 
-    Gtk::Label * label = new Gtk::Label(_(_text), Gtk::ALIGN_LEFT);
+    Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
     label->show();
     hbox->pack_start(*label, true, true);
 
-    ParamFloatAdjustment * fadjust = new ParamFloatAdjustment(this);
-    Gtk::SpinButton * spin = new Gtk::SpinButton(*fadjust, 0.1, 1);
+    ParamFloatAdjustment * fadjust = Gtk::manage(new ParamFloatAdjustment(this, doc, node));
+    Gtk::SpinButton * spin = Gtk::manage(new Gtk::SpinButton(*fadjust, 0.1, 1));
     spin->show();
     hbox->pack_start(*spin, false, false);
 
@@ -616,16 +716,16 @@ ParamFloat::get_widget (void)
     Builds a hbox with a label and a int adjustment in it.
 */
 Gtk::Widget *
-ParamInt::get_widget (void)
+ParamInt::get_widget (SPDocument * doc, Inkscape::XML::Node * node)
 {
-    Gtk::HBox * hbox = new Gtk::HBox();
+    Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
 
-    Gtk::Label * label = new Gtk::Label(_(_text), Gtk::ALIGN_LEFT);
+    Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
     label->show();
     hbox->pack_start(*label, true, true);
 
-    ParamIntAdjustment * fadjust = new ParamIntAdjustment(this);
-    Gtk::SpinButton * spin = new Gtk::SpinButton(*fadjust, 1.0, 0);
+    ParamIntAdjustment * fadjust = Gtk::manage(new ParamIntAdjustment(this, doc, node));
+    Gtk::SpinButton * spin = Gtk::manage(new Gtk::SpinButton(*fadjust, 1.0, 0));
     spin->show();
     hbox->pack_start(*spin, false, false);
 
@@ -641,6 +741,8 @@ class ParamBoolCheckButton : public Gtk::CheckButton {
 private:
     /** \brief  Param to change */
     ParamBool * _pref;
+    SPDocument * _doc;
+    Inkscape::XML::Node * _node;
 public:
     /** \brief  Initialize the check button
         \param  param  Which parameter to adjust on changing the check button
@@ -648,8 +750,8 @@ public:
         This function sets the value of the checkbox to be that of the
         parameter, and then sets up a callback to \c on_toggle.
     */
-    ParamBoolCheckButton (ParamBool * param) :
-            Gtk::CheckButton(), _pref(param) {
+    ParamBoolCheckButton (ParamBool * param, SPDocument * doc, Inkscape::XML::Node * node) :
+            Gtk::CheckButton(), _pref(param), _doc(doc), _node(node) {
         this->set_active(_pref->get(NULL, NULL) /**\todo fix */);
         this->signal_toggled().connect(sigc::mem_fun(this, &ParamBoolCheckButton::on_toggle));
         return;
@@ -675,15 +777,15 @@ ParamBoolCheckButton::on_toggle (void)
     Builds a hbox with a label and a check button in it.
 */
 Gtk::Widget *
-ParamBool::get_widget (void)
+ParamBool::get_widget (SPDocument * doc, Inkscape::XML::Node * node)
 {
-    Gtk::HBox * hbox = new Gtk::HBox();
+    Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
 
-    Gtk::Label * label = new Gtk::Label(_(_text), Gtk::ALIGN_LEFT);
+    Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
     label->show();
     hbox->pack_start(*label, true, true);
 
-    ParamBoolCheckButton * checkbox = new ParamBoolCheckButton(this);
+    ParamBoolCheckButton * checkbox = new ParamBoolCheckButton(this, doc, node);
     checkbox->show();
     hbox->pack_start(*checkbox, false, false);
 
@@ -696,13 +798,15 @@ ParamBool::get_widget (void)
 class ParamStringEntry : public Gtk::Entry {
 private:
     ParamString * _pref;
+    SPDocument * _doc;
+    Inkscape::XML::Node * _node;
 public:
     /** \brief  Build a string preference for the given parameter
         \param  pref  Where to get the string from, and where to put it
                       when it changes.
     */
-    ParamStringEntry (ParamString * pref) :
-        Gtk::Entry(), _pref(pref) {
+    ParamStringEntry (ParamString * pref, SPDocument * doc, Inkscape::XML::Node * node) :
+        Gtk::Entry(), _pref(pref), _doc(doc), _node(node) {
         if (_pref->get(NULL, NULL) != NULL)
             this->set_text(Glib::ustring(_pref->get(NULL, NULL)));
         this->signal_changed().connect(sigc::mem_fun(this, &ParamStringEntry::changed_text));
@@ -719,7 +823,7 @@ void
 ParamStringEntry::changed_text (void)
 {
     Glib::ustring data = this->get_text();
-    _pref->set(data.c_str(), NULL, NULL);
+    _pref->set(data.c_str(), _doc, _node);
     return;
 }
 
@@ -729,17 +833,17 @@ ParamStringEntry::changed_text (void)
     Builds a hbox with a label and a text box in it.
 */
 Gtk::Widget *
-ParamString::get_widget (void)
+ParamString::get_widget (SPDocument * doc, Inkscape::XML::Node * node)
 {
-    Gtk::HBox * hbox = new Gtk::HBox();
+    Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
 
-    Gtk::Label * label = new Gtk::Label(_(_text), Gtk::ALIGN_LEFT);
+    Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
     label->show();
-    hbox->pack_start(*label, true, true);
+    hbox->pack_start(*label, false, false);
 
-    ParamStringEntry * textbox = new ParamStringEntry(this);
+    ParamStringEntry * textbox = new ParamStringEntry(this, doc, node);
     textbox->show();
-    hbox->pack_start(*textbox, false, false);
+    hbox->pack_start(*textbox, true, true);
 
     hbox->show();
 
@@ -791,6 +895,70 @@ ParamString::string (void)
     return mystring;
 }
 
+/** \brief  Create a label for the description */
+Gtk::Widget *
+ParamDescription::get_widget (SPDocument * doc, Inkscape::XML::Node * node)
+{
+    Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_value)));
+    label->set_line_wrap();
+    label->show();
+
+    Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
+    hbox->pack_start(*label, true, true, 5);
+    hbox->show();
+
+    return hbox;
+}
+
+/** \brief  Initialize the object, to do that, copy the data. */
+ParamDescription::ParamDescription (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
+    Parameter(name, guitext, desc, scope, ext), _value(NULL)
+{
+    // printf("Building Description\n");
+    const char * defaultval = NULL;
+    if (sp_repr_children(xml) != NULL)
+        defaultval = sp_repr_children(xml)->content();
+
+    if (defaultval != NULL)
+        _value = g_strdup(defaultval);
+
+    return;
+}
+
+ParamEnum::ParamEnum (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
+    Parameter(name, guitext, desc, scope, ext), _current_choice(NULL)
+{
+    return;
+}
+
+ParamEnum::~ParamEnum (void)
+{
+
+}
+
+/** \brief  Return the value as a string */
+Glib::ustring *
+ParamEnum::string (void)
+{
+    Glib::ustring * mystring = new Glib::ustring("");
+    *mystring += "\"";
+    *mystring += this->get(NULL, NULL);
+    *mystring += "\"";
+    return mystring;
+}
+
+Gtk::Widget *
+ParamEnum::get_widget (SPDocument * doc, Inkscape::XML::Node * node)
+{
+    return NULL;
+}
+
+const gchar *
+ParamEnum::set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node)
+{
+    return NULL;
+}
+
 
 }  /* namespace Extension */
 }  /* namespace Inkscape */