Code

r11516@tres: ted | 2006-04-26 21:30:18 -0700
[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 "extension.h"
26 #include "prefs-utils.h"
27 #include "document-private.h"
28 #include "sp-object.h"
30 #include "parameter.h"
32 /** \brief  The root directory in the preferences database for extension
33             related parameters. */
34 #define PREF_DIR "extensions"
36 namespace Inkscape {
37 namespace Extension {
39 /** \brief  A boolean parameter */
40 class ParamBool : public Parameter {
41 private:
42     /** \brief  Internal value. */
43     bool _value;
44 public:
45     ParamBool(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
46     /** \brief  Returns \c _value */
47     bool get (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node) { return _value; }
48     bool set (bool in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node);
49     Gtk::Widget * get_widget(void);
50     Glib::ustring * string (void);
51 };
53 /** \brief  Use the superclass' allocator and set the \c _value */
54 ParamBool::ParamBool (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
55         Parameter(name, guitext, desc, scope, ext), _value(false)
56 {
57     const char * defaultval = NULL;
58     if (sp_repr_children(xml) != NULL)
59         defaultval = sp_repr_children(xml)->content();
61     if (defaultval != NULL && (!strcmp(defaultval, "TRUE") || !strcmp(defaultval, "true") || !strcmp(defaultval, "1"))) {
62         _value = true;
63     } else {
64         _value = false;
65     }
67     gchar * pref_name = this->pref_name();
68     _value = (bool)prefs_get_int_attribute(PREF_DIR, pref_name, _value);
69     g_free(pref_name);
71     return;
72 }
74 class ParamInt : public Parameter {
75 private:
76     /** \brief  Internal value. */
77     int _value;
78     int _min;
79     int _max;
80 public:
81     ParamInt (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
82     /** \brief  Returns \c _value */
83     int get (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node) { return _value; }
84     int set (int in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node);
85     int max (void) { return _max; }
86     int min (void) { return _min; }
87     Gtk::Widget * get_widget(void);
88     Glib::ustring * string (void);
89 };
91 /** \brief  Use the superclass' allocator and set the \c _value */
92 ParamInt::ParamInt (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
93         Parameter(name, guitext, desc, scope, ext), _value(0), _min(0), _max(10)
94 {
95     const char * defaultval = NULL;
96     if (sp_repr_children(xml) != NULL)
97         defaultval = sp_repr_children(xml)->content();
98     if (defaultval != NULL) {
99         _value = atoi(defaultval);
100     }
102     const char * maxval = xml->attribute("max");
103     if (maxval != NULL)
104         _max = atoi(maxval);
106     const char * minval = xml->attribute("min");
107     if (minval != NULL)
108         _min = atoi(minval);
110     /* We're handling this by just killing both values */
111     if (_max < _min) {
112         _max = 10;
113         _min = 0;
114     }
116     gchar * pref_name = this->pref_name();
117     _value = prefs_get_int_attribute(PREF_DIR, pref_name, _value);
118     g_free(pref_name);
120     // std::cout << "New Int::  value: " << _value << "  max: " << _max << "  min: " << _min << std::endl;
122     if (_value > _max) _value = _max;
123     if (_value < _min) _value = _min;
125     return;
128 class ParamFloat : public Parameter {
129 private:
130     /** \brief  Internal value. */
131     float _value;
132     float _min;
133     float _max;
134 public:
135     ParamFloat (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
136     /** \brief  Returns \c _value */
137     float get (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node) { return _value; }
138     float set (float in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node);
139     float max (void) { return _max; }
140     float min (void) { return _min; }
141     Gtk::Widget * get_widget(void);
142     Glib::ustring * string (void);
143 };
145 /** \brief  Use the superclass' allocator and set the \c _value */
146 ParamFloat::ParamFloat (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
147         Parameter(name, guitext, desc, scope, ext), _value(0.0), _min(0.0), _max(10.0)
149     const char * defaultval = NULL;
150     if (sp_repr_children(xml) != NULL)
151         defaultval = sp_repr_children(xml)->content();
152     if (defaultval != NULL) {
153         _value = atof(defaultval);
154     }
156     const char * maxval = xml->attribute("max");
157     if (maxval != NULL)
158         _max = atof(maxval);
160     const char * minval = xml->attribute("min");
161     if (minval != NULL)
162         _min = atof(minval);
164     /* We're handling this by just killing both values */
165     if (_max < _min) {
166         _max = 10.0;
167         _min = 0.0;
168     }
170     gchar * pref_name = this->pref_name();
171     _value = prefs_get_double_attribute(PREF_DIR, pref_name, _value);
172     g_free(pref_name);
174     // std::cout << "New Float::  value: " << _value << "  max: " << _max << "  min: " << _min << std::endl;
176     if (_value > _max) _value = _max;
177     if (_value < _min) _value = _min;
179     return;
182 class ParamString : public Parameter {
183 private:
184     /** \brief  Internal value.  This should point to a string that has
185                 been allocated in memory.  And should be free'd. */
186     gchar * _value;
187 public:
188     ParamString(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
189     ~ParamString(void);
190     /** \brief  Returns \c _value, with a \i const to protect it. */
191     const gchar * get (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node) { return _value; }
192     const gchar * set (const gchar * in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node);
193     Gtk::Widget * get_widget(void);
194     Glib::ustring * string (void);
195 };
197 /**
198     \return None
199     \brief  This function creates a parameter that can be used later.  This
200             is typically done in the creation of the extension and defined
201             in the XML file describing the extension (it's private so people
202             have to use the system) :)
203     \param  in_repr  The XML describing the parameter
205     This function first grabs all of the data out of the Repr and puts
206     it into local variables.  Actually, these are just pointers, and the
207     data is not duplicated so we need to be careful with it.  If there
208     isn't a name or a type in the XML, then no parameter is created as
209     the function just returns.
211     From this point on, we're pretty committed as we've allocated an
212     object and we're starting to fill it.  The name is set first, and
213     is created with a strdup to actually allocate memory for it.  Then
214     there is a case statement (roughly because strcmp requires 'ifs')
215     based on what type of parameter this is.  Depending which type it
216     is, the value is interpreted differently, but they are relatively
217     straight forward.  In all cases the value is set to the default
218     value from the XML and the type is set to the interpreted type.
219 */
220 Parameter *
221 Parameter::make (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext)
223     const char * name;
224     const char * type;
225     const char * guitext;
226     const char * desc;
227     const char * scope_str;
228     Parameter::_scope_t scope = Parameter::SCOPE_USER;
230     name = in_repr->attribute("name");
231     type = in_repr->attribute("type");
232     guitext = in_repr->attribute("gui-text");
233     if (guitext == NULL)
234         guitext = in_repr->attribute("_gui-text");
235     desc = in_repr->attribute("gui-description");
236     if (desc == NULL)
237         desc = in_repr->attribute("_gui-description");
238     scope_str = in_repr->attribute("scope");
240     /* In this case we just don't have enough information */
241     if (name == NULL || type == NULL) {
242         return NULL;
243     }
245     if (scope_str != NULL) {
246         if (!strcmp(scope_str, "user")) {
247             scope = Parameter::SCOPE_USER;
248         } else if (!strcmp(scope_str, "document")) {
249             scope = Parameter::SCOPE_DOCUMENT;
250         } else if (!strcmp(scope_str, "node")) {
251             scope = Parameter::SCOPE_NODE;
252         }
253     }
255     Parameter * param = NULL;
256     if (!strcmp(type, "boolean")) {
257         param = new ParamBool(name, guitext, desc, scope, in_ext, in_repr);
258     } else if (!strcmp(type, "int")) {
259         param = new ParamInt(name, guitext, desc, scope, in_ext, in_repr);
260     } else if (!strcmp(type, "float")) {
261         param = new ParamFloat(name, guitext, desc, scope, in_ext, in_repr);
262     } else if (!strcmp(type, "string")) {
263         param = new ParamString(name, guitext, desc, scope, in_ext, in_repr);
264     }
266     /* Note: param could equal NULL */
267     return param;
270 /** \brief  A function to set the \c _value
271     \param  in   The value to set to
272     \param  doc  A document that should be used to set the value.
273     \param  node The node where the value may be placed
275     This function sets the internal value, but it also sets the value
276     in the preferences structure.  To put it in the right place, \c PREF_DIR
277     and \c pref_name() are used.
278 */
279 bool
280 ParamBool::set (bool in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
282     _value = in;
284     gchar * prefname = this->pref_name();
285     prefs_set_int_attribute(PREF_DIR, prefname, _value == true ? 1 : 0);
286     g_free(prefname);
288     return _value;
291 /** \brief  A function to set the \c _value
292     \param  in   The value to set to
293     \param  doc  A document that should be used to set the value.
294     \param  node The node where the value may be placed
296     This function sets the internal value, but it also sets the value
297     in the preferences structure.  To put it in the right place, \c PREF_DIR
298     and \c pref_name() are used.
299 */
300 int
301 ParamInt::set (int in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
303     _value = in;
304     if (_value > _max) _value = _max;
305     if (_value < _min) _value = _min;
307     gchar * prefname = this->pref_name();
308     prefs_set_int_attribute(PREF_DIR, prefname, _value);
309     g_free(prefname);
311     return _value;
314 /** \brief  A function to set the \c _value
315     \param  in   The value to set to
316     \param  doc  A document that should be used to set the value.
317     \param  node The node where the value may be placed
319     This function sets the internal value, but it also sets the value
320     in the preferences structure.  To put it in the right place, \c PREF_DIR
321     and \c pref_name() are used.
322 */
323 float
324 ParamFloat::set (float in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
326     _value = in;
327     if (_value > _max) _value = _max;
328     if (_value < _min) _value = _min;
330     gchar * prefname = this->pref_name();
331     prefs_set_double_attribute(PREF_DIR, prefname, _value);
332     g_free(prefname);
334     return _value;
337 /** \brief  A function to set the \c _value
338     \param  in   The value to set to
339     \param  doc  A document that should be used to set the value.
340     \param  node The node where the value may be placed
342     This function sets the internal value, but it also sets the value
343     in the preferences structure.  To put it in the right place, \c PREF_DIR
344     and \c pref_name() are used.
346     To copy the data into _value the old memory must be free'd first.
347     It is important to note that \c g_free handles \c NULL just fine.  Then
348     the passed in value is duplicated using \c g_strdup().
349 */
350 const gchar *
351 ParamString::set (const gchar * in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
353     if (in == NULL) return NULL; /* Can't have NULL string */
355     if (_value != NULL)
356         g_free(_value);
357     _value = g_strdup(in);
359     gchar * prefname = this->pref_name();
360     prefs_set_string_attribute(PREF_DIR, prefname, _value);
361     g_free(prefname);
363     return _value;
366 /** \brief  Wrapper to cast to the object and use it's function.  */
367 bool
368 Parameter::get_bool (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node)
370     ParamBool * boolpntr;
371     boolpntr = dynamic_cast<ParamBool *>(this);
372     if (boolpntr == NULL)
373         throw Extension::param_wrong_type();
374     return boolpntr->get(doc, node);
377 /** \brief  Wrapper to cast to the object and use it's function.  */
378 int
379 Parameter::get_int (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node)
381     ParamInt * intpntr;
382     intpntr = dynamic_cast<ParamInt *>(this);
383     if (intpntr == NULL)
384         throw Extension::param_wrong_type();
385     return intpntr->get(doc, node);
388 /** \brief  Wrapper to cast to the object and use it's function.  */
389 float
390 Parameter::get_float (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node)
392     ParamFloat * floatpntr;
393     floatpntr = dynamic_cast<ParamFloat *>(this);
394     if (floatpntr == NULL)
395         throw Extension::param_wrong_type();
396     return floatpntr->get(doc, node);
399 /** \brief  Wrapper to cast to the object and use it's function.  */
400 const gchar *
401 Parameter::get_string (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node)
403     ParamString * stringpntr;
404     stringpntr = dynamic_cast<ParamString *>(this);
405     if (stringpntr == NULL)
406         throw Extension::param_wrong_type();
407     return stringpntr->get(doc, node);
410 /** \brief  Wrapper to cast to the object and use it's function.  */
411 bool
412 Parameter::set_bool (bool in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
414     ParamBool * boolpntr;
415     boolpntr = dynamic_cast<ParamBool *>(this);
416     if (boolpntr == NULL)
417         throw Extension::param_wrong_type();
418     return boolpntr->set(in, doc, node);
421 /** \brief  Wrapper to cast to the object and use it's function.  */
422 int
423 Parameter::set_int (int in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
425     ParamInt * intpntr;
426     intpntr = dynamic_cast<ParamInt *>(this);
427     if (intpntr == NULL)
428         throw Extension::param_wrong_type();
429     return intpntr->set(in, doc, node);
432 /** \brief  Wrapper to cast to the object and use it's function.  */
433 float
434 Parameter::set_float (float in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
436     ParamFloat * floatpntr;
437     floatpntr = dynamic_cast<ParamFloat *>(this);
438     if (floatpntr == NULL)
439         throw Extension::param_wrong_type();
440     return floatpntr->set(in, doc, node);
443 /** \brief  Wrapper to cast to the object and use it's function.  */
444 const gchar *
445 Parameter::set_string (const gchar * in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
447     ParamString * stringpntr;
448     stringpntr = dynamic_cast<ParamString *>(this);
449     if (stringpntr == NULL)
450         throw Extension::param_wrong_type();
451     return stringpntr->set(in, doc, node);
454 /** \brief  Initialize the object, to do that, copy the data. */
455 ParamString::ParamString (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
456     Parameter(name, guitext, desc, scope, ext), _value(NULL)
458     const char * defaultval = NULL;
459     if (sp_repr_children(xml) != NULL)
460         defaultval = sp_repr_children(xml)->content();
462     gchar * pref_name = this->pref_name();
463     const gchar * paramval = prefs_get_string_attribute(PREF_DIR, pref_name);
464     g_free(pref_name);
466     if (paramval != NULL)
467         defaultval = paramval;
468     if (defaultval != NULL)
469         _value = g_strdup(defaultval);
471     return;
474 /** \brief  Free the allocated data. */
475 ParamString::~ParamString(void)
477     g_free(_value);
480 /** \brief  Oop, now that we need a parameter, we need it's name.  */
481 Parameter::Parameter (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext) :
482     extension(ext), _name(NULL), _desc(NULL), _scope(scope), _text(NULL)
484     if (name != NULL)
485         _name = g_strdup(name);
486     if (desc != NULL) {
487         _desc = g_strdup(desc);
488         // printf("Adding description: '%s' on '%s'\n", _desc, _name);
489     }
492     if (guitext != NULL)
493         _text = g_strdup(guitext);
494     else
495         _text = g_strdup(name);
497     return;
500 /** \brief  Just free the allocated name. */
501 Parameter::~Parameter (void)
503     g_free(_name);
504     g_free(_text);
507 /** \brief  Build the name to write the parameter from the extension's
508             ID and the name of this parameter. */
509 gchar *
510 Parameter::pref_name (void)
512     return g_strdup_printf("%s.%s", extension->get_id(), _name);
515 Inkscape::XML::Node *
516 Parameter::find_child (Inkscape::XML::Node * adult)
518     Inkscape::XML::Node * retval = NULL;
519     for (retval = adult->firstChild();
520             retval != NULL;
521             retval = retval->next()) {
522         gchar const * name = retval->attribute("name");
523         if (name == NULL) continue;
524         if (!strcmp(name, _name))
525             break;
526     }
528     return retval;
531 Inkscape::XML::Node *
532 Parameter::new_child (Inkscape::XML::Node * parent)
534     Inkscape::XML::Node * retval;
535     retval = sp_repr_new("inkscape:extension-param");
536     retval->setAttribute("extension", extension->get_id());
537     retval->setAttribute("name", _name);
539     parent->appendChild(retval);
540     return retval;
543 Inkscape::XML::Node *
544 Parameter::document_param_node (SPDocument * doc)
546     Inkscape::XML::Node * defs = SP_OBJECT_REPR(SP_DOCUMENT_DEFS(doc));
547     Inkscape::XML::Node * params = NULL;
549     for (Inkscape::XML::Node * child = defs->firstChild();
550             child != NULL;
551             child = child->next()) {
552         if (!strcmp(child->name(), "inkscape:extension-param")) {
553             params = child;
554             break;
555         }
556     }
558     if (params == NULL) {
559         params = sp_repr_new("inkscape:extension-param");
560         defs->appendChild(params);
561     }
563     return params;
566 /** \brief  Basically, if there is no widget pass a NULL. */
567 Gtk::Widget *
568 Parameter::get_widget (void)
570     return NULL;
573 /** \brief  If I'm not sure which it is, just don't return a value. */
574 Glib::ustring *
575 Parameter::string (void)
577     Glib::ustring * mystring = new Glib::ustring("");
578     return mystring;
581 /** \brief  A class to make an adjustment that uses Extension params */
582 class ParamFloatAdjustment : public Gtk::Adjustment {
583     /** The parameter to adjust */
584     ParamFloat * _pref;
585 public:
586     /** \brief  Make the adjustment using an extension and the string
587                 describing the parameter. */
588     ParamFloatAdjustment (ParamFloat * param) :
589             Gtk::Adjustment(0.0, param->min(), param->max(), 0.1), _pref(param) {
590         this->set_value(_pref->get(NULL, NULL) /* \todo fix */);
591         this->signal_value_changed().connect(sigc::mem_fun(this, &ParamFloatAdjustment::val_changed));
592         return;
593     };
595     void val_changed (void);
596 }; /* class ParamFloatAdjustment */
598 /** \brief  A function to respond to the value_changed signal from the
599             adjustment.
601     This function just grabs the value from the adjustment and writes
602     it to the parameter.  Very simple, but yet beautiful.
603 */
604 void
605 ParamFloatAdjustment::val_changed (void)
607     // std::cout << "Value Changed to: " << this->get_value() << std::endl;
608     _pref->set(this->get_value(), NULL /* \todo fix */, NULL);
609     return;
612 /** \brief  A class to make an adjustment that uses Extension params */
613 class ParamIntAdjustment : public Gtk::Adjustment {
614     /** The parameter to adjust */
615     ParamInt * _pref;
616 public:
617     /** \brief  Make the adjustment using an extension and the string
618                 describing the parameter. */
619     ParamIntAdjustment (ParamInt * param) :
620             Gtk::Adjustment(0.0, param->min(), param->max(), 1.0), _pref(param) {
621         this->set_value(_pref->get(NULL, NULL) /* \todo fix */);
622         this->signal_value_changed().connect(sigc::mem_fun(this, &ParamIntAdjustment::val_changed));
623         return;
624     };
626     void val_changed (void);
627 }; /* class ParamIntAdjustment */
629 /** \brief  A function to respond to the value_changed signal from the
630             adjustment.
632     This function just grabs the value from the adjustment and writes
633     it to the parameter.  Very simple, but yet beautiful.
634 */
635 void
636 ParamIntAdjustment::val_changed (void)
638     // std::cout << "Value Changed to: " << this->get_value() << std::endl;
639     _pref->set((int)this->get_value(), NULL /* \todo fix */, NULL);
640     return;
643 /**
644     \brief  Creates a Float Adjustment for a float parameter
646     Builds a hbox with a label and a float adjustment in it.
647 */
648 Gtk::Widget *
649 ParamFloat::get_widget (void)
651     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox());
653     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
654     label->show();
655     hbox->pack_start(*label, true, true);
657     ParamFloatAdjustment * fadjust = Gtk::manage(new ParamFloatAdjustment(this));
658     Gtk::SpinButton * spin = Gtk::manage(new Gtk::SpinButton(*fadjust, 0.1, 1));
659     spin->show();
660     hbox->pack_start(*spin, false, false);
662     hbox->show();
664     return dynamic_cast<Gtk::Widget *>(hbox);
667 /**
668     \brief  Creates a Int Adjustment for a int parameter
670     Builds a hbox with a label and a int adjustment in it.
671 */
672 Gtk::Widget *
673 ParamInt::get_widget (void)
675     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox());
677     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
678     label->show();
679     hbox->pack_start(*label, true, true);
681     ParamIntAdjustment * fadjust = Gtk::manage(new ParamIntAdjustment(this));
682     Gtk::SpinButton * spin = Gtk::manage(new Gtk::SpinButton(*fadjust, 1.0, 0));
683     spin->show();
684     hbox->pack_start(*spin, false, false);
686     hbox->show();
688     return dynamic_cast<Gtk::Widget *>(hbox);
691 /** \brief  A check button which is Param aware.  It works with the
692             parameter to change it's value as the check button changes
693             value. */
694 class ParamBoolCheckButton : public Gtk::CheckButton {
695 private:
696     /** \brief  Param to change */
697     ParamBool * _pref;
698 public:
699     /** \brief  Initialize the check button
700         \param  param  Which parameter to adjust on changing the check button
702         This function sets the value of the checkbox to be that of the
703         parameter, and then sets up a callback to \c on_toggle.
704     */
705     ParamBoolCheckButton (ParamBool * param) :
706             Gtk::CheckButton(), _pref(param) {
707         this->set_active(_pref->get(NULL, NULL) /**\todo fix */);
708         this->signal_toggled().connect(sigc::mem_fun(this, &ParamBoolCheckButton::on_toggle));
709         return;
710     }
711     void on_toggle (void);
712 };
714 /**
715     \brief  A function to respond to the check box changing
717     Adjusts the value of the preference to match that in the check box.
718 */
719 void
720 ParamBoolCheckButton::on_toggle (void)
722     _pref->set(this->get_active(), NULL /**\todo fix this */, NULL);
723     return;
726 /**
727     \brief  Creates a bool check button for a bool parameter
729     Builds a hbox with a label and a check button in it.
730 */
731 Gtk::Widget *
732 ParamBool::get_widget (void)
734     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox());
736     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
737     label->show();
738     hbox->pack_start(*label, true, true);
740     ParamBoolCheckButton * checkbox = new ParamBoolCheckButton(this);
741     checkbox->show();
742     hbox->pack_start(*checkbox, false, false);
744     hbox->show();
746     return dynamic_cast<Gtk::Widget *>(hbox);
749 /** \brief  A special category of Gtk::Entry to handle string parameteres */
750 class ParamStringEntry : public Gtk::Entry {
751 private:
752     ParamString * _pref;
753 public:
754     /** \brief  Build a string preference for the given parameter
755         \param  pref  Where to get the string from, and where to put it
756                       when it changes.
757     */
758     ParamStringEntry (ParamString * pref) :
759         Gtk::Entry(), _pref(pref) {
760         if (_pref->get(NULL, NULL) != NULL)
761             this->set_text(Glib::ustring(_pref->get(NULL, NULL)));
762         this->signal_changed().connect(sigc::mem_fun(this, &ParamStringEntry::changed_text));
763     };
764     void changed_text (void);
765 };
767 /** \brief  Respond to the text box changing
769     This function responds to the box changing by grabbing the value
770     from the text box and putting it in the parameter.
771 */
772 void
773 ParamStringEntry::changed_text (void)
775     Glib::ustring data = this->get_text();
776     _pref->set(data.c_str(), NULL, NULL);
777     return;
780 /**
781     \brief  Creates a text box for the string parameter
783     Builds a hbox with a label and a text box in it.
784 */
785 Gtk::Widget *
786 ParamString::get_widget (void)
788     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox());
790     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
791     label->show();
792     hbox->pack_start(*label, true, true);
794     ParamStringEntry * textbox = new ParamStringEntry(this);
795     textbox->show();
796     hbox->pack_start(*textbox, false, false);
798     hbox->show();
800     return dynamic_cast<Gtk::Widget *>(hbox);
803 /** \brief  Return 'true' or 'false' */
804 Glib::ustring *
805 ParamBool::string (void)
807     Glib::ustring * mystring;
809     if (_value)
810         mystring = new Glib::ustring("true");
811     else
812         mystring = new Glib::ustring("false");
814     return mystring;
817 /** \brief  Return the value as a string */
818 Glib::ustring *
819 ParamInt::string (void)
821     char startstring[32];
822     sprintf(startstring, "%d", _value);
823     Glib::ustring * mystring = new Glib::ustring(startstring);
824     return mystring;
827 /** \brief  Return the value as a string */
828 Glib::ustring *
829 ParamFloat::string (void)
831     char startstring[G_ASCII_DTOSTR_BUF_SIZE];
832     g_ascii_dtostr(startstring, G_ASCII_DTOSTR_BUF_SIZE, _value);
833     Glib::ustring * mystring = new Glib::ustring(startstring);
834     return mystring;
837 /** \brief  Return the value as a string */
838 Glib::ustring *
839 ParamString::string (void)
841     Glib::ustring * mystring = new Glib::ustring("");
842     *mystring += "\"";
843     *mystring += _value;
844     *mystring += "\"";
845     return mystring;
849 }  /* namespace Extension */
850 }  /* namespace Inkscape */
852 /*
853   Local Variables:
854   mode:c++
855   c-file-style:"stroustrup"
856   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
857   indent-tabs-mode:nil
858   fill-column:99
859   End:
860 */
861 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :