Code

eda540a9d56d789cf72b115cea19b014a5db1fa7
[inkscape.git] / src / extension / parameter.cpp
1 /** \file
2  * Parameters for extensions.
3  */
5 /*
6  * Authors:
7  *   Ted Gould <ted@gould.cx>
8  *
9  * Copyright (C) 2005-2006 Authors
10  *
11  * Released under GNU GPL, read the file 'COPYING' for more information
12  */
14 #ifdef HAVE_CONFIG_H
15 # include "config.h"
16 #endif
19 #include <gtkmm/adjustment.h>
20 #include <gtkmm/box.h>
21 #include <gtkmm/spinbutton.h>
23 #include <glibmm/i18n.h>
25 #include <xml/node.h>
27 #include "extension.h"
28 #include "prefs-utils.h"
29 #include "document-private.h"
30 #include "sp-object.h"
32 #include "parameter.h"
34 /** \brief  The root directory in the preferences database for extension
35             related parameters. */
36 #define PREF_DIR "extensions"
38 namespace Inkscape {
39 namespace Extension {
41 /** \brief  A boolean parameter */
42 class ParamBool : public Parameter {
43 private:
44     /** \brief  Internal value. */
45     bool _value;
46 public:
47     ParamBool(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
48     /** \brief  Returns \c _value */
49     bool get (const SPDocument * doc, const Inkscape::XML::Node * node) { return _value; }
50     bool set (bool in, SPDocument * doc, Inkscape::XML::Node * node);
51     Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);
52     Glib::ustring * string (void);
53 };
55 /** \brief  Use the superclass' allocator and set the \c _value */
56 ParamBool::ParamBool (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
57         Parameter(name, guitext, desc, scope, ext), _value(false)
58 {
59     const char * defaultval = NULL;
60     if (sp_repr_children(xml) != NULL)
61         defaultval = sp_repr_children(xml)->content();
63     if (defaultval != NULL && (!strcmp(defaultval, "TRUE") || !strcmp(defaultval, "true") || !strcmp(defaultval, "1"))) {
64         _value = true;
65     } else {
66         _value = false;
67     }
69     gchar * pref_name = this->pref_name();
70     _value = (bool)prefs_get_int_attribute(PREF_DIR, pref_name, _value);
71     g_free(pref_name);
73     return;
74 }
76 class ParamInt : public Parameter {
77 private:
78     /** \brief  Internal value. */
79     int _value;
80     int _min;
81     int _max;
82 public:
83     ParamInt (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
84     /** \brief  Returns \c _value */
85     int get (const SPDocument * doc, const Inkscape::XML::Node * node) { return _value; }
86     int set (int in, SPDocument * doc, Inkscape::XML::Node * node);
87     int max (void) { return _max; }
88     int min (void) { return _min; }
89     Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);
90     Glib::ustring * string (void);
91 };
93 /** \brief  Use the superclass' allocator and set the \c _value */
94 ParamInt::ParamInt (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
95         Parameter(name, guitext, desc, scope, ext), _value(0), _min(0), _max(10)
96 {
97     const char * defaultval = NULL;
98     if (sp_repr_children(xml) != NULL)
99         defaultval = sp_repr_children(xml)->content();
100     if (defaultval != NULL) {
101         _value = atoi(defaultval);
102     }
104     const char * maxval = xml->attribute("max");
105     if (maxval != NULL)
106         _max = atoi(maxval);
108     const char * minval = xml->attribute("min");
109     if (minval != NULL)
110         _min = atoi(minval);
112     /* We're handling this by just killing both values */
113     if (_max < _min) {
114         _max = 10;
115         _min = 0;
116     }
118     gchar * pref_name = this->pref_name();
119     _value = prefs_get_int_attribute(PREF_DIR, pref_name, _value);
120     g_free(pref_name);
122     // std::cout << "New Int::  value: " << _value << "  max: " << _max << "  min: " << _min << std::endl;
124     if (_value > _max) _value = _max;
125     if (_value < _min) _value = _min;
127     return;
130 class ParamFloat : public Parameter {
131 private:
132     /** \brief  Internal value. */
133     float _value;
134     float _min;
135     float _max;
136 public:
137     ParamFloat (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
138     /** \brief  Returns \c _value */
139     float get (const SPDocument * doc, const Inkscape::XML::Node * node) { return _value; }
140     float set (float in, SPDocument * doc, Inkscape::XML::Node * node);
141     float max (void) { return _max; }
142     float min (void) { return _min; }
143     Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);
144     Glib::ustring * string (void);
145 };
147 /** \brief  Use the superclass' allocator and set the \c _value */
148 ParamFloat::ParamFloat (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
149         Parameter(name, guitext, desc, scope, ext), _value(0.0), _min(0.0), _max(10.0)
151     const char * defaultval = NULL;
152     if (sp_repr_children(xml) != NULL)
153         defaultval = sp_repr_children(xml)->content();
154     if (defaultval != NULL) {
155         _value = atof(defaultval);
156     }
158     const char * maxval = xml->attribute("max");
159     if (maxval != NULL)
160         _max = atof(maxval);
162     const char * minval = xml->attribute("min");
163     if (minval != NULL)
164         _min = atof(minval);
166     /* We're handling this by just killing both values */
167     if (_max < _min) {
168         _max = 10.0;
169         _min = 0.0;
170     }
172     gchar * pref_name = this->pref_name();
173     _value = prefs_get_double_attribute(PREF_DIR, pref_name, _value);
174     g_free(pref_name);
176     // std::cout << "New Float::  value: " << _value << "  max: " << _max << "  min: " << _min << std::endl;
178     if (_value > _max) _value = _max;
179     if (_value < _min) _value = _min;
181     return;
184 class ParamString : public Parameter {
185 private:
186     /** \brief  Internal value.  This should point to a string that has
187                 been allocated in memory.  And should be free'd. */
188     gchar * _value;
189 public:
190     ParamString(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
191     ~ParamString(void);
192     /** \brief  Returns \c _value, with a \i const to protect it. */
193     const gchar * get (const SPDocument * doc, const Inkscape::XML::Node * node) { return _value; }
194     const gchar * set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node);
195     Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);
196     Glib::ustring * string (void);
197 };
199 /**
200     \return None
201     \brief  This function creates a parameter that can be used later.  This
202             is typically done in the creation of the extension and defined
203             in the XML file describing the extension (it's private so people
204             have to use the system) :)
205     \param  in_repr  The XML describing the parameter
207     This function first grabs all of the data out of the Repr and puts
208     it into local variables.  Actually, these are just pointers, and the
209     data is not duplicated so we need to be careful with it.  If there
210     isn't a name or a type in the XML, then no parameter is created as
211     the function just returns.
213     From this point on, we're pretty committed as we've allocated an
214     object and we're starting to fill it.  The name is set first, and
215     is created with a strdup to actually allocate memory for it.  Then
216     there is a case statement (roughly because strcmp requires 'ifs')
217     based on what type of parameter this is.  Depending which type it
218     is, the value is interpreted differently, but they are relatively
219     straight forward.  In all cases the value is set to the default
220     value from the XML and the type is set to the interpreted type.
221 */
222 Parameter *
223 Parameter::make (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext)
225     const char * name;
226     const char * type;
227     const char * guitext;
228     const char * desc;
229     const char * scope_str;
230     Parameter::_scope_t scope = Parameter::SCOPE_USER;
232     name = in_repr->attribute("name");
233     type = in_repr->attribute("type");
234     guitext = in_repr->attribute("gui-text");
235     if (guitext == NULL)
236         guitext = in_repr->attribute("_gui-text");
237     desc = in_repr->attribute("gui-description");
238     if (desc == NULL)
239         desc = in_repr->attribute("_gui-description");
240     scope_str = in_repr->attribute("scope");
242     /* In this case we just don't have enough information */
243     if (name == NULL || type == NULL) {
244         return NULL;
245     }
247     if (scope_str != NULL) {
248         if (!strcmp(scope_str, "user")) {
249             scope = Parameter::SCOPE_USER;
250         } else if (!strcmp(scope_str, "document")) {
251             scope = Parameter::SCOPE_DOCUMENT;
252         } else if (!strcmp(scope_str, "node")) {
253             scope = Parameter::SCOPE_NODE;
254         }
255     }
257     Parameter * param = NULL;
258     if (!strcmp(type, "boolean")) {
259         param = new ParamBool(name, guitext, desc, scope, in_ext, in_repr);
260     } else if (!strcmp(type, "int")) {
261         param = new ParamInt(name, guitext, desc, scope, in_ext, in_repr);
262     } else if (!strcmp(type, "float")) {
263         param = new ParamFloat(name, guitext, desc, scope, in_ext, in_repr);
264     } else if (!strcmp(type, "string")) {
265         param = new ParamString(name, guitext, desc, scope, in_ext, in_repr);
266     }
268     /* Note: param could equal NULL */
269     return param;
272 /** \brief  A function to set the \c _value
273     \param  in   The value to set to
274     \param  doc  A document that should be used to set the value.
275     \param  node The node where the value may be placed
277     This function sets the internal value, but it also sets the value
278     in the preferences structure.  To put it in the right place, \c PREF_DIR
279     and \c pref_name() are used.
280 */
281 bool
282 ParamBool::set (bool in, SPDocument * doc, Inkscape::XML::Node * node)
284     _value = in;
286     gchar * prefname = this->pref_name();
287     prefs_set_int_attribute(PREF_DIR, prefname, _value == true ? 1 : 0);
288     g_free(prefname);
290     return _value;
293 /** \brief  A function to set the \c _value
294     \param  in   The value to set to
295     \param  doc  A document that should be used to set the value.
296     \param  node The node where the value may be placed
298     This function sets the internal value, but it also sets the value
299     in the preferences structure.  To put it in the right place, \c PREF_DIR
300     and \c pref_name() are used.
301 */
302 int
303 ParamInt::set (int in, SPDocument * doc, Inkscape::XML::Node * node)
305     _value = in;
306     if (_value > _max) _value = _max;
307     if (_value < _min) _value = _min;
309     gchar * prefname = this->pref_name();
310     prefs_set_int_attribute(PREF_DIR, prefname, _value);
311     g_free(prefname);
313     return _value;
316 /** \brief  A function to set the \c _value
317     \param  in   The value to set to
318     \param  doc  A document that should be used to set the value.
319     \param  node The node where the value may be placed
321     This function sets the internal value, but it also sets the value
322     in the preferences structure.  To put it in the right place, \c PREF_DIR
323     and \c pref_name() are used.
324 */
325 float
326 ParamFloat::set (float in, SPDocument * doc, Inkscape::XML::Node * node)
328     _value = in;
329     if (_value > _max) _value = _max;
330     if (_value < _min) _value = _min;
332     gchar * prefname = this->pref_name();
333     prefs_set_double_attribute(PREF_DIR, prefname, _value);
334     g_free(prefname);
336     return _value;
339 /** \brief  A function to set the \c _value
340     \param  in   The value to set to
341     \param  doc  A document that should be used to set the value.
342     \param  node The node where the value may be placed
344     This function sets the internal value, but it also sets the value
345     in the preferences structure.  To put it in the right place, \c PREF_DIR
346     and \c pref_name() are used.
348     To copy the data into _value the old memory must be free'd first.
349     It is important to note that \c g_free handles \c NULL just fine.  Then
350     the passed in value is duplicated using \c g_strdup().
351 */
352 const gchar *
353 ParamString::set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node)
355     if (in == NULL) return NULL; /* Can't have NULL string */
357     if (_value != NULL)
358         g_free(_value);
359     _value = g_strdup(in);
361     gchar * prefname = this->pref_name();
362     prefs_set_string_attribute(PREF_DIR, prefname, _value);
363     g_free(prefname);
365     return _value;
368 /** \brief  Wrapper to cast to the object and use it's function.  */
369 bool
370 Parameter::get_bool (const SPDocument * doc, const Inkscape::XML::Node * node)
372     ParamBool * boolpntr;
373     boolpntr = dynamic_cast<ParamBool *>(this);
374     if (boolpntr == NULL)
375         throw Extension::param_wrong_type();
376     return boolpntr->get(doc, node);
379 /** \brief  Wrapper to cast to the object and use it's function.  */
380 int
381 Parameter::get_int (const SPDocument * doc, const Inkscape::XML::Node * node)
383     ParamInt * intpntr;
384     intpntr = dynamic_cast<ParamInt *>(this);
385     if (intpntr == NULL)
386         throw Extension::param_wrong_type();
387     return intpntr->get(doc, node);
390 /** \brief  Wrapper to cast to the object and use it's function.  */
391 float
392 Parameter::get_float (const SPDocument * doc, const Inkscape::XML::Node * node)
394     ParamFloat * floatpntr;
395     floatpntr = dynamic_cast<ParamFloat *>(this);
396     if (floatpntr == NULL)
397         throw Extension::param_wrong_type();
398     return floatpntr->get(doc, node);
401 /** \brief  Wrapper to cast to the object and use it's function.  */
402 const gchar *
403 Parameter::get_string (const SPDocument * doc, const Inkscape::XML::Node * node)
405     ParamString * stringpntr;
406     stringpntr = dynamic_cast<ParamString *>(this);
407     if (stringpntr == NULL)
408         throw Extension::param_wrong_type();
409     return stringpntr->get(doc, node);
412 /** \brief  Wrapper to cast to the object and use it's function.  */
413 bool
414 Parameter::set_bool (bool in, SPDocument * doc, Inkscape::XML::Node * node)
416     ParamBool * boolpntr;
417     boolpntr = dynamic_cast<ParamBool *>(this);
418     if (boolpntr == NULL)
419         throw Extension::param_wrong_type();
420     return boolpntr->set(in, doc, node);
423 /** \brief  Wrapper to cast to the object and use it's function.  */
424 int
425 Parameter::set_int (int in, SPDocument * doc, Inkscape::XML::Node * node)
427     ParamInt * intpntr;
428     intpntr = dynamic_cast<ParamInt *>(this);
429     if (intpntr == NULL)
430         throw Extension::param_wrong_type();
431     return intpntr->set(in, doc, node);
434 /** \brief  Wrapper to cast to the object and use it's function.  */
435 float
436 Parameter::set_float (float in, SPDocument * doc, Inkscape::XML::Node * node)
438     ParamFloat * floatpntr;
439     floatpntr = dynamic_cast<ParamFloat *>(this);
440     if (floatpntr == NULL)
441         throw Extension::param_wrong_type();
442     return floatpntr->set(in, doc, node);
445 /** \brief  Wrapper to cast to the object and use it's function.  */
446 const gchar *
447 Parameter::set_string (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node)
449     ParamString * stringpntr;
450     stringpntr = dynamic_cast<ParamString *>(this);
451     if (stringpntr == NULL)
452         throw Extension::param_wrong_type();
453     return stringpntr->set(in, doc, node);
456 /** \brief  Initialize the object, to do that, copy the data. */
457 ParamString::ParamString (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
458     Parameter(name, guitext, desc, scope, ext), _value(NULL)
460     const char * defaultval = NULL;
461     if (sp_repr_children(xml) != NULL)
462         defaultval = sp_repr_children(xml)->content();
464     gchar * pref_name = this->pref_name();
465     const gchar * paramval = prefs_get_string_attribute(PREF_DIR, pref_name);
466     g_free(pref_name);
468     if (paramval != NULL)
469         defaultval = paramval;
470     if (defaultval != NULL)
471         _value = g_strdup(defaultval);
473     return;
476 /** \brief  Free the allocated data. */
477 ParamString::~ParamString(void)
479     g_free(_value);
482 /** \brief  Oop, now that we need a parameter, we need it's name.  */
483 Parameter::Parameter (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext) :
484     extension(ext), _name(NULL), _desc(NULL), _scope(scope), _text(NULL)
486     if (name != NULL)
487         _name = g_strdup(name);
488     if (desc != NULL) {
489         _desc = g_strdup(desc);
490         // printf("Adding description: '%s' on '%s'\n", _desc, _name);
491     }
494     if (guitext != NULL)
495         _text = g_strdup(guitext);
496     else
497         _text = g_strdup(name);
499     return;
502 /** \brief  Just free the allocated name. */
503 Parameter::~Parameter (void)
505     g_free(_name);
506     g_free(_text);
509 /** \brief  Build the name to write the parameter from the extension's
510             ID and the name of this parameter. */
511 gchar *
512 Parameter::pref_name (void)
514     return g_strdup_printf("%s.%s", extension->get_id(), _name);
517 Inkscape::XML::Node *
518 Parameter::find_child (Inkscape::XML::Node * adult)
520     return sp_repr_lookup_child(adult, "name", _name);
523 Inkscape::XML::Node *
524 Parameter::new_child (Inkscape::XML::Node * parent)
526     Inkscape::XML::Node * retval;
527     retval = sp_repr_new("inkscape:extension-param");
528     retval->setAttribute("name", _name);
530     parent->appendChild(retval);
531     return retval;
534 Inkscape::XML::Node *
535 Parameter::document_param_node (SPDocument * doc)
537     Inkscape::XML::Node * defs = SP_OBJECT_REPR(SP_DOCUMENT_DEFS(doc));
538     Inkscape::XML::Node * params = NULL;
540     GQuark const name_quark = g_quark_from_string("inkscape:extension-params");
542     for (Inkscape::XML::Node * child = defs->firstChild();
543             child != NULL;
544             child = child->next()) {
545         if ((GQuark)child->code() == name_quark &&
546                 !strcmp(child->attribute("extension"), extension->get_id())) {
547             params = child;
548             break;
549         }
550     }
552     if (params == NULL) {
553         params = sp_repr_new("inkscape:extension-param");
554         params->setAttribute("extension", extension->get_id());
555         defs->appendChild(params);
556     }
558     return params;
561 /** \brief  Basically, if there is no widget pass a NULL. */
562 Gtk::Widget *
563 Parameter::get_widget (SPDocument * doc, Inkscape::XML::Node * node)
565     return NULL;
568 /** \brief  If I'm not sure which it is, just don't return a value. */
569 Glib::ustring *
570 Parameter::string (void)
572     Glib::ustring * mystring = new Glib::ustring("");
573     return mystring;
576 /** \brief  A class to make an adjustment that uses Extension params */
577 class ParamFloatAdjustment : public Gtk::Adjustment {
578     /** The parameter to adjust */
579     ParamFloat * _pref;
580     SPDocument * _doc;
581     Inkscape::XML::Node * _node;
582 public:
583     /** \brief  Make the adjustment using an extension and the string
584                 describing the parameter. */
585     ParamFloatAdjustment (ParamFloat * param, SPDocument * doc, Inkscape::XML::Node * node) :
586             Gtk::Adjustment(0.0, param->min(), param->max(), 0.1), _pref(param), _doc(doc), _node(node) {
587         this->set_value(_pref->get(NULL, NULL) /* \todo fix */);
588         this->signal_value_changed().connect(sigc::mem_fun(this, &ParamFloatAdjustment::val_changed));
589         return;
590     };
592     void val_changed (void);
593 }; /* class ParamFloatAdjustment */
595 /** \brief  A function to respond to the value_changed signal from the
596             adjustment.
598     This function just grabs the value from the adjustment and writes
599     it to the parameter.  Very simple, but yet beautiful.
600 */
601 void
602 ParamFloatAdjustment::val_changed (void)
604     // std::cout << "Value Changed to: " << this->get_value() << std::endl;
605     _pref->set(this->get_value(), _doc, _node);
606     return;
609 /** \brief  A class to make an adjustment that uses Extension params */
610 class ParamIntAdjustment : public Gtk::Adjustment {
611     /** The parameter to adjust */
612     ParamInt * _pref;
613     SPDocument * _doc;
614     Inkscape::XML::Node * _node;
615 public:
616     /** \brief  Make the adjustment using an extension and the string
617                 describing the parameter. */
618     ParamIntAdjustment (ParamInt * param, SPDocument * doc, Inkscape::XML::Node * node) :
619             Gtk::Adjustment(0.0, param->min(), param->max(), 1.0), _pref(param), _doc(doc), _node(node) {
620         this->set_value(_pref->get(NULL, NULL) /* \todo fix */);
621         this->signal_value_changed().connect(sigc::mem_fun(this, &ParamIntAdjustment::val_changed));
622         return;
623     };
625     void val_changed (void);
626 }; /* class ParamIntAdjustment */
628 /** \brief  A function to respond to the value_changed signal from the
629             adjustment.
631     This function just grabs the value from the adjustment and writes
632     it to the parameter.  Very simple, but yet beautiful.
633 */
634 void
635 ParamIntAdjustment::val_changed (void)
637     // std::cout << "Value Changed to: " << this->get_value() << std::endl;
638     _pref->set((int)this->get_value(), _doc, _node);
639     return;
642 /**
643     \brief  Creates a Float Adjustment for a float parameter
645     Builds a hbox with a label and a float adjustment in it.
646 */
647 Gtk::Widget *
648 ParamFloat::get_widget (SPDocument * doc, Inkscape::XML::Node * node)
650     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox());
652     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
653     label->show();
654     hbox->pack_start(*label, true, true);
656     ParamFloatAdjustment * fadjust = Gtk::manage(new ParamFloatAdjustment(this, doc, node));
657     Gtk::SpinButton * spin = Gtk::manage(new Gtk::SpinButton(*fadjust, 0.1, 1));
658     spin->show();
659     hbox->pack_start(*spin, false, false);
661     hbox->show();
663     return dynamic_cast<Gtk::Widget *>(hbox);
666 /**
667     \brief  Creates a Int Adjustment for a int parameter
669     Builds a hbox with a label and a int adjustment in it.
670 */
671 Gtk::Widget *
672 ParamInt::get_widget (SPDocument * doc, Inkscape::XML::Node * node)
674     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox());
676     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
677     label->show();
678     hbox->pack_start(*label, true, true);
680     ParamIntAdjustment * fadjust = Gtk::manage(new ParamIntAdjustment(this, doc, node));
681     Gtk::SpinButton * spin = Gtk::manage(new Gtk::SpinButton(*fadjust, 1.0, 0));
682     spin->show();
683     hbox->pack_start(*spin, false, false);
685     hbox->show();
687     return dynamic_cast<Gtk::Widget *>(hbox);
690 /** \brief  A check button which is Param aware.  It works with the
691             parameter to change it's value as the check button changes
692             value. */
693 class ParamBoolCheckButton : public Gtk::CheckButton {
694 private:
695     /** \brief  Param to change */
696     ParamBool * _pref;
697     SPDocument * _doc;
698     Inkscape::XML::Node * _node;
699 public:
700     /** \brief  Initialize the check button
701         \param  param  Which parameter to adjust on changing the check button
703         This function sets the value of the checkbox to be that of the
704         parameter, and then sets up a callback to \c on_toggle.
705     */
706     ParamBoolCheckButton (ParamBool * param, SPDocument * doc, Inkscape::XML::Node * node) :
707             Gtk::CheckButton(), _pref(param), _doc(doc), _node(node) {
708         this->set_active(_pref->get(NULL, NULL) /**\todo fix */);
709         this->signal_toggled().connect(sigc::mem_fun(this, &ParamBoolCheckButton::on_toggle));
710         return;
711     }
712     void on_toggle (void);
713 };
715 /**
716     \brief  A function to respond to the check box changing
718     Adjusts the value of the preference to match that in the check box.
719 */
720 void
721 ParamBoolCheckButton::on_toggle (void)
723     _pref->set(this->get_active(), NULL /**\todo fix this */, NULL);
724     return;
727 /**
728     \brief  Creates a bool check button for a bool parameter
730     Builds a hbox with a label and a check button in it.
731 */
732 Gtk::Widget *
733 ParamBool::get_widget (SPDocument * doc, Inkscape::XML::Node * node)
735     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox());
737     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
738     label->show();
739     hbox->pack_start(*label, true, true);
741     ParamBoolCheckButton * checkbox = new ParamBoolCheckButton(this, doc, node);
742     checkbox->show();
743     hbox->pack_start(*checkbox, false, false);
745     hbox->show();
747     return dynamic_cast<Gtk::Widget *>(hbox);
750 /** \brief  A special category of Gtk::Entry to handle string parameteres */
751 class ParamStringEntry : public Gtk::Entry {
752 private:
753     ParamString * _pref;
754     SPDocument * _doc;
755     Inkscape::XML::Node * _node;
756 public:
757     /** \brief  Build a string preference for the given parameter
758         \param  pref  Where to get the string from, and where to put it
759                       when it changes.
760     */
761     ParamStringEntry (ParamString * pref, SPDocument * doc, Inkscape::XML::Node * node) :
762         Gtk::Entry(), _pref(pref), _doc(doc), _node(node) {
763         if (_pref->get(NULL, NULL) != NULL)
764             this->set_text(Glib::ustring(_pref->get(NULL, NULL)));
765         this->signal_changed().connect(sigc::mem_fun(this, &ParamStringEntry::changed_text));
766     };
767     void changed_text (void);
768 };
770 /** \brief  Respond to the text box changing
772     This function responds to the box changing by grabbing the value
773     from the text box and putting it in the parameter.
774 */
775 void
776 ParamStringEntry::changed_text (void)
778     Glib::ustring data = this->get_text();
779     _pref->set(data.c_str(), _doc, _node);
780     return;
783 /**
784     \brief  Creates a text box for the string parameter
786     Builds a hbox with a label and a text box in it.
787 */
788 Gtk::Widget *
789 ParamString::get_widget (SPDocument * doc, Inkscape::XML::Node * node)
791     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox());
793     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
794     label->show();
795     hbox->pack_start(*label, true, true);
797     ParamStringEntry * textbox = new ParamStringEntry(this, doc, node);
798     textbox->show();
799     hbox->pack_start(*textbox, false, false);
801     hbox->show();
803     return dynamic_cast<Gtk::Widget *>(hbox);
806 /** \brief  Return 'true' or 'false' */
807 Glib::ustring *
808 ParamBool::string (void)
810     Glib::ustring * mystring;
812     if (_value)
813         mystring = new Glib::ustring("true");
814     else
815         mystring = new Glib::ustring("false");
817     return mystring;
820 /** \brief  Return the value as a string */
821 Glib::ustring *
822 ParamInt::string (void)
824     char startstring[32];
825     sprintf(startstring, "%d", _value);
826     Glib::ustring * mystring = new Glib::ustring(startstring);
827     return mystring;
830 /** \brief  Return the value as a string */
831 Glib::ustring *
832 ParamFloat::string (void)
834     char startstring[G_ASCII_DTOSTR_BUF_SIZE];
835     g_ascii_dtostr(startstring, G_ASCII_DTOSTR_BUF_SIZE, _value);
836     Glib::ustring * mystring = new Glib::ustring(startstring);
837     return mystring;
840 /** \brief  Return the value as a string */
841 Glib::ustring *
842 ParamString::string (void)
844     Glib::ustring * mystring = new Glib::ustring("");
845     *mystring += "\"";
846     *mystring += _value;
847     *mystring += "\"";
848     return mystring;
852 }  /* namespace Extension */
853 }  /* namespace Inkscape */
855 /*
856   Local Variables:
857   mode:c++
858   c-file-style:"stroustrup"
859   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
860   indent-tabs-mode:nil
861   fill-column:99
862   End:
863 */
864 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :