summaryrefslogtreecommitdiffstats
path: root/src/extension/param
diff options
context:
space:
mode:
authorTed Gould <ted@gould.cx>2008-04-04 04:55:24 +0000
committergouldtj <gouldtj@users.sourceforge.net>2008-04-04 04:55:24 +0000
commit8a2ba4f29d0304fef7631e0efec8b10a2dc99121 (patch)
tree0eb2b0987084a55191da506c6c7e870bbe2d903d /src/extension/param
parent* packaging/macosx/ScriptExec/main.c: Add a comment to clarify what looks (diff)
downloadinkscape-8a2ba4f29d0304fef7631e0efec8b10a2dc99121.tar.gz
inkscape-8a2ba4f29d0304fef7631e0efec8b10a2dc99121.zip
r18381@shi: ted | 2008-03-07 20:11:34 -0800
New work branch r18391@shi: ted | 2008-03-08 21:36:03 -0800 Moving the parameters around to clean up the directories. r18392@shi: ted | 2008-03-08 21:57:14 -0800 Moving the 'get' function to cpp r18870@shi: ted | 2008-04-03 21:10:20 -0700 Adding in to the parameter prototype the ability to have a gui-tip and a gui-hidden parameter r18871@shi: ted | 2008-04-03 21:17:39 -0700 Using the _gui-hidden parameter to block the creation of the widget if set. r18890@shi: ted | 2008-04-03 21:53:55 -0700 Merge from r18024 which got lost in the shuffle. (bzr r5322)
Diffstat (limited to 'src/extension/param')
-rw-r--r--src/extension/param/bool.cpp152
-rw-r--r--src/extension/param/bool.h45
-rw-r--r--src/extension/param/color.cpp124
-rw-r--r--src/extension/param/color.h36
-rw-r--r--src/extension/param/description.cpp69
-rw-r--r--src/extension/param/description.h43
-rw-r--r--src/extension/param/enum.cpp258
-rw-r--r--src/extension/param/enum.h69
-rw-r--r--src/extension/param/float.cpp165
-rw-r--r--src/extension/param/float.h52
-rw-r--r--src/extension/param/int.cpp159
-rw-r--r--src/extension/param/int.h50
-rw-r--r--src/extension/param/notebook.cpp430
-rw-r--r--src/extension/param/notebook.h68
-rw-r--r--src/extension/param/parameter.cpp389
-rw-r--r--src/extension/param/parameter.h131
-rw-r--r--src/extension/param/radiobutton.cpp271
-rw-r--r--src/extension/param/radiobutton.h57
-rw-r--r--src/extension/param/string.cpp155
-rw-r--r--src/extension/param/string.h49
20 files changed, 2772 insertions, 0 deletions
diff --git a/src/extension/param/bool.cpp b/src/extension/param/bool.cpp
new file mode 100644
index 000000000..509ded032
--- /dev/null
+++ b/src/extension/param/bool.cpp
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2005-2007 Authors:
+ * Ted Gould <ted@gould.cx>
+ * Johan Engelen <johan@shouraizou.nl> *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <gtkmm/adjustment.h>
+#include <gtkmm/box.h>
+#include <gtkmm/spinbutton.h>
+
+#include <xml/node.h>
+
+#include "../extension.h"
+#include "bool.h"
+
+namespace Inkscape {
+namespace Extension {
+
+/** \brief Use the superclass' allocator and set the \c _value */
+ParamBool::ParamBool (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
+ Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, ext), _value(false)
+{
+ const char * defaultval = NULL;
+ if (sp_repr_children(xml) != NULL)
+ defaultval = sp_repr_children(xml)->content();
+
+ if (defaultval != NULL && (!strcmp(defaultval, "TRUE") || !strcmp(defaultval, "true") || !strcmp(defaultval, "1"))) {
+ _value = true;
+ } else {
+ _value = false;
+ }
+
+ gchar * pref_name = this->pref_name();
+ _value = (bool)prefs_get_int_attribute(PREF_DIR, pref_name, _value);
+ g_free(pref_name);
+
+ return;
+}
+
+/** \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, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/ )
+{
+ _value = in;
+
+ gchar * prefname = this->pref_name();
+ prefs_set_int_attribute(PREF_DIR, prefname, _value == true ? 1 : 0);
+ g_free(prefname);
+
+ return _value;
+}
+
+/** \brief Returns \c _value */
+bool
+ParamBool::get (const SPDocument * doc, const Inkscape::XML::Node * node)
+{
+ return _value;
+}
+
+/** \brief A check button which is Param aware. It works with the
+ parameter to change it's value as the check button changes
+ value. */
+class ParamBoolCheckButton : public Gtk::CheckButton {
+private:
+ /** \brief Param to change */
+ ParamBool * _pref;
+ SPDocument * _doc;
+ Inkscape::XML::Node * _node;
+ sigc::signal<void> * _changeSignal;
+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, SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal) :
+ Gtk::CheckButton(), _pref(param), _doc(doc), _node(node), _changeSignal(changeSignal) {
+ this->set_active(_pref->get(NULL, NULL) /**\todo fix */);
+ this->signal_toggled().connect(sigc::mem_fun(this, &ParamBoolCheckButton::on_toggle));
+ return;
+ }
+ void on_toggle (void);
+};
+
+/**
+ \brief A function to respond to the check box changing
+
+ Adjusts the value of the preference to match that in the check box.
+*/
+void
+ParamBoolCheckButton::on_toggle (void)
+{
+ _pref->set(this->get_active(), NULL /**\todo fix this */, NULL);
+ if (_changeSignal != NULL) {
+ _changeSignal->emit();
+ }
+ return;
+}
+
+/** \brief Return 'true' or 'false' */
+void
+ParamBool::string (std::string &string)
+{
+ if (_value) {
+ string += "true";
+ } else {
+ string += "false";
+ }
+
+ 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 (SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal)
+{
+ if (_gui_hidden) return NULL;
+ Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
+
+ 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, doc, node, changeSignal);
+ checkbox->show();
+ hbox->pack_start(*checkbox, false, false);
+
+ hbox->show();
+
+ return dynamic_cast<Gtk::Widget *>(hbox);
+}
+
+} /* namespace Extension */
+} /* namespace Inkscape */
diff --git a/src/extension/param/bool.h b/src/extension/param/bool.h
new file mode 100644
index 000000000..a1cd4ce4a
--- /dev/null
+++ b/src/extension/param/bool.h
@@ -0,0 +1,45 @@
+#ifndef __INK_EXTENSION_PARAMBOOL_H__
+#define __INK_EXTENSION_PARAMBOOL_H__
+/*
+ * Copyright (C) 2005-2007 Authors:
+ * Ted Gould <ted@gould.cx>
+ * Johan Engelen <johan@shouraizou.nl> *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <gtkmm/widget.h>
+#include <xml/node.h>
+#include <document.h>
+#include "parameter.h"
+
+namespace Inkscape {
+namespace Extension {
+
+/** \brief A boolean parameter */
+class ParamBool : public Parameter {
+private:
+ /** \brief Internal value. */
+ bool _value;
+public:
+ ParamBool(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
+ bool get (const SPDocument * doc, const Inkscape::XML::Node * node);
+ bool set (bool in, SPDocument * doc, Inkscape::XML::Node * node);
+ Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal);
+ void string (std::string &string);
+};
+
+} /* namespace Extension */
+} /* namespace Inkscape */
+
+#endif /* __INK_EXTENSION_PARAMBOOL_H__ */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/extension/param/color.cpp b/src/extension/param/color.cpp
new file mode 100644
index 000000000..845a04824
--- /dev/null
+++ b/src/extension/param/color.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2005-2007 Authors:
+ * Ted Gould <ted@gould.cx>
+ * Johan Engelen <johan@shouraizou.nl>
+ * Christopher Brown <audiere@gmail.com>
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <iostream>
+#include <sstream>
+
+#include <gtkmm/adjustment.h>
+#include <gtkmm/box.h>
+#include <gtkmm/spinbutton.h>
+
+#include <xml/node.h>
+
+#include "../extension.h"
+#include "color.h"
+
+#include <color.h>
+#include "widgets/sp-color-selector.h"
+#include "widgets/sp-color-notebook.h"
+
+
+namespace Inkscape {
+namespace Extension {
+
+void sp_color_param_changed(SPColorSelector *csel, GObject *cp);
+
+
+/** \brief Free the allocated data. */
+ParamColor::~ParamColor(void)
+{
+
+}
+
+guint32
+ParamColor::set( guint32 in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/ )
+{
+ _value = in;
+
+ gchar * prefname = this->pref_name();
+ std::string value;
+ string(value);
+ prefs_set_string_attribute(PREF_DIR, prefname, value.c_str());
+ g_free(prefname);
+
+ return _value;
+}
+
+/** \brief Initialize the object, to do that, copy the data. */
+ParamColor::ParamColor (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
+ Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, ext)
+{
+ const char * defaulthex = NULL;
+ if (sp_repr_children(xml) != NULL)
+ defaulthex = sp_repr_children(xml)->content();
+
+ gchar * pref_name = this->pref_name();
+ const gchar * paramval = prefs_get_string_attribute(PREF_DIR, pref_name);
+ g_free(pref_name);
+
+ if (paramval != NULL)
+ defaulthex = paramval;
+
+ _value = atoi(defaulthex);
+
+ return;
+}
+
+void
+ParamColor::string (std::string &string)
+{
+ char str[16];
+ sprintf(str, "%i", _value);
+ string += str;
+ return;
+}
+
+Gtk::Widget *
+ParamColor::get_widget( SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/, sigc::signal<void> * changeSignal )
+{
+ if (_gui_hidden) return NULL;
+
+ _changeSignal = new sigc::signal<void>(*changeSignal);
+ Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
+ SPColorSelector* spColorSelector = (SPColorSelector*)sp_color_selector_new(SP_TYPE_COLOR_NOTEBOOK);
+
+ ColorSelector* colorSelector = spColorSelector->base;
+ if (_value < 1) {
+ _value = 0xFF000000;
+ }
+ SPColor *color = new SPColor( _value );
+ float alpha = (_value & 0xff) / 255.0F;
+ colorSelector->setColorAlpha(*color, alpha);
+
+ hbox->pack_start (*Glib::wrap(&spColorSelector->vbox), true, true, 0);
+ g_signal_connect(G_OBJECT(spColorSelector), "changed", G_CALLBACK(sp_color_param_changed), (void*)this);
+
+ gtk_widget_show(GTK_WIDGET(spColorSelector));
+ hbox->show();
+
+ return dynamic_cast<Gtk::Widget *>(hbox);
+}
+
+void
+sp_color_param_changed(SPColorSelector *csel, GObject *obj)
+{
+ const SPColor color = csel->base->getColor();
+ float alpha = csel->base->getAlpha();
+
+ ParamColor* ptr = (ParamColor*)obj;
+ ptr->set(color.toRGBA32( alpha ), NULL, NULL);
+
+ ptr->_changeSignal->emit();
+}
+
+}; /* namespace Extension */
+}; /* namespace Inkscape */
diff --git a/src/extension/param/color.h b/src/extension/param/color.h
new file mode 100644
index 000000000..6836442a1
--- /dev/null
+++ b/src/extension/param/color.h
@@ -0,0 +1,36 @@
+#ifndef __INK_EXTENSION_PARAMCOLOR_H__
+#define __INK_EXTENSION_PARAMCOLOR_H__
+/*
+ * Copyright (C) 2005-2007 Authors:
+ * Ted Gould <ted@gould.cx>
+ * Johan Engelen <johan@shouraizou.nl> *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <gtkmm/widget.h>
+#include <xml/node.h>
+#include <document.h>
+#include <color.h>
+#include "parameter.h"
+
+namespace Inkscape {
+namespace Extension {
+
+class ParamColor : public Parameter {
+private:
+ guint32 _value;
+public:
+ ParamColor(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
+ virtual ~ParamColor(void);
+ /** \brief Returns \c _value, with a \i const to protect it. */
+ guint32 get( const SPDocument * /*doc*/, const Inkscape::XML::Node * /*node*/ ) { return _value; }
+ guint32 set (guint32 in, SPDocument * doc, Inkscape::XML::Node * node);
+ Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal);
+ void string (std::string &string);
+ sigc::signal<void> * _changeSignal;
+}; /* class ParamColor */
+
+} /* namespace Extension */
+} /* namespace Inkscape */
+
+#endif /* __INK_EXTENSION_PARAMCOLOR_H__ */
diff --git a/src/extension/param/description.cpp b/src/extension/param/description.cpp
new file mode 100644
index 000000000..61bfa9f5a
--- /dev/null
+++ b/src/extension/param/description.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2005-2007 Authors:
+ * Ted Gould <ted@gould.cx>
+ * Johan Engelen <johan@shouraizou.nl> *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef linux // does the dollar sign need escaping when passed as string parameter?
+# define ESCAPE_DOLLAR_COMMANDLINE
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+
+#include "description.h"
+
+#include <gtkmm/adjustment.h>
+#include <gtkmm/box.h>
+#include <gtkmm/spinbutton.h>
+#include <sstream>
+
+
+#include <glibmm/i18n.h>
+
+#include <xml/node.h>
+
+#include <extension/extension.h>
+#include <prefs-utils.h>
+
+namespace Inkscape {
+namespace Extension {
+
+
+/** \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, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
+ Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, 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;
+}
+
+/** \brief Create a label for the description */
+Gtk::Widget *
+ParamDescription::get_widget (SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/, sigc::signal<void> * /*changeSignal*/)
+{
+ if (_gui_hidden) return NULL;
+
+ 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;
+}
+
+} /* namespace Extension */
+} /* namespace Inkscape */
diff --git a/src/extension/param/description.h b/src/extension/param/description.h
new file mode 100644
index 000000000..c305ea6df
--- /dev/null
+++ b/src/extension/param/description.h
@@ -0,0 +1,43 @@
+#ifndef __INK_EXTENSION_PARAMDESCRIPTION_H__
+#define __INK_EXTENSION_PARAMDESCRIPTION_H__
+
+/*
+ * Copyright (C) 2005-2007 Authors:
+ * Ted Gould <ted@gould.cx>
+ * Johan Engelen <johan@shouraizou.nl> *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <gtkmm/widget.h>
+#include <xml/node.h>
+#include <document.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, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
+ Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal);
+};
+
+} /* namespace Extension */
+} /* namespace Inkscape */
+
+#endif /* __INK_EXTENSION_PARAMDESCRIPTION_H__ */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/extension/param/enum.cpp b/src/extension/param/enum.cpp
new file mode 100644
index 000000000..274220699
--- /dev/null
+++ b/src/extension/param/enum.cpp
@@ -0,0 +1,258 @@
+/** \file
+ * extension parameter for enumerations.
+ *
+ * It uses a Gtk:ComboBoxText widget in the extension UI.
+ */
+
+/*
+ * Author:
+ * Johan Engelen <johan@shouraizou.nl>
+ *
+ * Copyright (C) 2006-2007 Johan Engelen
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+
+#include <gtkmm/box.h>
+#include <gtkmm/comboboxtext.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/label.h>
+
+#include <glibmm/i18n.h>
+
+#include <xml/node.h>
+
+#include <extension/extension.h>
+#include <prefs-utils.h>
+#include <document-private.h>
+#include <sp-object.h>
+
+#include "enum.h"
+
+/** \brief The root directory in the preferences database for extension
+ related parameters. */
+#define PREF_DIR "extensions"
+
+namespace Inkscape {
+namespace Extension {
+
+/* For internal use only.
+ Note that value and guitext MUST be non-NULL. This is ensured by newing only at one location in the code where non-NULL checks are made. */
+class enumentry {
+public:
+ enumentry (Glib::ustring * val, Glib::ustring * text) {
+ value = val;
+ guitext = text;
+ }
+ ~enumentry() {
+ delete value;
+ delete guitext;
+ }
+
+ Glib::ustring * value;
+ Glib::ustring * guitext;
+};
+
+
+ParamComboBox::ParamComboBox (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
+ Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, ext)
+{
+ choices = NULL;
+ _value = NULL;
+
+ // Read XML tree to add enumeration items:
+ // printf("Extension Constructor: ");
+ if (xml != NULL) {
+ Inkscape::XML::Node *child_repr = sp_repr_children(xml);
+ while (child_repr != NULL) {
+ char const * chname = child_repr->name();
+ if (!strcmp(chname, "item") || !strcmp(chname, "_item")) {
+ Glib::ustring * newguitext = NULL;
+ Glib::ustring * newvalue = NULL;
+ const char * contents = sp_repr_children(child_repr)->content();
+ if (contents != NULL)
+ // don't translate when 'item' but do translate when '_item'
+ // NOTE: internal extensions use build_from_mem and don't need _item but
+ // still need to include if are to be localized
+ newguitext = new Glib::ustring( !strcmp(chname, "_item") ? _(contents) : contents );
+ else
+ continue;
+
+ const char * val = child_repr->attribute("value");
+ if (val != NULL)
+ newvalue = new Glib::ustring(val);
+ else
+ newvalue = new Glib::ustring(contents);
+
+ if ( (newguitext) && (newvalue) ) { // logical error if this is not true here
+ choices = g_slist_append( choices, new enumentry(newvalue, newguitext) );
+ }
+ }
+ child_repr = sp_repr_next(child_repr);
+ }
+ }
+
+ // Initialize _value with the default value from xml
+ // for simplicity : default to the contents of the first xml-child
+ const char * defaultval = NULL;
+ if (sp_repr_children(sp_repr_children(xml)) != NULL)
+ defaultval = sp_repr_children(xml)->attribute("value");
+
+ gchar * pref_name = this->pref_name();
+ const gchar * paramval = prefs_get_string_attribute(PREF_DIR, pref_name);
+ g_free(pref_name);
+
+ if (paramval != NULL)
+ defaultval = paramval;
+ if (defaultval != NULL)
+ _value = g_strdup(defaultval); // allocate space for _value
+
+ return;
+}
+
+ParamComboBox::~ParamComboBox (void)
+{
+ //destroy choice strings
+ for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
+ delete (reinterpret_cast<enumentry *>(list->data));
+ }
+ g_slist_free(choices);
+
+ g_free(_value);
+}
+
+
+/** \brief A function to set the \c _value
+ \param in The value to set
+ \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 ONLY 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.
+
+ To copy the data into _value the old memory must be free'd first.
+ It is important to note that \c g_free handles \c NULL just fine. Then
+ the passed in value is duplicated using \c g_strdup().
+*/
+const gchar *
+ParamComboBox::set (const gchar * in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/)
+{
+ if (in == NULL) return NULL; /* Can't have NULL string */
+
+ Glib::ustring * settext = NULL;
+ for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
+ enumentry * entr = reinterpret_cast<enumentry *>(list->data);
+ if ( !entr->guitext->compare(in) ) {
+ settext = entr->value;
+ break; // break out of for loop
+ }
+ }
+ if (settext) {
+ if (_value != NULL) g_free(_value);
+ _value = g_strdup(settext->c_str());
+ gchar * prefname = this->pref_name();
+ prefs_set_string_attribute(PREF_DIR, prefname, _value);
+ g_free(prefname);
+ }
+
+ return _value;
+}
+
+void
+ParamComboBox::changed (void) {
+
+}
+
+
+/**
+ \brief A function to get the value of the parameter in string form
+ \return A string with the 'value' as command line argument
+*/
+void
+ParamComboBox::string (std::string &string)
+{
+ string += _value;
+ return;
+}
+
+
+
+
+/** \brief A special category of Gtk::Entry to handle string parameteres */
+class ParamComboBoxEntry : public Gtk::ComboBoxText {
+private:
+ ParamComboBox * _pref;
+ SPDocument * _doc;
+ Inkscape::XML::Node * _node;
+ sigc::signal<void> * _changeSignal;
+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.
+ */
+ ParamComboBoxEntry (ParamComboBox * pref, SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal) :
+ Gtk::ComboBoxText(), _pref(pref), _doc(doc), _node(node), _changeSignal(changeSignal) {
+ this->signal_changed().connect(sigc::mem_fun(this, &ParamComboBoxEntry::changed));
+ };
+ void changed (void);
+};
+
+/** \brief Respond to the text box changing
+
+ This function responds to the box changing by grabbing the value
+ from the text box and putting it in the parameter.
+*/
+void
+ParamComboBoxEntry::changed (void)
+{
+ Glib::ustring data = this->get_active_text();
+ _pref->set(data.c_str(), _doc, _node);
+ if (_changeSignal != NULL) {
+ _changeSignal->emit();
+ }
+}
+
+/**
+ \brief Creates a combobox widget for an enumeration parameter
+*/
+Gtk::Widget *
+ParamComboBox::get_widget (SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal)
+{
+ if (_gui_hidden) return NULL;
+
+ Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
+
+ Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
+ label->show();
+ hbox->pack_start(*label, false, false);
+
+ ParamComboBoxEntry * combo = Gtk::manage(new ParamComboBoxEntry(this, doc, node, changeSignal));
+ // add choice strings:
+ Glib::ustring * settext = 0;
+ for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
+ enumentry * entr = reinterpret_cast<enumentry *>(list->data);
+ Glib::ustring * text = entr->guitext;
+ combo->append_text(*text);
+ if ( !entr->value->compare(_value) ) {
+ settext = entr->guitext;
+ }
+ }
+ if (settext) combo->set_active_text(*settext);
+
+ combo->show();
+ hbox->pack_start(*combo, true, true);
+
+ hbox->show();
+
+ return dynamic_cast<Gtk::Widget *>(hbox);
+}
+
+
+} /* namespace Extension */
+} /* namespace Inkscape */
diff --git a/src/extension/param/enum.h b/src/extension/param/enum.h
new file mode 100644
index 000000000..3f9707c34
--- /dev/null
+++ b/src/extension/param/enum.h
@@ -0,0 +1,69 @@
+#ifndef INK_EXTENSION_PARAMENUM_H_SEEN
+#define INK_EXTENSION_PARAMENUM_H_SEEN
+
+/** \file
+ * Enumeration parameter for extensions.
+ */
+
+/*
+ * Author:
+ * Johan Engelen <johan@shouraizou.nl>
+ *
+ * Copyright (C) 2006-2007 Johan Engelen
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <gtkmm/widget.h>
+
+#include "xml/document.h"
+#include <extension/extension-forward.h>
+
+#include "parameter.h"
+
+namespace Inkscape {
+namespace Extension {
+
+
+
+// \brief A class to represent a notebookparameter of an extension
+class ParamComboBox : public Parameter {
+private:
+ /** \brief Internal value. This should point to a string that has
+ been allocated in memory. And should be free'd.
+ It is the value of the current selected string */
+ gchar * _value;
+
+ GSList * choices; /**< A table to store the choice strings */
+
+public:
+ ParamComboBox(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
+ virtual ~ParamComboBox(void);
+ Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal);
+ void string (std::string &string);
+
+ 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);
+
+ void changed (void);
+}; /* class ParamComboBox */
+
+
+
+
+
+} /* namespace Extension */
+} /* namespace Inkscape */
+
+#endif /* INK_EXTENSION_PARAMENUM_H_SEEN */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/extension/param/float.cpp b/src/extension/param/float.cpp
new file mode 100644
index 000000000..1225648d6
--- /dev/null
+++ b/src/extension/param/float.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright (C) 2005-2007 Authors:
+ * Ted Gould <ted@gould.cx>
+ * Johan Engelen <johan@shouraizou.nl> *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <gtkmm/adjustment.h>
+#include <gtkmm/box.h>
+#include <gtkmm/spinbutton.h>
+
+#include <xml/node.h>
+
+#include <extension/extension.h>
+#include "float.h"
+
+namespace Inkscape {
+namespace Extension {
+
+
+/** \brief Use the superclass' allocator and set the \c _value */
+ParamFloat::ParamFloat (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
+ Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, ext), _value(0.0), _min(0.0), _max(10.0)
+{
+ const char * defaultval = NULL;
+ if (sp_repr_children(xml) != NULL)
+ defaultval = sp_repr_children(xml)->content();
+ if (defaultval != NULL) {
+ _value = atof(defaultval);
+ }
+
+ const char * maxval = xml->attribute("max");
+ if (maxval != NULL)
+ _max = atof(maxval);
+
+ const char * minval = xml->attribute("min");
+ if (minval != NULL)
+ _min = atof(minval);
+
+ _precision = 1;
+ const char * precision = xml->attribute("precision");
+ if (precision != NULL)
+ _precision = atoi(precision);
+
+ /* We're handling this by just killing both values */
+ if (_max < _min) {
+ _max = 10.0;
+ _min = 0.0;
+ }
+
+ gchar * pref_name = this->pref_name();
+ _value = prefs_get_double_attribute(PREF_DIR, pref_name, _value);
+ g_free(pref_name);
+
+ // std::cout << "New Float:: value: " << _value << " max: " << _max << " min: " << _min << std::endl;
+
+ if (_value > _max) _value = _max;
+ if (_value < _min) _value = _min;
+
+ return;
+}
+
+/** \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, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/)
+{
+ _value = in;
+ if (_value > _max) _value = _max;
+ if (_value < _min) _value = _min;
+
+ gchar * prefname = this->pref_name();
+ prefs_set_double_attribute(PREF_DIR, prefname, _value);
+ g_free(prefname);
+
+ return _value;
+}
+
+/** \brief Return the value as a string */
+void
+ParamFloat::string (std::string &string)
+{
+ char startstring[G_ASCII_DTOSTR_BUF_SIZE];
+ g_ascii_dtostr(startstring, G_ASCII_DTOSTR_BUF_SIZE, _value);
+ string += startstring;
+ return;
+}
+
+/** \brief A class to make an adjustment that uses Extension params */
+class ParamFloatAdjustment : public Gtk::Adjustment {
+ /** The parameter to adjust */
+ ParamFloat * _pref;
+ SPDocument * _doc;
+ Inkscape::XML::Node * _node;
+ sigc::signal<void> * _changeSignal;
+public:
+ /** \brief Make the adjustment using an extension and the string
+ describing the parameter. */
+ ParamFloatAdjustment (ParamFloat * param, SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal) :
+ Gtk::Adjustment(0.0, param->min(), param->max(), 0.1), _pref(param), _doc(doc), _node(node), _changeSignal(changeSignal) {
+ this->set_value(_pref->get(NULL, NULL) /* \todo fix */);
+ this->signal_value_changed().connect(sigc::mem_fun(this, &ParamFloatAdjustment::val_changed));
+ return;
+ };
+
+ void val_changed (void);
+}; /* class ParamFloatAdjustment */
+
+/** \brief A function to respond to the value_changed signal from the
+ adjustment.
+
+ This function just grabs the value from the adjustment and writes
+ it to the parameter. Very simple, but yet beautiful.
+*/
+void
+ParamFloatAdjustment::val_changed (void)
+{
+ //std::cout << "Value Changed to: " << this->get_value() << std::endl;
+ _pref->set(this->get_value(), _doc, _node);
+ if (_changeSignal != NULL) {
+ _changeSignal->emit();
+ }
+ 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 (SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal)
+{
+ if (_gui_hidden) return NULL;
+
+ Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
+
+ Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
+ label->show();
+ hbox->pack_start(*label, true, true);
+
+ ParamFloatAdjustment * fadjust = Gtk::manage(new ParamFloatAdjustment(this, doc, node, changeSignal));
+ Gtk::SpinButton * spin = Gtk::manage(new Gtk::SpinButton(*fadjust, 0.1, _precision));
+ spin->show();
+ hbox->pack_start(*spin, false, false);
+
+ hbox->show();
+
+ return dynamic_cast<Gtk::Widget *>(hbox);
+}
+
+
+} /* namespace Extension */
+} /* namespace Inkscape */
diff --git a/src/extension/param/float.h b/src/extension/param/float.h
new file mode 100644
index 000000000..f105d8f0e
--- /dev/null
+++ b/src/extension/param/float.h
@@ -0,0 +1,52 @@
+#ifndef INK_EXTENSION_PARAMFLOAT_H_SEEN
+#define INK_EXTENSION_PARAMFLOAT_H_SEEN
+
+/*
+ * Copyright (C) 2005-2007 Authors:
+ * Ted Gould <ted@gould.cx>
+ * Johan Engelen <johan@shouraizou.nl> *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <gtkmm/widget.h>
+#include <xml/node.h>
+#include <document.h>
+#include "parameter.h"
+
+namespace Inkscape {
+namespace Extension {
+
+class ParamFloat : public Parameter {
+private:
+ /** \brief Internal value. */
+ float _value;
+ float _min;
+ float _max;
+ int _precision;
+public:
+ ParamFloat (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
+ /** \brief Returns \c _value */
+ 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; }
+ float precision (void) { return _precision; }
+ Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal);
+ void string (std::string &string);
+};
+
+} /* namespace Extension */
+} /* namespace Inkscape */
+
+#endif /* INK_EXTENSION_PARAMFLOAT_H_SEEN */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/extension/param/int.cpp b/src/extension/param/int.cpp
new file mode 100644
index 000000000..dc523435e
--- /dev/null
+++ b/src/extension/param/int.cpp
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2005-2007 Authors:
+ * Ted Gould <ted@gould.cx>
+ * Johan Engelen <johan@shouraizou.nl> *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <gtkmm/adjustment.h>
+#include <gtkmm/box.h>
+#include <gtkmm/spinbutton.h>
+
+#include <xml/node.h>
+
+#include <extension/extension.h>
+#include "int.h"
+
+namespace Inkscape {
+namespace Extension {
+
+
+/** \brief Use the superclass' allocator and set the \c _value */
+ParamInt::ParamInt (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
+ Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, ext), _value(0), _min(0), _max(10)
+{
+ const char * defaultval = NULL;
+ if (sp_repr_children(xml) != NULL)
+ defaultval = sp_repr_children(xml)->content();
+ if (defaultval != NULL) {
+ _value = atoi(defaultval);
+ }
+
+ const char * maxval = xml->attribute("max");
+ if (maxval != NULL)
+ _max = atoi(maxval);
+
+ const char * minval = xml->attribute("min");
+ if (minval != NULL)
+ _min = atoi(minval);
+
+ /* We're handling this by just killing both values */
+ if (_max < _min) {
+ _max = 10;
+ _min = 0;
+ }
+
+ gchar * pref_name = this->pref_name();
+ _value = prefs_get_int_attribute(PREF_DIR, pref_name, _value);
+ g_free(pref_name);
+
+ // std::cout << "New Int:: value: " << _value << " max: " << _max << " min: " << _min << std::endl;
+
+ if (_value > _max) _value = _max;
+ if (_value < _min) _value = _min;
+
+ return;
+}
+
+/** \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, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/)
+{
+ _value = in;
+ if (_value > _max) _value = _max;
+ if (_value < _min) _value = _min;
+
+ gchar * prefname = this->pref_name();
+ prefs_set_int_attribute(PREF_DIR, prefname, _value);
+ g_free(prefname);
+
+ return _value;
+}
+
+/** \brief A class to make an adjustment that uses Extension params */
+class ParamIntAdjustment : public Gtk::Adjustment {
+ /** The parameter to adjust */
+ ParamInt * _pref;
+ SPDocument * _doc;
+ Inkscape::XML::Node * _node;
+ sigc::signal<void> * _changeSignal;
+public:
+ /** \brief Make the adjustment using an extension and the string
+ describing the parameter. */
+ ParamIntAdjustment (ParamInt * param, SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal) :
+ Gtk::Adjustment(0.0, param->min(), param->max(), 1.0), _pref(param), _doc(doc), _node(node), _changeSignal(changeSignal) {
+ this->set_value(_pref->get(NULL, NULL) /* \todo fix */);
+ this->signal_value_changed().connect(sigc::mem_fun(this, &ParamIntAdjustment::val_changed));
+ return;
+ };
+
+ void val_changed (void);
+}; /* class ParamIntAdjustment */
+
+/** \brief A function to respond to the value_changed signal from the
+ adjustment.
+
+ This function just grabs the value from the adjustment and writes
+ it to the parameter. Very simple, but yet beautiful.
+*/
+void
+ParamIntAdjustment::val_changed (void)
+{
+ //std::cout << "Value Changed to: " << this->get_value() << std::endl;
+ _pref->set((int)this->get_value(), _doc, _node);
+ if (_changeSignal != NULL) {
+ _changeSignal->emit();
+ }
+ return;
+}
+
+/**
+ \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 (SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal)
+{
+ if (_gui_hidden) return NULL;
+
+ Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
+
+ Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
+ label->show();
+ hbox->pack_start(*label, true, true);
+
+ ParamIntAdjustment * fadjust = Gtk::manage(new ParamIntAdjustment(this, doc, node, changeSignal));
+ Gtk::SpinButton * spin = Gtk::manage(new Gtk::SpinButton(*fadjust, 1.0, 0));
+ spin->show();
+ hbox->pack_start(*spin, false, false);
+
+ hbox->show();
+
+ return dynamic_cast<Gtk::Widget *>(hbox);
+}
+
+/** \brief Return the value as a string */
+void
+ParamInt::string (std::string &string)
+{
+ char startstring[32];
+ sprintf(startstring, "%d", _value);
+ string += startstring;
+ return;
+}
+
+} /* namespace Extension */
+} /* namespace Inkscape */
diff --git a/src/extension/param/int.h b/src/extension/param/int.h
new file mode 100644
index 000000000..a4eb54c81
--- /dev/null
+++ b/src/extension/param/int.h
@@ -0,0 +1,50 @@
+#ifndef INK_EXTENSION_PARAMINT_H_SEEN
+#define INK_EXTENSION_PARAMINT_H_SEEN
+
+/*
+ * Copyright (C) 2005-2007 Authors:
+ * Ted Gould <ted@gould.cx>
+ * Johan Engelen <johan@shouraizou.nl> *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <gtkmm/widget.h>
+#include <xml/node.h>
+#include <document.h>
+#include "parameter.h"
+
+namespace Inkscape {
+namespace Extension {
+
+class ParamInt : public Parameter {
+private:
+ /** \brief Internal value. */
+ int _value;
+ int _min;
+ int _max;
+public:
+ ParamInt (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
+ /** \brief Returns \c _value */
+ 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(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal);
+ void string (std::string &string);
+};
+
+} /* namespace Extension */
+} /* namespace Inkscape */
+
+#endif /* INK_EXTENSION_PARAMINT_H_SEEN */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/extension/param/notebook.cpp b/src/extension/param/notebook.cpp
new file mode 100644
index 000000000..5c4f96759
--- /dev/null
+++ b/src/extension/param/notebook.cpp
@@ -0,0 +1,430 @@
+/** \file
+ * Notebook and NotebookPage parameters for extensions.
+ */
+
+/*
+ * Author:
+ * Johan Engelen <johan@shouraizou.nl>
+ *
+ * Copyright (C) 2006 Author
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+
+#include <gtkmm/adjustment.h>
+#include <gtkmm/box.h>
+#include <gtkmm/spinbutton.h>
+#include <gtkmm/notebook.h>
+#include <gtkmm/tooltips.h>
+
+#include <glibmm/i18n.h>
+
+#include <xml/node.h>
+
+#include <extension/extension.h>
+#include "prefs-utils.h"
+#include "document-private.h"
+#include "sp-object.h"
+
+#include "notebook.h"
+
+/** \brief The root directory in the preferences database for extension
+ related parameters. */
+#define PREF_DIR "extensions"
+
+namespace Inkscape {
+namespace Extension {
+
+
+// \brief A class to represent the pages of a notebookparameter of an extension
+class ParamNotebookPage : public Parameter {
+private:
+ GSList * parameters; /**< A table to store the parameters for this page.
+ This only gets created if there are parameters on this
+ page */
+ Gtk::Tooltips * _tooltips;
+
+public:
+ static ParamNotebookPage * makepage (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext);
+
+ ParamNotebookPage(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
+ ~ParamNotebookPage(void);
+ Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal);
+ void paramString (std::list <std::string> &list);
+ gchar * get_guitext (void) {return _text;};
+
+}; /* class ParamNotebookPage */
+
+
+ParamNotebookPage::ParamNotebookPage (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
+ Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, ext)
+{
+ parameters = NULL;
+
+ // Read XML to build page
+ if (xml != NULL) {
+ Inkscape::XML::Node *child_repr = sp_repr_children(xml);
+ while (child_repr != NULL) {
+ char const * chname = child_repr->name();
+ if (chname[0] == '_') // Allow _ for translation of tags
+ chname++;
+ if (!strcmp(chname, "param") || !strcmp(chname, "_param")) {
+ Parameter * param;
+ param = Parameter::make(child_repr, ext);
+ if (param != NULL) parameters = g_slist_append(parameters, param);
+ }
+ child_repr = sp_repr_next(child_repr);
+ }
+ }
+
+ return;
+}
+
+ParamNotebookPage::~ParamNotebookPage (void)
+{
+ if (_tooltips) delete _tooltips;
+ //destroy parameters
+ for (GSList * list = parameters; list != NULL; list = g_slist_next(list)) {
+ Parameter * param = reinterpret_cast<Parameter *>(list->data);
+ delete param;
+ }
+ g_slist_free(parameters);
+}
+
+/** \brief Return the value as a string */
+void
+ParamNotebookPage::paramString (std::list <std::string> &list)
+{
+ for (GSList * plist = parameters; plist != NULL; plist = g_slist_next(plist)) {
+ Parameter * param = reinterpret_cast<Parameter *>(plist->data);
+ param->string(list);
+ }
+
+ return;
+}
+
+
+/**
+ \return None
+ \brief This function creates a page that can be used later. This
+ is typically done in the creation of the notebook and defined
+ in the XML file describing the extension (it's private so people
+ have to use the system) :)
+ \param in_repr The XML describing the page
+
+ This function first grabs all of the data out of the Repr and puts
+ it into local variables. Actually, these are just pointers, and the
+ data is not duplicated so we need to be careful with it. If there
+ isn't a name in the XML, then no page is created as
+ the function just returns.
+
+ From this point on, we're pretty committed as we've allocated an
+ object and we're starting to fill it. The name is set first, and
+ is created with a strdup to actually allocate memory for it. Then
+ there is a case statement (roughly because strcmp requires 'ifs')
+ based on what type of parameter this is. Depending which type it
+ is, the value is interpreted differently, but they are relatively
+ straight forward. In all cases the value is set to the default
+ value from the XML and the type is set to the interpreted type.
+*/
+ParamNotebookPage *
+ParamNotebookPage::makepage (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext)
+{
+ const char * name;
+ const char * guitext;
+ const char * desc;
+ const char * scope_str;
+ Parameter::_scope_t scope = Parameter::SCOPE_USER;
+ bool gui_hidden = false;
+ const char * gui_hide;
+ const char * gui_tip;
+
+ name = in_repr->attribute("name");
+ guitext = in_repr->attribute("gui-text");
+ if (guitext == NULL)
+ guitext = in_repr->attribute("_gui-text");
+ gui_tip = in_repr->attribute("gui-tip");
+ if (gui_tip == NULL)
+ gui_tip = in_repr->attribute("_gui-tip");
+ desc = in_repr->attribute("gui-description");
+ if (desc == NULL)
+ desc = in_repr->attribute("_gui-description");
+ scope_str = in_repr->attribute("scope");
+ gui_hide = in_repr->attribute("gui-hidden");
+ if (gui_hide != NULL) {
+ if (strcmp(gui_hide, "1") == 0 ||
+ strcmp(gui_hide, "true") == 0) {
+ gui_hidden = true;
+ }
+ /* else stays false */
+ }
+
+ /* In this case we just don't have enough information */
+ if (name == 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;
+ }
+ }
+
+ ParamNotebookPage * page = new ParamNotebookPage(name, guitext, desc, scope, gui_hide, gui_tip, in_ext, in_repr);
+
+ /* Note: page could equal NULL */
+ return page;
+}
+
+
+
+/**
+ \brief Creates a notebookpage widget for a notebook
+
+ Builds a notebook page (a vbox) and puts parameters on it.
+*/
+Gtk::Widget *
+ParamNotebookPage::get_widget (SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal)
+{
+ if (_gui_hidden) return NULL;
+
+ if (!_tooltips) _tooltips = new Gtk::Tooltips();
+
+ Gtk::VBox * vbox = Gtk::manage(new Gtk::VBox);
+ vbox->set_border_width(5);
+
+ // add parameters onto page (if any)
+ for (GSList * list = parameters; list != NULL; list = g_slist_next(list)) {
+ Parameter * param = reinterpret_cast<Parameter *>(list->data);
+ Gtk::Widget * widg = param->get_widget(doc, node, changeSignal);
+ gchar const * tip = param->get_tooltip();
+
+ vbox->pack_start(*widg, true, true, 2);
+ if (tip != NULL) {
+ _tooltips->set_tip(*widg, Glib::ustring(tip));
+ }
+ }
+
+ vbox->show();
+
+ return dynamic_cast<Gtk::Widget *>(vbox);
+}
+
+
+
+
+
+
+
+
+
+ParamNotebook::ParamNotebook (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
+ Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, ext)
+{
+ pages = NULL;
+
+ // Read XML tree to add pages:
+ if (xml != NULL) {
+ Inkscape::XML::Node *child_repr = sp_repr_children(xml);
+ while (child_repr != NULL) {
+ char const * chname = child_repr->name();
+ if (chname[0] == '_') // Allow _ for translation of tags
+ chname++;
+ if (!strcmp(chname, "page")) {
+ ParamNotebookPage * page;
+ page = ParamNotebookPage::makepage(child_repr, ext);
+ if (page != NULL) pages = g_slist_append(pages, page);
+ }
+ child_repr = sp_repr_next(child_repr);
+ }
+ }
+
+ // Initialize _value with the current page
+ const char * defaultval = NULL;
+ // set first page as default
+ if (pages != NULL) {
+ ParamNotebookPage * defpage = reinterpret_cast<ParamNotebookPage *>(pages->data);
+ defaultval = defpage->name();
+ }
+
+ gchar * pref_name = this->pref_name();
+ const gchar * paramval = prefs_get_string_attribute(PREF_DIR, pref_name);
+ g_free(pref_name);
+
+ if (paramval != NULL)
+ defaultval = paramval;
+ if (defaultval != NULL)
+ _value = g_strdup(defaultval); // allocate space for _value
+
+ return;
+}
+
+ParamNotebook::~ParamNotebook (void)
+{
+ //destroy pages
+ for (GSList * list = pages; list != NULL; list = g_slist_next(list)) {
+ ParamNotebookPage * page = reinterpret_cast<ParamNotebookPage *>(list->data);
+ delete page;
+ }
+ g_slist_free(pages);
+
+ g_free(_value);
+}
+
+
+/** \brief A function to set the \c _value
+ \param in The number of the page which value must be set
+ \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.
+
+ To copy the data into _value the old memory must be free'd first.
+ It is important to note that \c g_free handles \c NULL just fine. Then
+ the passed in value is duplicated using \c g_strdup().
+*/
+const gchar *
+ParamNotebook::set (const int in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/)
+{
+ ParamNotebookPage * page = NULL;
+ int i = 0;
+ for (GSList * list = pages; (list != NULL) && (i <= in); list = g_slist_next(list)) {
+ page = reinterpret_cast<ParamNotebookPage *>(list->data);
+ i++;
+ }
+
+ if (page == NULL) return _value;
+
+ if (_value != NULL) g_free(_value);
+ _value = g_strdup(page->name());
+
+ gchar * prefname = this->pref_name();
+ prefs_set_string_attribute(PREF_DIR, prefname, _value);
+ g_free(prefname);
+
+ return _value;
+}
+
+
+/**
+ \brief A function to get the currentpage and the parameters in a string form
+ \return A string with the 'value' and all the parameters on all pages as command line arguments
+*/
+void
+ParamNotebook::string (std::list <std::string> &list)
+{
+ std::string param_string;
+ param_string += "--";
+ param_string += name();
+ param_string += "=";
+
+ param_string += "\"";
+ param_string += _value; // the name of the current page
+ param_string += "\"";
+ list.insert(list.end(), param_string);
+
+ for (GSList * pglist = pages; pglist != NULL; pglist = g_slist_next(pglist)) {
+ ParamNotebookPage * page = reinterpret_cast<ParamNotebookPage *>(pglist->data);
+ page->paramString(list);
+ }
+
+ return;
+}
+
+/** \brief A special category of Gtk::Notebook to handle notebook parameters */
+class ParamNotebookWdg : public Gtk::Notebook {
+private:
+ ParamNotebook * _pref;
+ SPDocument * _doc;
+ Inkscape::XML::Node * _node;
+public:
+ /** \brief Build a notebookpage preference for the given parameter
+ \param pref Where to get the string (pagename) from, and where to put it
+ when it changes.
+ */
+ ParamNotebookWdg (ParamNotebook * pref, SPDocument * doc, Inkscape::XML::Node * node) :
+ Gtk::Notebook(), _pref(pref), _doc(doc), _node(node), activated(false) {
+ // don't have to set the correct page: this is done in ParamNotebook::get_widget.
+ // hook function
+ this->signal_switch_page().connect(sigc::mem_fun(this, &ParamNotebookWdg::changed_page));
+ return;
+ };
+ void changed_page(GtkNotebookPage *page, guint pagenum);
+ bool activated;
+};
+
+/** \brief Respond to the selected page of notebook changing
+ This function responds to the changing by reporting it to
+ ParamNotebook. The change is only reported when the notebook
+ is actually visible. This to exclude 'fake' changes when the
+ notebookpages are added or removed.
+*/
+void
+ParamNotebookWdg::changed_page(GtkNotebookPage */*page*/,
+ guint pagenum)
+{
+ if (is_visible()) {
+ _pref->set((int)pagenum, _doc, _node);
+ }
+ return;
+}
+
+
+
+/**
+ \brief Creates a Notebook widget for a notebook parameter
+
+ Builds a notebook and puts pages in it.
+*/
+Gtk::Widget *
+ParamNotebook::get_widget (SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal)
+{
+ if (_gui_hidden) return NULL;
+
+ ParamNotebookWdg * nb = Gtk::manage(new ParamNotebookWdg(this, doc, node));
+
+ // add pages (if any)
+ int i = -1;
+ int pagenr = i;
+ for (GSList * list = pages; list != NULL; list = g_slist_next(list)) {
+ i++;
+ ParamNotebookPage * page = reinterpret_cast<ParamNotebookPage *>(list->data);
+ Gtk::Widget * widg = page->get_widget(doc, node, changeSignal);
+ nb->append_page(*widg, _(page->get_guitext()));
+ if (!strcmp(_value, page->name())) {
+ pagenr = i; // this is the page to be displayed?
+ }
+ }
+
+ nb->show();
+
+ if (pagenr >= 0) nb->set_current_page(pagenr);
+
+ return dynamic_cast<Gtk::Widget *>(nb);
+}
+
+
+} /* namespace Extension */
+} /* namespace Inkscape */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/extension/param/notebook.h b/src/extension/param/notebook.h
new file mode 100644
index 000000000..24d4ebfc1
--- /dev/null
+++ b/src/extension/param/notebook.h
@@ -0,0 +1,68 @@
+#ifndef INK_EXTENSION_PARAMNOTEBOOK_H_SEEN
+#define INK_EXTENSION_PARAMNOTEBOOK_H_SEEN
+
+/** \file
+ * Notebook parameter for extensions.
+ */
+
+/*
+ * Author:
+ * Johan Engelen <johan@shouraizou.nl>
+ *
+ * Copyright (C) 2006 Author
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <gtkmm/widget.h>
+
+#include "xml/document.h"
+#include <extension/extension-forward.h>
+
+#include "parameter.h"
+
+namespace Inkscape {
+namespace Extension {
+
+
+
+// \brief A class to represent a notebookparameter of an extension
+class ParamNotebook : public Parameter {
+private:
+ /** \brief Internal value. This should point to a string that has
+ been allocated in memory. And should be free'd.
+ It is the name of the current page. */
+ gchar * _value;
+
+ GSList * pages; /**< A table to store the pages with parameters for this notebook.
+ This only gets created if there are pages in this
+ notebook */
+public:
+ ParamNotebook(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
+ virtual ~ParamNotebook(void);
+ Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal);
+ void string (std::list <std::string> &list);
+
+ const gchar * get (const SPDocument * /*doc*/, const Inkscape::XML::Node * /*node*/) { return _value; }
+ const gchar * set (const int in, SPDocument * doc, Inkscape::XML::Node * node);
+}; /* class ParamNotebook */
+
+
+
+
+
+} /* namespace Extension */
+} /* namespace Inkscape */
+
+#endif /* INK_EXTENSION_PARAMNOTEBOOK_H_SEEN */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/extension/param/parameter.cpp b/src/extension/param/parameter.cpp
new file mode 100644
index 000000000..7e071e7e3
--- /dev/null
+++ b/src/extension/param/parameter.cpp
@@ -0,0 +1,389 @@
+/** \file
+ * Parameters for extensions.
+ */
+
+/*
+ * Author:
+ * Ted Gould <ted@gould.cx>
+ * Johan Engelen <johan@shouraizou.nl>
+ *
+ * Copyright (C) 2005-2007 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#ifdef linux // does the dollar sign need escaping when passed as string parameter?
+# define ESCAPE_DOLLAR_COMMANDLINE
+#endif
+
+#include <gtkmm/adjustment.h>
+#include <gtkmm/box.h>
+#include <gtkmm/spinbutton.h>
+
+#include <xml/node.h>
+
+#include <extension/extension.h>
+#include "document-private.h"
+#include "sp-object.h"
+#include <color.h>
+#include "widgets/sp-color-selector.h"
+#include "widgets/sp-color-notebook.h"
+
+#include "parameter.h"
+#include "bool.h"
+#include "color.h"
+#include "description.h"
+#include "enum.h"
+#include "float.h"
+#include "int.h"
+#include "notebook.h"
+#include "radiobutton.h"
+#include "string.h"
+
+namespace Inkscape {
+namespace Extension {
+
+/**
+ \return None
+ \brief This function creates a parameter that can be used later. This
+ is typically done in the creation of the extension and defined
+ in the XML file describing the extension (it's private so people
+ have to use the system) :)
+ \param in_repr The XML describing the parameter
+
+ This function first grabs all of the data out of the Repr and puts
+ it into local variables. Actually, these are just pointers, and the
+ data is not duplicated so we need to be careful with it. If there
+ isn't a name or a type in the XML, then no parameter is created as
+ the function just returns.
+
+ From this point on, we're pretty committed as we've allocated an
+ object and we're starting to fill it. The name is set first, and
+ is created with a strdup to actually allocate memory for it. Then
+ there is a case statement (roughly because strcmp requires 'ifs')
+ based on what type of parameter this is. Depending which type it
+ is, the value is interpreted differently, but they are relatively
+ straight forward. In all cases the value is set to the default
+ value from the XML and the type is set to the interpreted type.
+*/
+Parameter *
+Parameter::make (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext)
+{
+ const char * name;
+ const char * type;
+ const char * guitext;
+ const char * desc;
+ const char * scope_str;
+ Parameter::_scope_t scope = Parameter::SCOPE_USER;
+ bool gui_hidden = false;
+ const char * gui_hide;
+ const char * gui_tip;
+
+ 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");
+ gui_tip = in_repr->attribute("gui-tip");
+ if (gui_tip == NULL)
+ gui_tip = in_repr->attribute("_gui-tip");
+ desc = in_repr->attribute("gui-description");
+ if (desc == NULL)
+ desc = in_repr->attribute("_gui-description");
+ scope_str = in_repr->attribute("scope");
+ gui_hide = in_repr->attribute("gui-hidden");
+ if (gui_hide != NULL) {
+ if (strcmp(gui_hide, "1") == 0 ||
+ strcmp(gui_hide, "true") == 0) {
+ gui_hidden = true;
+ }
+ /* else stays false */
+ }
+
+ /* 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, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
+ } else if (!strcmp(type, "int")) {
+ param = new ParamInt(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
+ } else if (!strcmp(type, "float")) {
+ param = new ParamFloat(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
+ } else if (!strcmp(type, "string")) {
+ param = new ParamString(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
+ } else if (!strcmp(type, "description")) {
+ param = new ParamDescription(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
+ } else if (!strcmp(type, "enum")) {
+ param = new ParamComboBox(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
+ } else if (!strcmp(type, "notebook")) {
+ param = new ParamNotebook(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
+ } else if (!strcmp(type, "optiongroup")) {
+ param = new ParamRadioButton(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
+ } else if (!strcmp(type, "color")) {
+ param = new ParamColor(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
+ }
+
+ /* Note: param could equal NULL */
+ return param;
+}
+
+
+
+/** \brief Wrapper to cast to the object and use it's function. */
+bool
+Parameter::get_bool (const SPDocument * doc, const Inkscape::XML::Node * node)
+{
+ ParamBool * boolpntr = dynamic_cast<ParamBool *>(this);
+ if (boolpntr == NULL)
+ throw Extension::param_not_bool_param();
+ return boolpntr->get(doc, node);
+}
+
+/** \brief Wrapper to cast to the object and use it's function. */
+int
+Parameter::get_int (const SPDocument * doc, const Inkscape::XML::Node * node)
+{
+ ParamInt * intpntr = dynamic_cast<ParamInt *>(this);
+ if (intpntr == NULL)
+ throw Extension::param_not_int_param();
+ return intpntr->get(doc, node);
+}
+
+/** \brief Wrapper to cast to the object and use it's function. */
+float
+Parameter::get_float (const SPDocument * doc, const Inkscape::XML::Node * node)
+{
+ ParamFloat * floatpntr = dynamic_cast<ParamFloat *>(this);
+ if (floatpntr == NULL)
+ throw Extension::param_not_float_param();
+ return floatpntr->get(doc, node);
+}
+
+/** \brief Wrapper to cast to the object and use it's function. */
+const gchar *
+Parameter::get_string (const SPDocument * doc, const Inkscape::XML::Node * node)
+{
+ ParamString * stringpntr = dynamic_cast<ParamString *>(this);
+ if (stringpntr == NULL)
+ throw Extension::param_not_string_param();
+ return stringpntr->get(doc, node);
+}
+
+/** \brief Wrapper to cast to the object and use it's function. */
+const gchar *
+Parameter::get_enum (const SPDocument * doc, const Inkscape::XML::Node * node)
+{
+ ParamComboBox * param = dynamic_cast<ParamComboBox *>(this);
+ if (param == NULL)
+ throw Extension::param_not_enum_param();
+ return param->get(doc, node);
+}
+
+guint32
+Parameter::get_color(const SPDocument* doc, const Inkscape::XML::Node* node)
+{
+ ParamColor* param = dynamic_cast<ParamColor *>(this);
+ if (param == NULL)
+ throw Extension::param_not_color_param();
+ return param->get(doc, node);
+}
+
+/** \brief Wrapper to cast to the object and use it's function. */
+bool
+Parameter::set_bool (bool in, SPDocument * doc, Inkscape::XML::Node * node)
+{
+ ParamBool * boolpntr = dynamic_cast<ParamBool *>(this);
+ if (boolpntr == NULL)
+ throw Extension::param_not_bool_param();
+ return boolpntr->set(in, doc, node);
+}
+
+/** \brief Wrapper to cast to the object and use it's function. */
+int
+Parameter::set_int (int in, SPDocument * doc, Inkscape::XML::Node * node)
+{
+ ParamInt * intpntr = dynamic_cast<ParamInt *>(this);
+ if (intpntr == NULL)
+ throw Extension::param_not_int_param();
+ return intpntr->set(in, doc, node);
+}
+
+/** \brief Wrapper to cast to the object and use it's function. */
+float
+Parameter::set_float (float in, SPDocument * doc, Inkscape::XML::Node * node)
+{
+ ParamFloat * floatpntr;
+ floatpntr = dynamic_cast<ParamFloat *>(this);
+ if (floatpntr == NULL)
+ throw Extension::param_not_float_param();
+ 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, SPDocument * doc, Inkscape::XML::Node * node)
+{
+ ParamString * stringpntr = dynamic_cast<ParamString *>(this);
+ if (stringpntr == NULL)
+ throw Extension::param_not_string_param();
+ return stringpntr->set(in, doc, node);
+}
+/** \brief Wrapper to cast to the object and use it's function. */
+guint32
+Parameter::set_color (guint32 in, SPDocument * doc, Inkscape::XML::Node * node)
+{
+ ParamColor* param = dynamic_cast<ParamColor *>(this);
+ if (param == NULL)
+ throw Extension::param_not_color_param();
+ return param->set(in, doc, node);
+}
+
+
+/** \brief Oop, now that we need a parameter, we need it's name. */
+Parameter::Parameter (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext) :
+ extension(ext), _name(NULL), _desc(NULL), _scope(scope), _text(NULL), _gui_hidden(gui_hidden), _gui_tip(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 (gui_tip != NULL) {
+ _gui_tip = g_strdup(gui_tip);
+ }
+
+
+ if (guitext != NULL)
+ _text = g_strdup(guitext);
+ else
+ _text = g_strdup(name);
+
+ return;
+}
+
+/** \brief Just free the allocated name. */
+Parameter::~Parameter (void)
+{
+ g_free(_name);
+ g_free(_text);
+ g_free(_gui_tip);
+}
+
+/** \brief Build the name to write the parameter from the extension's
+ ID and the name of this parameter. */
+gchar *
+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 = parent->document()->createElement("inkscape:extension-param");
+ retval->setAttribute("name", _name);
+
+ parent->appendChild(retval);
+ return retval;
+}
+
+Inkscape::XML::Node *
+Parameter::document_param_node (SPDocument * doc)
+{
+ Inkscape::XML::Document *xml_doc = sp_document_repr_doc(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 = xml_doc->createElement("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 (SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/, sigc::signal<void> * /*changeSignal*/)
+{
+ return NULL;
+}
+
+/** \brief If I'm not sure which it is, just don't return a value. */
+void
+Parameter::string (std::string &/*string*/)
+{
+ return;
+}
+
+void
+Parameter::string (std::list <std::string> &list)
+{
+ std::string value;
+ string(value);
+ if (value == "") {
+ return;
+ }
+
+ std::string final;
+ final += "--";
+ final += name();
+ final += "=";
+ final += value;
+
+ list.insert(list.end(), final);
+ return;
+}
+
+} /* namespace Extension */
+} /* namespace Inkscape */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/extension/param/parameter.h b/src/extension/param/parameter.h
new file mode 100644
index 000000000..ca3a2a0d4
--- /dev/null
+++ b/src/extension/param/parameter.h
@@ -0,0 +1,131 @@
+#ifndef __INK_EXTENSION_PARAM_H__
+#define __INK_EXTENSION_PARAM_H__
+
+/** \file
+ * Parameters for extensions.
+ */
+
+/*
+ * Authors:
+ * Ted Gould <ted@gould.cx>
+ *
+ * Copyright (C) 2005-2006 Authors
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+/** \brief The root directory in the preferences database for extension-related parameters. */
+#define PREF_DIR "extensions"
+
+#include <gtkmm/widget.h>
+
+#include "xml/document.h"
+#include "xml/node.h"
+#include "document.h"
+#include <extension/extension-forward.h>
+#include "prefs-utils.h"
+
+#include <glibmm/i18n.h>
+
+#include <color.h>
+
+namespace Inkscape {
+namespace Extension {
+
+/** \brief A class to represent the parameter of an extension
+
+ This is really a super class that allows them to abstract all
+ the different types of parameters into some that can be passed
+ around. There is also a few functions that are used by all the
+ different parameters.
+*/
+class Parameter {
+private:
+ /** \brief Which extension is this parameter attached to? */
+ Inkscape::Extension::Extension * extension;
+ /** \brief The name of this parameter. */
+ gchar * _name;
+
+protected:
+ /** \brief Description of the parameter. */
+ gchar * _desc;
+ /** \brief List of possible scopes. */
+ typedef enum {
+ SCOPE_USER, /**< Parameter value is saved in the user's configuration file. (default) */
+ SCOPE_DOCUMENT, /**< Parameter value is saved in the document. */
+ SCOPE_NODE /**< Parameter value is attached to the node. */
+ } _scope_t;
+ /** \brief Scope of the parameter. */
+ _scope_t _scope;
+ /** \brief Text for the GUI selection of this. */
+ gchar * _text;
+ /** \brief Whether the GUI is visible */
+ bool _gui_hidden;
+ /** \brief A tip for the GUI if there is one */
+ gchar * _gui_tip;
+
+
+ /* **** funcs **** */
+ gchar * pref_name (void);
+ Inkscape::XML::Node * find_child (Inkscape::XML::Node * adult);
+ Inkscape::XML::Node * document_param_node (SPDocument * doc);
+ Inkscape::XML::Node * new_child (Inkscape::XML::Node * parent);
+
+public:
+ Parameter (const gchar * name,
+ const gchar * guitext,
+ const gchar * desc,
+ const Parameter::_scope_t scope,
+ bool gui_hidden,
+ const gchar * gui_tip,
+ Inkscape::Extension::Extension * ext);
+ Parameter (const gchar * name,
+ const gchar * guitext,
+ Inkscape::Extension::Extension * ext) {
+ Parameter(name, guitext, NULL, Parameter::SCOPE_USER, false, NULL, ext);
+ };
+ virtual ~Parameter (void);
+ bool get_bool (const SPDocument * doc,
+ const Inkscape::XML::Node * node);
+ int get_int (const SPDocument * doc,
+ const Inkscape::XML::Node * node);
+ float get_float (const SPDocument * doc,
+ const Inkscape::XML::Node * node);
+ const gchar * get_string (const SPDocument * doc,
+ const Inkscape::XML::Node * node);
+ guint32 get_color (const SPDocument * doc,
+ const Inkscape::XML::Node * node);
+ const gchar * get_enum (const SPDocument * doc,
+ const Inkscape::XML::Node * node);
+
+ bool set_bool (bool in, SPDocument * doc, Inkscape::XML::Node * node);
+ int set_int (int in, SPDocument * doc, Inkscape::XML::Node * node);
+ float set_float (float in, SPDocument * doc, Inkscape::XML::Node * node);
+ const gchar * set_string (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node);
+ guint32 set_color (guint32 in, SPDocument * doc, Inkscape::XML::Node * node);
+
+ const gchar * name (void) {return _name;}
+
+ static Parameter * make (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext);
+ virtual Gtk::Widget * get_widget (SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal);
+ gchar const * get_tooltip (void) { return _desc; }
+
+ virtual void string (std::list <std::string> &list);
+ virtual void string (std::string &string);
+};
+
+} /* namespace Extension */
+} /* namespace Inkscape */
+
+#endif /* __INK_EXTENSION_PARAM_H__ */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
diff --git a/src/extension/param/radiobutton.cpp b/src/extension/param/radiobutton.cpp
new file mode 100644
index 000000000..1ab526d19
--- /dev/null
+++ b/src/extension/param/radiobutton.cpp
@@ -0,0 +1,271 @@
+/** \file
+ * extension parameter for radiobuttons.
+ *
+ * It uses a Gtk:ComboBoxText widget in the extension UI.
+ */
+
+/*
+ * Author:
+ * Johan Engelen <johan@shouraizou.nl>
+ *
+ * Copyright (C) 2006-2007 Johan Engelen
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+
+#include <gtkmm/box.h>
+#include <gtkmm/radiobutton.h>
+#include <gtkmm/radiobuttongroup.h>
+#include <gtkmm/tooltips.h>
+#include <gtkmm/label.h>
+
+#include <glibmm/i18n.h>
+
+#include <xml/node.h>
+
+#include <extension/extension.h>
+#include "prefs-utils.h"
+#include "document-private.h"
+#include "sp-object.h"
+
+#include "radiobutton.h"
+
+/** \brief The root directory in the preferences database for extension
+ related parameters. */
+#define PREF_DIR "extensions"
+
+namespace Inkscape {
+namespace Extension {
+
+/* For internal use only.
+ Note that value and guitext MUST be non-NULL. This is ensured by newing only at one location in the code where non-NULL checks are made. */
+class optionentry {
+public:
+ optionentry (Glib::ustring * val, Glib::ustring * text) {
+ value = val;
+ guitext = text;
+ }
+ ~optionentry() {
+ delete value;
+ delete guitext;
+ }
+
+ Glib::ustring * value;
+ Glib::ustring * guitext;
+};
+
+ParamRadioButton::ParamRadioButton (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
+ Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, ext)
+{
+ choices = NULL;
+ _value = NULL;
+
+ // Read XML tree to add enumeration items:
+ // printf("Extension Constructor: ");
+ if (xml != NULL) {
+ Inkscape::XML::Node *child_repr = sp_repr_children(xml);
+ while (child_repr != NULL) {
+ char const * chname = child_repr->name();
+ if (!strcmp(chname, "option") || !strcmp(chname, "_option")) {
+ Glib::ustring * newguitext = NULL;
+ Glib::ustring * newvalue = NULL;
+ const char * contents = sp_repr_children(child_repr)->content();
+ if (contents != NULL)
+ // don't translate when 'option' but do translate when '_option'
+ newguitext = new Glib::ustring( !strcmp(chname, "_option") ? _(contents) : contents );
+ else
+ continue;
+
+ const char * val = child_repr->attribute("value");
+ if (val != NULL)
+ newvalue = new Glib::ustring(val);
+ else
+ newvalue = new Glib::ustring(contents);
+
+ if ( (newguitext) && (newvalue) ) { // logical error if this is not true here
+ choices = g_slist_append( choices, new optionentry(newvalue, newguitext) );
+ }
+ }
+ child_repr = sp_repr_next(child_repr);
+ }
+ }
+
+ // Initialize _value with the default value from xml
+ // for simplicity : default to the contents of the first xml-child
+ const char * defaultval = NULL;
+ if (choices)
+ defaultval = ((optionentry*) choices->data)->value->c_str();
+
+ gchar * pref_name = this->pref_name();
+ const gchar * paramval = prefs_get_string_attribute(PREF_DIR, pref_name);
+ g_free(pref_name);
+
+ if (paramval != NULL)
+ defaultval = paramval;
+ if (defaultval != NULL)
+ _value = g_strdup(defaultval); // allocate space for _value
+
+ return;
+}
+
+ParamRadioButton::~ParamRadioButton (void)
+{
+ //destroy choice strings
+ for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
+ delete (reinterpret_cast<optionentry *>(list->data));
+ }
+ g_slist_free(choices);
+
+ g_free(_value);
+}
+
+
+/** \brief A function to set the \c _value
+ \param in The value to set
+ \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 ONLY 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.
+
+ To copy the data into _value the old memory must be free'd first.
+ It is important to note that \c g_free handles \c NULL just fine. Then
+ the passed in value is duplicated using \c g_strdup().
+*/
+const gchar *
+ParamRadioButton::set (const gchar * in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/)
+{
+ if (in == NULL) return NULL; /* Can't have NULL string */
+
+ Glib::ustring * settext = NULL;
+ for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
+ optionentry * entr = reinterpret_cast<optionentry *>(list->data);
+ if ( !entr->guitext->compare(in) ) {
+ settext = entr->value;
+ break; // break out of for loop
+ }
+ }
+ if (settext) {
+ if (_value != NULL) g_free(_value);
+ _value = g_strdup(settext->c_str());
+ gchar * prefname = this->pref_name();
+ prefs_set_string_attribute(PREF_DIR, prefname, _value);
+ g_free(prefname);
+ }
+
+ return _value;
+}
+
+
+/**
+ \brief A function to get the current value of the parameter in a string form
+ \return A string with the 'value' as command line argument
+*/
+void
+ParamRadioButton::string (std::string &string)
+{
+ string += _value;
+ return;
+}
+
+/** \brief A special radiobutton class to use in ParamRadioButton */
+class ParamRadioButtonWdg : public Gtk::RadioButton {
+private:
+ ParamRadioButton * _pref;
+ SPDocument * _doc;
+ Inkscape::XML::Node * _node;
+ sigc::signal<void> * _changeSignal;
+public:
+ /** \brief Build a string preference for the given parameter
+ \param pref Where to put the radiobutton's string when it is selected.
+ */
+ ParamRadioButtonWdg ( Gtk::RadioButtonGroup& group, const Glib::ustring& label,
+ ParamRadioButton * pref, SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal ) :
+ Gtk::RadioButton(group, label), _pref(pref), _doc(doc), _node(node), _changeSignal(changeSignal) {
+ add_changesignal();
+ };
+ ParamRadioButtonWdg ( const Glib::ustring& label,
+ ParamRadioButton * pref, SPDocument * doc, Inkscape::XML::Node * node , sigc::signal<void> * changeSignal) :
+ Gtk::RadioButton(label), _pref(pref), _doc(doc), _node(node), _changeSignal(changeSignal) {
+ add_changesignal();
+ };
+ void add_changesignal() {
+ this->signal_toggled().connect(sigc::mem_fun(this, &ParamRadioButtonWdg::changed));
+ };
+ void changed (void);
+};
+
+/** \brief Respond to the selected radiobutton changing
+
+ This function responds to the radiobutton selection changing by grabbing the value
+ from the text box and putting it in the parameter.
+*/
+void
+ParamRadioButtonWdg::changed (void)
+{
+ if (this->get_active()) {
+ Glib::ustring data = this->get_label();
+ _pref->set(data.c_str(), _doc, _node);
+ }
+ if (_changeSignal != NULL) {
+ _changeSignal->emit();
+ }
+}
+
+
+
+/**
+ \brief Creates a combobox widget for an enumeration parameter
+*/
+Gtk::Widget *
+ParamRadioButton::get_widget (SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal)
+{
+ if (_gui_hidden) return NULL;
+
+ Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
+ Gtk::VBox * vbox = Gtk::manage(new Gtk::VBox(false, 0));
+
+ Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT, Gtk::ALIGN_TOP));
+ label->show();
+ hbox->pack_start(*label, false, false);
+
+ // add choice strings as radiobuttons
+ // and select last selected option (_value)
+ bool first = true;
+ ParamRadioButtonWdg * radio;
+ Gtk::RadioButtonGroup group;
+ for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
+ optionentry * entr = reinterpret_cast<optionentry *>(list->data);
+ Glib::ustring * text = entr->guitext;
+ if (first) {
+ radio = Gtk::manage(new ParamRadioButtonWdg(*text, this, doc, node, changeSignal));
+ group = radio->get_group();
+ first = false;
+ } else {
+ radio = Gtk::manage(new ParamRadioButtonWdg(group, *text, this, doc, node, changeSignal));
+ }
+ radio->show();
+ vbox->pack_start(*radio, true, true);
+ if (!entr->value->compare(_value)) {
+ radio->set_active();
+ }
+ }
+
+ vbox->show();
+ hbox->pack_end(*vbox, false, false);
+ hbox->show();
+
+
+ return dynamic_cast<Gtk::Widget *>(hbox);
+}
+
+
+} /* namespace Extension */
+} /* namespace Inkscape */
+
diff --git a/src/extension/param/radiobutton.h b/src/extension/param/radiobutton.h
new file mode 100644
index 000000000..4bf596e4f
--- /dev/null
+++ b/src/extension/param/radiobutton.h
@@ -0,0 +1,57 @@
+#ifndef INK_EXTENSION_PARAMRADIOBUTTON_H_SEEN
+#define INK_EXTENSION_PARAMRADIOBUTTON_H_SEEN
+
+/** \file
+ * Radiobutton parameter for extensions.
+ */
+
+/*
+ * Author:
+ * Johan Engelen <johan@shouraizou.nl>
+ *
+ * Copyright (C) 2006-2007 Johan Engelen
+ *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <gtkmm/widget.h>
+
+#include "xml/document.h"
+#include <extension/extension-forward.h>
+
+#include "parameter.h"
+
+namespace Inkscape {
+namespace Extension {
+
+
+
+// \brief A class to represent a radiobutton parameter of an extension
+class ParamRadioButton : public Parameter {
+private:
+ /** \brief Internal value. This should point to a string that has
+ been allocated in memory. And should be free'd.
+ It is the value of the current selected string */
+ gchar * _value;
+
+ GSList * choices; /**< A table to store the choice strings */
+
+public:
+ ParamRadioButton(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
+ virtual ~ParamRadioButton(void);
+ Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal);
+ void string (std::string &string);
+
+ 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);
+}; /* class ParamRadioButton */
+
+
+
+
+
+} /* namespace Extension */
+} /* namespace Inkscape */
+
+#endif /* INK_EXTENSION_PARAMRADIOBUTTON_H_SEEN */
+
diff --git a/src/extension/param/string.cpp b/src/extension/param/string.cpp
new file mode 100644
index 000000000..36c3ce115
--- /dev/null
+++ b/src/extension/param/string.cpp
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2005-2007 Authors:
+ * Ted Gould <ted@gould.cx>
+ * Johan Engelen <johan@shouraizou.nl> *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <gtkmm/adjustment.h>
+#include <gtkmm/box.h>
+#include <gtkmm/spinbutton.h>
+
+#include <xml/node.h>
+
+#include <extension/extension.h>
+#include "string.h"
+
+namespace Inkscape {
+namespace Extension {
+
+
+/** \brief Free the allocated data. */
+ParamString::~ParamString(void)
+{
+ g_free(_value);
+}
+
+/** \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.
+
+ To copy the data into _value the old memory must be free'd first.
+ It is important to note that \c g_free handles \c NULL just fine. Then
+ the passed in value is duplicated using \c g_strdup().
+*/
+const gchar *
+ParamString::set (const gchar * in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/)
+{
+ if (in == NULL) return NULL; /* Can't have NULL string */
+
+ if (_value != NULL)
+ g_free(_value);
+ _value = g_strdup(in);
+
+ gchar * prefname = this->pref_name();
+ prefs_set_string_attribute(PREF_DIR, prefname, _value);
+ g_free(prefname);
+
+ return _value;
+}
+
+/** \brief Return the value as a string */
+void
+ParamString::string (std::string &string)
+{
+ if (_value == NULL)
+ return;
+
+ string += _value;
+ return;
+}
+
+/** \brief Initialize the object, to do that, copy the data. */
+ParamString::ParamString (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
+ Parameter(name, guitext, desc, scope, gui_hidden, gui_tip, ext), _value(NULL)
+{
+ const char * defaultval = NULL;
+ if (sp_repr_children(xml) != NULL)
+ defaultval = sp_repr_children(xml)->content();
+
+ gchar * pref_name = this->pref_name();
+ const gchar * paramval = prefs_get_string_attribute(PREF_DIR, pref_name);
+ g_free(pref_name);
+
+ if (paramval != NULL)
+ defaultval = paramval;
+ if (defaultval != NULL)
+ _value = g_strdup(defaultval);
+
+ return;
+}
+
+/** \brief A special category of Gtk::Entry to handle string parameteres */
+class ParamStringEntry : public Gtk::Entry {
+private:
+ ParamString * _pref;
+ SPDocument * _doc;
+ Inkscape::XML::Node * _node;
+ sigc::signal<void> * _changeSignal;
+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, SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal) :
+ Gtk::Entry(), _pref(pref), _doc(doc), _node(node), _changeSignal(changeSignal) {
+ 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);
+};
+
+
+/** \brief Respond to the text box changing
+
+ This function responds to the box changing by grabbing the value
+ from the text box and putting it in the parameter.
+*/
+void
+ParamStringEntry::changed_text (void)
+{
+ Glib::ustring data = this->get_text();
+ _pref->set(data.c_str(), _doc, _node);
+ if (_changeSignal != NULL) {
+ _changeSignal->emit();
+ }
+ 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 (SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal)
+{
+ if (_gui_hidden) return NULL;
+
+ Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
+
+ Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
+ label->show();
+ hbox->pack_start(*label, false, false);
+
+ ParamStringEntry * textbox = new ParamStringEntry(this, doc, node, changeSignal);
+ textbox->show();
+ hbox->pack_start(*textbox, true, true);
+
+ hbox->show();
+
+ return dynamic_cast<Gtk::Widget *>(hbox);
+}
+
+} /* namespace Extension */
+} /* namespace Inkscape */
diff --git a/src/extension/param/string.h b/src/extension/param/string.h
new file mode 100644
index 000000000..0a1a0f2a3
--- /dev/null
+++ b/src/extension/param/string.h
@@ -0,0 +1,49 @@
+#ifndef INK_EXTENSION_PARAMSTRING_H_SEEN
+#define INK_EXTENSION_PARAMSTRING_H_SEEN
+
+/*
+ * Copyright (C) 2005-2007 Authors:
+ * Ted Gould <ted@gould.cx>
+ * Johan Engelen <johan@shouraizou.nl> *
+ * Released under GNU GPL, read the file 'COPYING' for more information
+ */
+
+#include <gtkmm/widget.h>
+#include <xml/node.h>
+#include <document.h>
+#include "parameter.h"
+
+namespace Inkscape {
+namespace Extension {
+
+class ParamString : public Parameter {
+private:
+ /** \brief Internal value. This should point to a string that has
+ been allocated in memory. And should be free'd. */
+ gchar * _value;
+public:
+ ParamString(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
+ virtual ~ParamString(void);
+ /** \brief Returns \c _value, with a \i const to protect it. */
+ 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, sigc::signal<void> * changeSignal);
+ void string (std::string &string);
+};
+
+
+} /* namespace Extension */
+} /* namespace Inkscape */
+
+#endif /* INK_EXTENSION_PARAMSTRING_H_SEEN */
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :