Code

Cleaned up more of the gboolean to bool janitorial task...great!
[inkscape.git] / src / extension / parameter.cpp
index 76163ac49b5654ee2a7ed5cee417da7378105dbe..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 {
 
+/** \brief  A description parameter */
+class ParamDescription : public Parameter {
+private:
+    /** \brief  Internal value. */
+    gchar * _value;
+public:
+    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);
+};
+
 /** \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) { return _value; }
-    bool set (bool in, Inkscape::XML::Document * doc);
-    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)
@@ -76,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) { return _value; }
-    int set (int in, Inkscape::XML::Document * doc);
+    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)
@@ -130,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) { return _value; }
-    float set (float in, Inkscape::XML::Document * doc);
+    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)
@@ -183,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) { return _value; }
-    const gchar * set (const gchar * in, Inkscape::XML::Document * doc);
-    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
@@ -221,28 +268,49 @@ 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);
-    } else if (!strcmp(type, "int")) { 
-        param = new ParamInt(name, guitext, in_ext, in_repr);
-    } else if (!strcmp(type, "float")) { 
-        param = new ParamFloat(name, guitext, in_ext, in_repr);
-    } else if (!strcmp(type, "string")) { 
-        param = new ParamString(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, desc, scope, in_ext, in_repr);
+    } else if (!strcmp(type, "float")) {
+        param = new ParamFloat(name, guitext, desc, scope, in_ext, in_repr);
+    } else if (!strcmp(type, "string")) {
+        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 */
     return param;
@@ -251,13 +319,14 @@ Parameter::make (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension *
 /** \brief  A function to set the \c _value
     \param  in   The value to set to
     \param  doc  A document that should be used to set the value.
+    \param  node The node where the value may be placed
 
     This function sets the internal value, but it also sets the value
     in the preferences structure.  To put it in the right place, \c PREF_DIR
     and \c pref_name() are used.
 */
 bool
-ParamBool::set (bool in, Inkscape::XML::Document * doc)
+ParamBool::set (bool in, SPDocument * doc, Inkscape::XML::Node * node)
 {
     _value = in;
 
@@ -271,13 +340,14 @@ ParamBool::set (bool in, Inkscape::XML::Document * doc)
 /** \brief  A function to set the \c _value
     \param  in   The value to set to
     \param  doc  A document that should be used to set the value.
+    \param  node The node where the value may be placed
 
     This function sets the internal value, but it also sets the value
     in the preferences structure.  To put it in the right place, \c PREF_DIR
     and \c pref_name() are used.
 */
 int
-ParamInt::set (int in, Inkscape::XML::Document * doc)
+ParamInt::set (int in, SPDocument * doc, Inkscape::XML::Node * node)
 {
     _value = in;
     if (_value > _max) _value = _max;
@@ -293,13 +363,14 @@ ParamInt::set (int in, Inkscape::XML::Document * doc)
 /** \brief  A function to set the \c _value
     \param  in   The value to set to
     \param  doc  A document that should be used to set the value.
+    \param  node The node where the value may be placed
 
     This function sets the internal value, but it also sets the value
     in the preferences structure.  To put it in the right place, \c PREF_DIR
     and \c pref_name() are used.
 */
 float
-ParamFloat::set (float in, Inkscape::XML::Document * doc)
+ParamFloat::set (float in, SPDocument * doc, Inkscape::XML::Node * node)
 {
     _value = in;
     if (_value > _max) _value = _max;
@@ -315,6 +386,7 @@ ParamFloat::set (float in, Inkscape::XML::Document * doc)
 /** \brief  A function to set the \c _value
     \param  in   The value to set to
     \param  doc  A document that should be used to set the value.
+    \param  node The node where the value may be placed
 
     This function sets the internal value, but it also sets the value
     in the preferences structure.  To put it in the right place, \c PREF_DIR
@@ -325,7 +397,7 @@ ParamFloat::set (float in, Inkscape::XML::Document * doc)
     the passed in value is duplicated using \c g_strdup().
 */
 const gchar *
-ParamString::set (const gchar * in, Inkscape::XML::Document * doc)
+ParamString::set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node)
 {
     if (in == NULL) return NULL; /* Can't have NULL string */
 
@@ -342,95 +414,95 @@ ParamString::set (const gchar * in, Inkscape::XML::Document * doc)
 
 /** \brief  Wrapper to cast to the object and use it's function.  */
 bool
-Parameter::get_bool (const Inkscape::XML::Document * doc)
+Parameter::get_bool (const SPDocument * doc, const Inkscape::XML::Node * node)
 {
     ParamBool * boolpntr;
     boolpntr = dynamic_cast<ParamBool *>(this);
     if (boolpntr == NULL)
         throw Extension::param_wrong_type();
-    return boolpntr->get(doc); 
+    return boolpntr->get(doc, node);
 }
 
 /** \brief  Wrapper to cast to the object and use it's function.  */
 int
-Parameter::get_int (const Inkscape::XML::Document * doc)
+Parameter::get_int (const SPDocument * doc, const Inkscape::XML::Node * node)
 {
     ParamInt * intpntr;
     intpntr = dynamic_cast<ParamInt *>(this);
     if (intpntr == NULL)
         throw Extension::param_wrong_type();
-    return intpntr->get(doc); 
+    return intpntr->get(doc, node);
 }
 
 /** \brief  Wrapper to cast to the object and use it's function.  */
 float
-Parameter::get_float (const Inkscape::XML::Document * doc)
+Parameter::get_float (const SPDocument * doc, const Inkscape::XML::Node * node)
 {
     ParamFloat * floatpntr;
     floatpntr = dynamic_cast<ParamFloat *>(this);
     if (floatpntr == NULL)
         throw Extension::param_wrong_type();
-    return floatpntr->get(doc); 
+    return floatpntr->get(doc, node);
 }
 
 /** \brief  Wrapper to cast to the object and use it's function.  */
 const gchar *
-Parameter::get_string (const Inkscape::XML::Document * doc)
+Parameter::get_string (const SPDocument * doc, const Inkscape::XML::Node * node)
 {
     ParamString * stringpntr;
     stringpntr = dynamic_cast<ParamString *>(this);
     if (stringpntr == NULL)
         throw Extension::param_wrong_type();
-    return stringpntr->get(doc); 
+    return stringpntr->get(doc, node);
 }
 
 /** \brief  Wrapper to cast to the object and use it's function.  */
 bool
-Parameter::set_bool (bool in, Inkscape::XML::Document * doc)
+Parameter::set_bool (bool in, SPDocument * doc, Inkscape::XML::Node * node)
 {
     ParamBool * boolpntr;
     boolpntr = dynamic_cast<ParamBool *>(this);
     if (boolpntr == NULL)
         throw Extension::param_wrong_type();
-    return boolpntr->set(in, doc); 
+    return boolpntr->set(in, doc, node);
 }
 
 /** \brief  Wrapper to cast to the object and use it's function.  */
 int
-Parameter::set_int (int in, Inkscape::XML::Document * doc)
+Parameter::set_int (int in, SPDocument * doc, Inkscape::XML::Node * node)
 {
     ParamInt * intpntr;
     intpntr = dynamic_cast<ParamInt *>(this);
     if (intpntr == NULL)
         throw Extension::param_wrong_type();
-    return intpntr->set(in, doc); 
+    return intpntr->set(in, doc, node);
 }
 
 /** \brief  Wrapper to cast to the object and use it's function.  */
 float
-Parameter::set_float (float in, Inkscape::XML::Document * doc)
+Parameter::set_float (float in, SPDocument * doc, Inkscape::XML::Node * node)
 {
     ParamFloat * floatpntr;
     floatpntr = dynamic_cast<ParamFloat *>(this);
     if (floatpntr == NULL)
         throw Extension::param_wrong_type();
-    return floatpntr->set(in, doc); 
+    return floatpntr->set(in, doc, node);
 }
 
 /** \brief  Wrapper to cast to the object and use it's function.  */
 const gchar *
-Parameter::set_string (const gchar * in, Inkscape::XML::Document * doc)
+Parameter::set_string (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node)
 {
     ParamString * stringpntr;
     stringpntr = dynamic_cast<ParamString *>(this);
     if (stringpntr == NULL)
         throw Extension::param_wrong_type();
-    return stringpntr->set(in, doc); 
+    return stringpntr->set(in, doc, node);
 }
 
 /** \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)
@@ -455,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. */
@@ -480,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;
 }
@@ -499,12 +624,14 @@ 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) {
-        this->set_value(_pref->get(NULL) /* \todo fix */); 
+    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;
     };
@@ -522,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 */);
+    _pref->set(this->get_value(), _doc, _node);
     return;
 }
 
@@ -530,12 +657,14 @@ 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) {
-        this->set_value(_pref->get(NULL) /* \todo fix */); 
+    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;
     };
@@ -553,26 +682,26 @@ void
 ParamIntAdjustment::val_changed (void)
 {
     // std::cout << "Value Changed to: " << this->get_value() << std::endl;
-    _pref->set((int)this->get_value(), NULL /* \todo fix */);
+    _pref->set((int)this->get_value(), _doc, _node);
     return;
 }
 
 /**
     \brief  Creates a Float Adjustment for a float parameter
-    
+
     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);
 
@@ -583,20 +712,20 @@ ParamFloat::get_widget (void)
 
 /**
     \brief  Creates a Int Adjustment for a int parameter
-    
+
     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);
 
@@ -612,16 +741,18 @@ 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
-        
+
         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) {
-        this->set_active(_pref->get(NULL) /**\todo fix */);
+    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;
     }
@@ -636,25 +767,25 @@ public:
 void
 ParamBoolCheckButton::on_toggle (void)
 {
-    _pref->set(this->get_active(), NULL /**\todo fix this */);
+    _pref->set(this->get_active(), NULL /**\todo fix this */, NULL);
     return;
 }
 
 /**
     \brief  Creates a bool check button for a bool parameter
-    
+
     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);
 
@@ -667,15 +798,17 @@ 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) {
-        if (_pref->get(NULL) != NULL)
-            this->set_text(Glib::ustring(_pref->get(NULL)));
+    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));
     };
     void changed_text (void);
@@ -690,27 +823,27 @@ void
 ParamStringEntry::changed_text (void)
 {
     Glib::ustring data = this->get_text();
-    _pref->set(data.c_str(), NULL);
+    _pref->set(data.c_str(), _doc, _node);
     return;
 }
 
 /**
     \brief  Creates a text box for the string parameter
-    
+
     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();
 
@@ -722,12 +855,12 @@ Glib::ustring *
 ParamBool::string (void)
 {
     Glib::ustring * mystring;
-    
-    if (_value) 
+
+    if (_value)
         mystring = new Glib::ustring("true");
     else
         mystring = new Glib::ustring("false");
-    
+
     return mystring;
 }
 
@@ -757,11 +890,75 @@ ParamString::string (void)
 {
     Glib::ustring * mystring = new Glib::ustring("");
     *mystring += "\"";
-    *mystring += _value; 
+    *mystring += _value;
     *mystring += "\"";
     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 */