Code

r11517@tres: ted | 2006-04-28 22:20:06 -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     return sp_repr_lookup_child(adult, "name", _name);
521 Inkscape::XML::Node *
522 Parameter::new_child (Inkscape::XML::Node * parent)
524     Inkscape::XML::Node * retval;
525     retval = sp_repr_new("inkscape:extension-param");
526     retval->setAttribute("name", _name);
528     parent->appendChild(retval);
529     return retval;
532 Inkscape::XML::Node *
533 Parameter::document_param_node (SPDocument * doc)
535     Inkscape::XML::Node * defs = SP_OBJECT_REPR(SP_DOCUMENT_DEFS(doc));
536     Inkscape::XML::Node * params = NULL;
538     GQuark const name_quark = g_quark_from_string("inkscape:extension-params");
540     for (Inkscape::XML::Node * child = defs->firstChild();
541             child != NULL;
542             child = child->next()) {
543         if ((GQuark)child->code() == name_quark &&
544                 !strcmp(child->attribute("extension"), extension->get_id())) {
545             params = child;
546             break;
547         }
548     }
550     if (params == NULL) {
551         params = sp_repr_new("inkscape:extension-param");
552         params->setAttribute("extension", extension->get_id());
553         defs->appendChild(params);
554     }
556     return params;
559 /** \brief  Basically, if there is no widget pass a NULL. */
560 Gtk::Widget *
561 Parameter::get_widget (void)
563     return NULL;
566 /** \brief  If I'm not sure which it is, just don't return a value. */
567 Glib::ustring *
568 Parameter::string (void)
570     Glib::ustring * mystring = new Glib::ustring("");
571     return mystring;
574 /** \brief  A class to make an adjustment that uses Extension params */
575 class ParamFloatAdjustment : public Gtk::Adjustment {
576     /** The parameter to adjust */
577     ParamFloat * _pref;
578 public:
579     /** \brief  Make the adjustment using an extension and the string
580                 describing the parameter. */
581     ParamFloatAdjustment (ParamFloat * param) :
582             Gtk::Adjustment(0.0, param->min(), param->max(), 0.1), _pref(param) {
583         this->set_value(_pref->get(NULL, NULL) /* \todo fix */);
584         this->signal_value_changed().connect(sigc::mem_fun(this, &ParamFloatAdjustment::val_changed));
585         return;
586     };
588     void val_changed (void);
589 }; /* class ParamFloatAdjustment */
591 /** \brief  A function to respond to the value_changed signal from the
592             adjustment.
594     This function just grabs the value from the adjustment and writes
595     it to the parameter.  Very simple, but yet beautiful.
596 */
597 void
598 ParamFloatAdjustment::val_changed (void)
600     // std::cout << "Value Changed to: " << this->get_value() << std::endl;
601     _pref->set(this->get_value(), NULL /* \todo fix */, NULL);
602     return;
605 /** \brief  A class to make an adjustment that uses Extension params */
606 class ParamIntAdjustment : public Gtk::Adjustment {
607     /** The parameter to adjust */
608     ParamInt * _pref;
609 public:
610     /** \brief  Make the adjustment using an extension and the string
611                 describing the parameter. */
612     ParamIntAdjustment (ParamInt * param) :
613             Gtk::Adjustment(0.0, param->min(), param->max(), 1.0), _pref(param) {
614         this->set_value(_pref->get(NULL, NULL) /* \todo fix */);
615         this->signal_value_changed().connect(sigc::mem_fun(this, &ParamIntAdjustment::val_changed));
616         return;
617     };
619     void val_changed (void);
620 }; /* class ParamIntAdjustment */
622 /** \brief  A function to respond to the value_changed signal from the
623             adjustment.
625     This function just grabs the value from the adjustment and writes
626     it to the parameter.  Very simple, but yet beautiful.
627 */
628 void
629 ParamIntAdjustment::val_changed (void)
631     // std::cout << "Value Changed to: " << this->get_value() << std::endl;
632     _pref->set((int)this->get_value(), NULL /* \todo fix */, NULL);
633     return;
636 /**
637     \brief  Creates a Float Adjustment for a float parameter
639     Builds a hbox with a label and a float adjustment in it.
640 */
641 Gtk::Widget *
642 ParamFloat::get_widget (void)
644     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox());
646     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
647     label->show();
648     hbox->pack_start(*label, true, true);
650     ParamFloatAdjustment * fadjust = Gtk::manage(new ParamFloatAdjustment(this));
651     Gtk::SpinButton * spin = Gtk::manage(new Gtk::SpinButton(*fadjust, 0.1, 1));
652     spin->show();
653     hbox->pack_start(*spin, false, false);
655     hbox->show();
657     return dynamic_cast<Gtk::Widget *>(hbox);
660 /**
661     \brief  Creates a Int Adjustment for a int parameter
663     Builds a hbox with a label and a int adjustment in it.
664 */
665 Gtk::Widget *
666 ParamInt::get_widget (void)
668     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox());
670     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
671     label->show();
672     hbox->pack_start(*label, true, true);
674     ParamIntAdjustment * fadjust = Gtk::manage(new ParamIntAdjustment(this));
675     Gtk::SpinButton * spin = Gtk::manage(new Gtk::SpinButton(*fadjust, 1.0, 0));
676     spin->show();
677     hbox->pack_start(*spin, false, false);
679     hbox->show();
681     return dynamic_cast<Gtk::Widget *>(hbox);
684 /** \brief  A check button which is Param aware.  It works with the
685             parameter to change it's value as the check button changes
686             value. */
687 class ParamBoolCheckButton : public Gtk::CheckButton {
688 private:
689     /** \brief  Param to change */
690     ParamBool * _pref;
691 public:
692     /** \brief  Initialize the check button
693         \param  param  Which parameter to adjust on changing the check button
695         This function sets the value of the checkbox to be that of the
696         parameter, and then sets up a callback to \c on_toggle.
697     */
698     ParamBoolCheckButton (ParamBool * param) :
699             Gtk::CheckButton(), _pref(param) {
700         this->set_active(_pref->get(NULL, NULL) /**\todo fix */);
701         this->signal_toggled().connect(sigc::mem_fun(this, &ParamBoolCheckButton::on_toggle));
702         return;
703     }
704     void on_toggle (void);
705 };
707 /**
708     \brief  A function to respond to the check box changing
710     Adjusts the value of the preference to match that in the check box.
711 */
712 void
713 ParamBoolCheckButton::on_toggle (void)
715     _pref->set(this->get_active(), NULL /**\todo fix this */, NULL);
716     return;
719 /**
720     \brief  Creates a bool check button for a bool parameter
722     Builds a hbox with a label and a check button in it.
723 */
724 Gtk::Widget *
725 ParamBool::get_widget (void)
727     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox());
729     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
730     label->show();
731     hbox->pack_start(*label, true, true);
733     ParamBoolCheckButton * checkbox = new ParamBoolCheckButton(this);
734     checkbox->show();
735     hbox->pack_start(*checkbox, false, false);
737     hbox->show();
739     return dynamic_cast<Gtk::Widget *>(hbox);
742 /** \brief  A special category of Gtk::Entry to handle string parameteres */
743 class ParamStringEntry : public Gtk::Entry {
744 private:
745     ParamString * _pref;
746 public:
747     /** \brief  Build a string preference for the given parameter
748         \param  pref  Where to get the string from, and where to put it
749                       when it changes.
750     */
751     ParamStringEntry (ParamString * pref) :
752         Gtk::Entry(), _pref(pref) {
753         if (_pref->get(NULL, NULL) != NULL)
754             this->set_text(Glib::ustring(_pref->get(NULL, NULL)));
755         this->signal_changed().connect(sigc::mem_fun(this, &ParamStringEntry::changed_text));
756     };
757     void changed_text (void);
758 };
760 /** \brief  Respond to the text box changing
762     This function responds to the box changing by grabbing the value
763     from the text box and putting it in the parameter.
764 */
765 void
766 ParamStringEntry::changed_text (void)
768     Glib::ustring data = this->get_text();
769     _pref->set(data.c_str(), NULL, NULL);
770     return;
773 /**
774     \brief  Creates a text box for the string parameter
776     Builds a hbox with a label and a text box in it.
777 */
778 Gtk::Widget *
779 ParamString::get_widget (void)
781     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox());
783     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
784     label->show();
785     hbox->pack_start(*label, true, true);
787     ParamStringEntry * textbox = new ParamStringEntry(this);
788     textbox->show();
789     hbox->pack_start(*textbox, false, false);
791     hbox->show();
793     return dynamic_cast<Gtk::Widget *>(hbox);
796 /** \brief  Return 'true' or 'false' */
797 Glib::ustring *
798 ParamBool::string (void)
800     Glib::ustring * mystring;
802     if (_value)
803         mystring = new Glib::ustring("true");
804     else
805         mystring = new Glib::ustring("false");
807     return mystring;
810 /** \brief  Return the value as a string */
811 Glib::ustring *
812 ParamInt::string (void)
814     char startstring[32];
815     sprintf(startstring, "%d", _value);
816     Glib::ustring * mystring = new Glib::ustring(startstring);
817     return mystring;
820 /** \brief  Return the value as a string */
821 Glib::ustring *
822 ParamFloat::string (void)
824     char startstring[G_ASCII_DTOSTR_BUF_SIZE];
825     g_ascii_dtostr(startstring, G_ASCII_DTOSTR_BUF_SIZE, _value);
826     Glib::ustring * mystring = new Glib::ustring(startstring);
827     return mystring;
830 /** \brief  Return the value as a string */
831 Glib::ustring *
832 ParamString::string (void)
834     Glib::ustring * mystring = new Glib::ustring("");
835     *mystring += "\"";
836     *mystring += _value;
837     *mystring += "\"";
838     return mystring;
842 }  /* namespace Extension */
843 }  /* namespace Inkscape */
845 /*
846   Local Variables:
847   mode:c++
848   c-file-style:"stroustrup"
849   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
850   indent-tabs-mode:nil
851   fill-column:99
852   End:
853 */
854 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :