Code

c1e8c04415e2f439add751e69266c186b3159b82
[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 /** \brief  Build the name to write the parameter in a node object.  This
516             requires the inkscape namespace and the other info. */
517 gchar *
518 Parameter::node_name (void)
520     return g_strdup_printf("inkscape:extension-param-%s-%s", extension->get_id(), _name);
523 Inkscape::XML::Node *
524 Parameter::document_param_node (SPDocument * doc)
526     Inkscape::XML::Node * defs = SP_OBJECT_REPR(SP_DOCUMENT_DEFS(doc));
527     Inkscape::XML::Node * params = NULL;
529     for (Inkscape::XML::Node * child = defs->firstChild();
530             child != NULL;
531             child = child->next()) {
532         if (!strcmp(child->name(), "inkscape:extension-param")) {
533             params = child;
534             break;
535         }
536     }
538     if (params == NULL) {
539         params = sp_repr_new("inkscape:extension-param");
540         defs->appendChild(params);
541     }
543     return params;
546 /** \brief  Basically, if there is no widget pass a NULL. */
547 Gtk::Widget *
548 Parameter::get_widget (void)
550     return NULL;
553 /** \brief  If I'm not sure which it is, just don't return a value. */
554 Glib::ustring *
555 Parameter::string (void)
557     Glib::ustring * mystring = new Glib::ustring("");
558     return mystring;
561 /** \brief  A class to make an adjustment that uses Extension params */
562 class ParamFloatAdjustment : public Gtk::Adjustment {
563     /** The parameter to adjust */
564     ParamFloat * _pref;
565 public:
566     /** \brief  Make the adjustment using an extension and the string
567                 describing the parameter. */
568     ParamFloatAdjustment (ParamFloat * param) :
569             Gtk::Adjustment(0.0, param->min(), param->max(), 0.1), _pref(param) {
570         this->set_value(_pref->get(NULL, NULL) /* \todo fix */);
571         this->signal_value_changed().connect(sigc::mem_fun(this, &ParamFloatAdjustment::val_changed));
572         return;
573     };
575     void val_changed (void);
576 }; /* class ParamFloatAdjustment */
578 /** \brief  A function to respond to the value_changed signal from the
579             adjustment.
581     This function just grabs the value from the adjustment and writes
582     it to the parameter.  Very simple, but yet beautiful.
583 */
584 void
585 ParamFloatAdjustment::val_changed (void)
587     // std::cout << "Value Changed to: " << this->get_value() << std::endl;
588     _pref->set(this->get_value(), NULL /* \todo fix */, NULL);
589     return;
592 /** \brief  A class to make an adjustment that uses Extension params */
593 class ParamIntAdjustment : public Gtk::Adjustment {
594     /** The parameter to adjust */
595     ParamInt * _pref;
596 public:
597     /** \brief  Make the adjustment using an extension and the string
598                 describing the parameter. */
599     ParamIntAdjustment (ParamInt * param) :
600             Gtk::Adjustment(0.0, param->min(), param->max(), 1.0), _pref(param) {
601         this->set_value(_pref->get(NULL, NULL) /* \todo fix */);
602         this->signal_value_changed().connect(sigc::mem_fun(this, &ParamIntAdjustment::val_changed));
603         return;
604     };
606     void val_changed (void);
607 }; /* class ParamIntAdjustment */
609 /** \brief  A function to respond to the value_changed signal from the
610             adjustment.
612     This function just grabs the value from the adjustment and writes
613     it to the parameter.  Very simple, but yet beautiful.
614 */
615 void
616 ParamIntAdjustment::val_changed (void)
618     // std::cout << "Value Changed to: " << this->get_value() << std::endl;
619     _pref->set((int)this->get_value(), NULL /* \todo fix */, NULL);
620     return;
623 /**
624     \brief  Creates a Float Adjustment for a float parameter
626     Builds a hbox with a label and a float adjustment in it.
627 */
628 Gtk::Widget *
629 ParamFloat::get_widget (void)
631     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox());
633     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
634     label->show();
635     hbox->pack_start(*label, true, true);
637     ParamFloatAdjustment * fadjust = Gtk::manage(new ParamFloatAdjustment(this));
638     Gtk::SpinButton * spin = Gtk::manage(new Gtk::SpinButton(*fadjust, 0.1, 1));
639     spin->show();
640     hbox->pack_start(*spin, false, false);
642     hbox->show();
644     return dynamic_cast<Gtk::Widget *>(hbox);
647 /**
648     \brief  Creates a Int Adjustment for a int parameter
650     Builds a hbox with a label and a int adjustment in it.
651 */
652 Gtk::Widget *
653 ParamInt::get_widget (void)
655     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox());
657     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
658     label->show();
659     hbox->pack_start(*label, true, true);
661     ParamIntAdjustment * fadjust = Gtk::manage(new ParamIntAdjustment(this));
662     Gtk::SpinButton * spin = Gtk::manage(new Gtk::SpinButton(*fadjust, 1.0, 0));
663     spin->show();
664     hbox->pack_start(*spin, false, false);
666     hbox->show();
668     return dynamic_cast<Gtk::Widget *>(hbox);
671 /** \brief  A check button which is Param aware.  It works with the
672             parameter to change it's value as the check button changes
673             value. */
674 class ParamBoolCheckButton : public Gtk::CheckButton {
675 private:
676     /** \brief  Param to change */
677     ParamBool * _pref;
678 public:
679     /** \brief  Initialize the check button
680         \param  param  Which parameter to adjust on changing the check button
682         This function sets the value of the checkbox to be that of the
683         parameter, and then sets up a callback to \c on_toggle.
684     */
685     ParamBoolCheckButton (ParamBool * param) :
686             Gtk::CheckButton(), _pref(param) {
687         this->set_active(_pref->get(NULL, NULL) /**\todo fix */);
688         this->signal_toggled().connect(sigc::mem_fun(this, &ParamBoolCheckButton::on_toggle));
689         return;
690     }
691     void on_toggle (void);
692 };
694 /**
695     \brief  A function to respond to the check box changing
697     Adjusts the value of the preference to match that in the check box.
698 */
699 void
700 ParamBoolCheckButton::on_toggle (void)
702     _pref->set(this->get_active(), NULL /**\todo fix this */, NULL);
703     return;
706 /**
707     \brief  Creates a bool check button for a bool parameter
709     Builds a hbox with a label and a check button in it.
710 */
711 Gtk::Widget *
712 ParamBool::get_widget (void)
714     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox());
716     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
717     label->show();
718     hbox->pack_start(*label, true, true);
720     ParamBoolCheckButton * checkbox = new ParamBoolCheckButton(this);
721     checkbox->show();
722     hbox->pack_start(*checkbox, false, false);
724     hbox->show();
726     return dynamic_cast<Gtk::Widget *>(hbox);
729 /** \brief  A special category of Gtk::Entry to handle string parameteres */
730 class ParamStringEntry : public Gtk::Entry {
731 private:
732     ParamString * _pref;
733 public:
734     /** \brief  Build a string preference for the given parameter
735         \param  pref  Where to get the string from, and where to put it
736                       when it changes.
737     */
738     ParamStringEntry (ParamString * pref) :
739         Gtk::Entry(), _pref(pref) {
740         if (_pref->get(NULL, NULL) != NULL)
741             this->set_text(Glib::ustring(_pref->get(NULL, NULL)));
742         this->signal_changed().connect(sigc::mem_fun(this, &ParamStringEntry::changed_text));
743     };
744     void changed_text (void);
745 };
747 /** \brief  Respond to the text box changing
749     This function responds to the box changing by grabbing the value
750     from the text box and putting it in the parameter.
751 */
752 void
753 ParamStringEntry::changed_text (void)
755     Glib::ustring data = this->get_text();
756     _pref->set(data.c_str(), NULL, NULL);
757     return;
760 /**
761     \brief  Creates a text box for the string parameter
763     Builds a hbox with a label and a text box in it.
764 */
765 Gtk::Widget *
766 ParamString::get_widget (void)
768     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox());
770     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
771     label->show();
772     hbox->pack_start(*label, true, true);
774     ParamStringEntry * textbox = new ParamStringEntry(this);
775     textbox->show();
776     hbox->pack_start(*textbox, false, false);
778     hbox->show();
780     return dynamic_cast<Gtk::Widget *>(hbox);
783 /** \brief  Return 'true' or 'false' */
784 Glib::ustring *
785 ParamBool::string (void)
787     Glib::ustring * mystring;
789     if (_value)
790         mystring = new Glib::ustring("true");
791     else
792         mystring = new Glib::ustring("false");
794     return mystring;
797 /** \brief  Return the value as a string */
798 Glib::ustring *
799 ParamInt::string (void)
801     char startstring[32];
802     sprintf(startstring, "%d", _value);
803     Glib::ustring * mystring = new Glib::ustring(startstring);
804     return mystring;
807 /** \brief  Return the value as a string */
808 Glib::ustring *
809 ParamFloat::string (void)
811     char startstring[G_ASCII_DTOSTR_BUF_SIZE];
812     g_ascii_dtostr(startstring, G_ASCII_DTOSTR_BUF_SIZE, _value);
813     Glib::ustring * mystring = new Glib::ustring(startstring);
814     return mystring;
817 /** \brief  Return the value as a string */
818 Glib::ustring *
819 ParamString::string (void)
821     Glib::ustring * mystring = new Glib::ustring("");
822     *mystring += "\"";
823     *mystring += _value;
824     *mystring += "\"";
825     return mystring;
829 }  /* namespace Extension */
830 }  /* namespace Inkscape */
832 /*
833   Local Variables:
834   mode:c++
835   c-file-style:"stroustrup"
836   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
837   indent-tabs-mode:nil
838   fill-column:99
839   End:
840 */
841 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :