Code

r11472@tres: ted | 2006-04-22 20:32:45 -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 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"
28 #include "parameter.h"
30 /** \brief  The root directory in the preferences database for extension
31             related parameters. */
32 #define PREF_DIR "extensions"
34 namespace Inkscape {
35 namespace Extension {
37 /** \brief  A boolean parameter */
38 class ParamBool : public Parameter {
39 private:
40     /** \brief  Internal value. */
41     bool _value;
42 public:
43     ParamBool(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
44     /** \brief  Returns \c _value */
45     bool get (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node) { return _value; }
46     bool set (bool in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node);
47     Gtk::Widget * get_widget(void);
48     Glib::ustring * string (void);
49 };
51 /** \brief  Use the superclass' allocator and set the \c _value */
52 ParamBool::ParamBool (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
53         Parameter(name, guitext, desc, scope, ext), _value(false)
54 {
55     const char * defaultval = NULL;
56     if (sp_repr_children(xml) != NULL)
57         defaultval = sp_repr_children(xml)->content();
59     if (defaultval != NULL && (!strcmp(defaultval, "TRUE") || !strcmp(defaultval, "true") || !strcmp(defaultval, "1"))) {
60         _value = true;
61     } else {
62         _value = false;
63     }
65     gchar * pref_name = this->pref_name();
66     _value = (bool)prefs_get_int_attribute(PREF_DIR, pref_name, _value);
67     g_free(pref_name);
69     return;
70 }
72 class ParamInt : public Parameter {
73 private:
74     /** \brief  Internal value. */
75     int _value;
76     int _min;
77     int _max;
78 public:
79     ParamInt (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
80     /** \brief  Returns \c _value */
81     int get (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node) { return _value; }
82     int set (int in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node);
83     int max (void) { return _max; }
84     int min (void) { return _min; }
85     Gtk::Widget * get_widget(void);
86     Glib::ustring * string (void);
87 };
89 /** \brief  Use the superclass' allocator and set the \c _value */
90 ParamInt::ParamInt (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
91         Parameter(name, guitext, desc, scope, ext), _value(0), _min(0), _max(10)
92 {
93     const char * defaultval = NULL;
94     if (sp_repr_children(xml) != NULL)
95         defaultval = sp_repr_children(xml)->content();
96     if (defaultval != NULL) {
97         _value = atoi(defaultval);
98     }
100     const char * maxval = xml->attribute("max");
101     if (maxval != NULL)
102         _max = atoi(maxval);
104     const char * minval = xml->attribute("min");
105     if (minval != NULL)
106         _min = atoi(minval);
108     /* We're handling this by just killing both values */
109     if (_max < _min) {
110         _max = 10;
111         _min = 0;
112     }
114     gchar * pref_name = this->pref_name();
115     _value = prefs_get_int_attribute(PREF_DIR, pref_name, _value);
116     g_free(pref_name);
118     // std::cout << "New Int::  value: " << _value << "  max: " << _max << "  min: " << _min << std::endl;
120     if (_value > _max) _value = _max;
121     if (_value < _min) _value = _min;
123     return;
126 class ParamFloat : public Parameter {
127 private:
128     /** \brief  Internal value. */
129     float _value;
130     float _min;
131     float _max;
132 public:
133     ParamFloat (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
134     /** \brief  Returns \c _value */
135     float get (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node) { return _value; }
136     float set (float in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node);
137     float max (void) { return _max; }
138     float min (void) { return _min; }
139     Gtk::Widget * get_widget(void);
140     Glib::ustring * string (void);
141 };
143 /** \brief  Use the superclass' allocator and set the \c _value */
144 ParamFloat::ParamFloat (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
145         Parameter(name, guitext, desc, scope, ext), _value(0.0), _min(0.0), _max(10.0)
147     const char * defaultval = NULL;
148     if (sp_repr_children(xml) != NULL)
149         defaultval = sp_repr_children(xml)->content();
150     if (defaultval != NULL) {
151         _value = atof(defaultval);
152     }
154     const char * maxval = xml->attribute("max");
155     if (maxval != NULL)
156         _max = atof(maxval);
158     const char * minval = xml->attribute("min");
159     if (minval != NULL)
160         _min = atof(minval);
162     /* We're handling this by just killing both values */
163     if (_max < _min) {
164         _max = 10.0;
165         _min = 0.0;
166     }
168     gchar * pref_name = this->pref_name();
169     _value = prefs_get_double_attribute(PREF_DIR, pref_name, _value);
170     g_free(pref_name);
172     // std::cout << "New Float::  value: " << _value << "  max: " << _max << "  min: " << _min << std::endl;
174     if (_value > _max) _value = _max;
175     if (_value < _min) _value = _min;
177     return;
180 class ParamString : public Parameter {
181 private:
182     /** \brief  Internal value.  This should point to a string that has
183                 been allocated in memory.  And should be free'd. */
184     gchar * _value;
185 public:
186     ParamString(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
187     ~ParamString(void);
188     /** \brief  Returns \c _value, with a \i const to protect it. */
189     const gchar * get (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node) { return _value; }
190     const gchar * set (const gchar * in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node);
191     Gtk::Widget * get_widget(void);
192     Glib::ustring * string (void);
193 };
195 /**
196     \return None
197     \brief  This function creates a parameter that can be used later.  This
198             is typically done in the creation of the extension and defined
199             in the XML file describing the extension (it's private so people
200             have to use the system) :)
201     \param  in_repr  The XML describing the parameter
203     This function first grabs all of the data out of the Repr and puts
204     it into local variables.  Actually, these are just pointers, and the
205     data is not duplicated so we need to be careful with it.  If there
206     isn't a name or a type in the XML, then no parameter is created as
207     the function just returns.
209     From this point on, we're pretty committed as we've allocated an
210     object and we're starting to fill it.  The name is set first, and
211     is created with a strdup to actually allocate memory for it.  Then
212     there is a case statement (roughly because strcmp requires 'ifs')
213     based on what type of parameter this is.  Depending which type it
214     is, the value is interpreted differently, but they are relatively
215     straight forward.  In all cases the value is set to the default
216     value from the XML and the type is set to the interpreted type.
217 */
218 Parameter *
219 Parameter::make (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext)
221     const char * name;
222     const char * type;
223     const char * guitext;
224     const char * desc;
225     const char * scope_str;
226     Parameter::_scope_t scope = Parameter::SCOPE_USER;
228     name = in_repr->attribute("name");
229     type = in_repr->attribute("type");
230     guitext = in_repr->attribute("gui-text");
231     if (guitext == NULL)
232         guitext = in_repr->attribute("_gui-text");
233     desc = in_repr->attribute("gui-description");
234     if (desc == NULL)
235         desc = in_repr->attribute("_gui-description");
236     scope_str = in_repr->attribute("scope");
238     /* In this case we just don't have enough information */
239     if (name == NULL || type == NULL) {
240         return NULL;
241     }
243     if (scope_str != NULL) {
244         if (!strcmp(scope_str, "user")) {
245             scope = Parameter::SCOPE_USER;
246         } else if (!strcmp(scope_str, "document")) {
247             scope = Parameter::SCOPE_DOCUMENT;
248         } else if (!strcmp(scope_str, "node")) {
249             scope = Parameter::SCOPE_NODE;
250         }
251     }
253     Parameter * param = NULL;
254     if (!strcmp(type, "boolean")) {
255         param = new ParamBool(name, guitext, desc, scope, in_ext, in_repr);
256     } else if (!strcmp(type, "int")) {
257         param = new ParamInt(name, guitext, desc, scope, in_ext, in_repr);
258     } else if (!strcmp(type, "float")) {
259         param = new ParamFloat(name, guitext, desc, scope, in_ext, in_repr);
260     } else if (!strcmp(type, "string")) {
261         param = new ParamString(name, guitext, desc, scope, in_ext, in_repr);
262     }
264     /* Note: param could equal NULL */
265     return param;
268 /** \brief  A function to set the \c _value
269     \param  in   The value to set to
270     \param  doc  A document that should be used to set the value.
271     \param  node The node where the value may be placed
273     This function sets the internal value, but it also sets the value
274     in the preferences structure.  To put it in the right place, \c PREF_DIR
275     and \c pref_name() are used.
276 */
277 bool
278 ParamBool::set (bool in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
280     _value = in;
282     gchar * prefname = this->pref_name();
283     prefs_set_int_attribute(PREF_DIR, prefname, _value == true ? 1 : 0);
284     g_free(prefname);
286     return _value;
289 /** \brief  A function to set the \c _value
290     \param  in   The value to set to
291     \param  doc  A document that should be used to set the value.
292     \param  node The node where the value may be placed
294     This function sets the internal value, but it also sets the value
295     in the preferences structure.  To put it in the right place, \c PREF_DIR
296     and \c pref_name() are used.
297 */
298 int
299 ParamInt::set (int in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
301     _value = in;
302     if (_value > _max) _value = _max;
303     if (_value < _min) _value = _min;
305     gchar * prefname = this->pref_name();
306     prefs_set_int_attribute(PREF_DIR, prefname, _value);
307     g_free(prefname);
309     return _value;
312 /** \brief  A function to set the \c _value
313     \param  in   The value to set to
314     \param  doc  A document that should be used to set the value.
315     \param  node The node where the value may be placed
317     This function sets the internal value, but it also sets the value
318     in the preferences structure.  To put it in the right place, \c PREF_DIR
319     and \c pref_name() are used.
320 */
321 float
322 ParamFloat::set (float in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
324     _value = in;
325     if (_value > _max) _value = _max;
326     if (_value < _min) _value = _min;
328     gchar * prefname = this->pref_name();
329     prefs_set_double_attribute(PREF_DIR, prefname, _value);
330     g_free(prefname);
332     return _value;
335 /** \brief  A function to set the \c _value
336     \param  in   The value to set to
337     \param  doc  A document that should be used to set the value.
338     \param  node The node where the value may be placed
340     This function sets the internal value, but it also sets the value
341     in the preferences structure.  To put it in the right place, \c PREF_DIR
342     and \c pref_name() are used.
344     To copy the data into _value the old memory must be free'd first.
345     It is important to note that \c g_free handles \c NULL just fine.  Then
346     the passed in value is duplicated using \c g_strdup().
347 */
348 const gchar *
349 ParamString::set (const gchar * in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
351     if (in == NULL) return NULL; /* Can't have NULL string */
353     if (_value != NULL)
354         g_free(_value);
355     _value = g_strdup(in);
357     gchar * prefname = this->pref_name();
358     prefs_set_string_attribute(PREF_DIR, prefname, _value);
359     g_free(prefname);
361     return _value;
364 /** \brief  Wrapper to cast to the object and use it's function.  */
365 bool
366 Parameter::get_bool (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node)
368     ParamBool * boolpntr;
369     boolpntr = dynamic_cast<ParamBool *>(this);
370     if (boolpntr == NULL)
371         throw Extension::param_wrong_type();
372     return boolpntr->get(doc, node);
375 /** \brief  Wrapper to cast to the object and use it's function.  */
376 int
377 Parameter::get_int (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node)
379     ParamInt * intpntr;
380     intpntr = dynamic_cast<ParamInt *>(this);
381     if (intpntr == NULL)
382         throw Extension::param_wrong_type();
383     return intpntr->get(doc, node);
386 /** \brief  Wrapper to cast to the object and use it's function.  */
387 float
388 Parameter::get_float (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node)
390     ParamFloat * floatpntr;
391     floatpntr = dynamic_cast<ParamFloat *>(this);
392     if (floatpntr == NULL)
393         throw Extension::param_wrong_type();
394     return floatpntr->get(doc, node);
397 /** \brief  Wrapper to cast to the object and use it's function.  */
398 const gchar *
399 Parameter::get_string (const Inkscape::XML::Document * doc, const Inkscape::XML::Node * node)
401     ParamString * stringpntr;
402     stringpntr = dynamic_cast<ParamString *>(this);
403     if (stringpntr == NULL)
404         throw Extension::param_wrong_type();
405     return stringpntr->get(doc, node);
408 /** \brief  Wrapper to cast to the object and use it's function.  */
409 bool
410 Parameter::set_bool (bool in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
412     ParamBool * boolpntr;
413     boolpntr = dynamic_cast<ParamBool *>(this);
414     if (boolpntr == NULL)
415         throw Extension::param_wrong_type();
416     return boolpntr->set(in, doc, node);
419 /** \brief  Wrapper to cast to the object and use it's function.  */
420 int
421 Parameter::set_int (int in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
423     ParamInt * intpntr;
424     intpntr = dynamic_cast<ParamInt *>(this);
425     if (intpntr == NULL)
426         throw Extension::param_wrong_type();
427     return intpntr->set(in, doc, node);
430 /** \brief  Wrapper to cast to the object and use it's function.  */
431 float
432 Parameter::set_float (float in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
434     ParamFloat * floatpntr;
435     floatpntr = dynamic_cast<ParamFloat *>(this);
436     if (floatpntr == NULL)
437         throw Extension::param_wrong_type();
438     return floatpntr->set(in, doc, node);
441 /** \brief  Wrapper to cast to the object and use it's function.  */
442 const gchar *
443 Parameter::set_string (const gchar * in, Inkscape::XML::Document * doc, Inkscape::XML::Node * node)
445     ParamString * stringpntr;
446     stringpntr = dynamic_cast<ParamString *>(this);
447     if (stringpntr == NULL)
448         throw Extension::param_wrong_type();
449     return stringpntr->set(in, doc, node);
452 /** \brief  Initialize the object, to do that, copy the data. */
453 ParamString::ParamString (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
454     Parameter(name, guitext, desc, scope, ext), _value(NULL)
456     const char * defaultval = NULL;
457     if (sp_repr_children(xml) != NULL)
458         defaultval = sp_repr_children(xml)->content();
460     gchar * pref_name = this->pref_name();
461     const gchar * paramval = prefs_get_string_attribute(PREF_DIR, pref_name);
462     g_free(pref_name);
464     if (paramval != NULL)
465         defaultval = paramval;
466     if (defaultval != NULL)
467         _value = g_strdup(defaultval);
469     return;
472 /** \brief  Free the allocated data. */
473 ParamString::~ParamString(void)
475     g_free(_value);
478 /** \brief  Oop, now that we need a parameter, we need it's name.  */
479 Parameter::Parameter (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext) :
480     extension(ext), _name(NULL), _desc(NULL), _scope(scope), _text(NULL)
482     if (name != NULL)
483         _name = g_strdup(name);
484     if (desc != NULL) {
485         _desc = g_strdup(desc);
486         // printf("Adding description: '%s' on '%s'\n", _desc, _name);
487     }
490     if (guitext != NULL)
491         _text = g_strdup(guitext);
492     else
493         _text = g_strdup(name);
495     return;
498 /** \brief  Just free the allocated name. */
499 Parameter::~Parameter (void)
501     g_free(_name);
502     g_free(_text);
505 /** \brief  Build the name to write the parameter from the extension's
506             ID and the name of this parameter. */
507 gchar *
508 Parameter::pref_name (void)
510     return g_strdup_printf("%s.%s", extension->get_id(), _name);
513 /** \brief  Basically, if there is no widget pass a NULL. */
514 Gtk::Widget *
515 Parameter::get_widget (void)
517     return NULL;
520 /** \brief  If I'm not sure which it is, just don't return a value. */
521 Glib::ustring *
522 Parameter::string (void)
524     Glib::ustring * mystring = new Glib::ustring("");
525     return mystring;
528 /** \brief  A class to make an adjustment that uses Extension params */
529 class ParamFloatAdjustment : public Gtk::Adjustment {
530     /** The parameter to adjust */
531     ParamFloat * _pref;
532 public:
533     /** \brief  Make the adjustment using an extension and the string
534                 describing the parameter. */
535     ParamFloatAdjustment (ParamFloat * param) :
536             Gtk::Adjustment(0.0, param->min(), param->max(), 0.1), _pref(param) {
537         this->set_value(_pref->get(NULL, NULL) /* \todo fix */);
538         this->signal_value_changed().connect(sigc::mem_fun(this, &ParamFloatAdjustment::val_changed));
539         return;
540     };
542     void val_changed (void);
543 }; /* class ParamFloatAdjustment */
545 /** \brief  A function to respond to the value_changed signal from the
546             adjustment.
548     This function just grabs the value from the adjustment and writes
549     it to the parameter.  Very simple, but yet beautiful.
550 */
551 void
552 ParamFloatAdjustment::val_changed (void)
554     // std::cout << "Value Changed to: " << this->get_value() << std::endl;
555     _pref->set(this->get_value(), NULL /* \todo fix */, NULL);
556     return;
559 /** \brief  A class to make an adjustment that uses Extension params */
560 class ParamIntAdjustment : public Gtk::Adjustment {
561     /** The parameter to adjust */
562     ParamInt * _pref;
563 public:
564     /** \brief  Make the adjustment using an extension and the string
565                 describing the parameter. */
566     ParamIntAdjustment (ParamInt * param) :
567             Gtk::Adjustment(0.0, param->min(), param->max(), 1.0), _pref(param) {
568         this->set_value(_pref->get(NULL, NULL) /* \todo fix */);
569         this->signal_value_changed().connect(sigc::mem_fun(this, &ParamIntAdjustment::val_changed));
570         return;
571     };
573     void val_changed (void);
574 }; /* class ParamIntAdjustment */
576 /** \brief  A function to respond to the value_changed signal from the
577             adjustment.
579     This function just grabs the value from the adjustment and writes
580     it to the parameter.  Very simple, but yet beautiful.
581 */
582 void
583 ParamIntAdjustment::val_changed (void)
585     // std::cout << "Value Changed to: " << this->get_value() << std::endl;
586     _pref->set((int)this->get_value(), NULL /* \todo fix */, NULL);
587     return;
590 /**
591     \brief  Creates a Float Adjustment for a float parameter
593     Builds a hbox with a label and a float adjustment in it.
594 */
595 Gtk::Widget *
596 ParamFloat::get_widget (void)
598     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox());
600     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
601     label->show();
602     hbox->pack_start(*label, true, true);
604     ParamFloatAdjustment * fadjust = new ParamFloatAdjustment(this);
605     Gtk::SpinButton * spin = Gtk::manage(new Gtk::SpinButton(*fadjust, 0.1, 1));
606     spin->show();
607     hbox->pack_start(*spin, false, false);
609     hbox->show();
611     return dynamic_cast<Gtk::Widget *>(hbox);
614 /**
615     \brief  Creates a Int Adjustment for a int parameter
617     Builds a hbox with a label and a int adjustment in it.
618 */
619 Gtk::Widget *
620 ParamInt::get_widget (void)
622     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox());
624     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
625     label->show();
626     hbox->pack_start(*label, true, true);
628     ParamIntAdjustment * fadjust = new ParamIntAdjustment(this);
629     Gtk::SpinButton * spin = Gtk::manage(new Gtk::SpinButton(*fadjust, 1.0, 0));
630     spin->show();
631     hbox->pack_start(*spin, false, false);
633     hbox->show();
635     return dynamic_cast<Gtk::Widget *>(hbox);
638 /** \brief  A check button which is Param aware.  It works with the
639             parameter to change it's value as the check button changes
640             value. */
641 class ParamBoolCheckButton : public Gtk::CheckButton {
642 private:
643     /** \brief  Param to change */
644     ParamBool * _pref;
645 public:
646     /** \brief  Initialize the check button
647         \param  param  Which parameter to adjust on changing the check button
649         This function sets the value of the checkbox to be that of the
650         parameter, and then sets up a callback to \c on_toggle.
651     */
652     ParamBoolCheckButton (ParamBool * param) :
653             Gtk::CheckButton(), _pref(param) {
654         this->set_active(_pref->get(NULL, NULL) /**\todo fix */);
655         this->signal_toggled().connect(sigc::mem_fun(this, &ParamBoolCheckButton::on_toggle));
656         return;
657     }
658     void on_toggle (void);
659 };
661 /**
662     \brief  A function to respond to the check box changing
664     Adjusts the value of the preference to match that in the check box.
665 */
666 void
667 ParamBoolCheckButton::on_toggle (void)
669     _pref->set(this->get_active(), NULL /**\todo fix this */, NULL);
670     return;
673 /**
674     \brief  Creates a bool check button for a bool parameter
676     Builds a hbox with a label and a check button in it.
677 */
678 Gtk::Widget *
679 ParamBool::get_widget (void)
681     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox());
683     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
684     label->show();
685     hbox->pack_start(*label, true, true);
687     ParamBoolCheckButton * checkbox = new ParamBoolCheckButton(this);
688     checkbox->show();
689     hbox->pack_start(*checkbox, false, false);
691     hbox->show();
693     return dynamic_cast<Gtk::Widget *>(hbox);
696 /** \brief  A special category of Gtk::Entry to handle string parameteres */
697 class ParamStringEntry : public Gtk::Entry {
698 private:
699     ParamString * _pref;
700 public:
701     /** \brief  Build a string preference for the given parameter
702         \param  pref  Where to get the string from, and where to put it
703                       when it changes.
704     */
705     ParamStringEntry (ParamString * pref) :
706         Gtk::Entry(), _pref(pref) {
707         if (_pref->get(NULL, NULL) != NULL)
708             this->set_text(Glib::ustring(_pref->get(NULL, NULL)));
709         this->signal_changed().connect(sigc::mem_fun(this, &ParamStringEntry::changed_text));
710     };
711     void changed_text (void);
712 };
714 /** \brief  Respond to the text box changing
716     This function responds to the box changing by grabbing the value
717     from the text box and putting it in the parameter.
718 */
719 void
720 ParamStringEntry::changed_text (void)
722     Glib::ustring data = this->get_text();
723     _pref->set(data.c_str(), NULL, NULL);
724     return;
727 /**
728     \brief  Creates a text box for the string parameter
730     Builds a hbox with a label and a text box in it.
731 */
732 Gtk::Widget *
733 ParamString::get_widget (void)
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     ParamStringEntry * textbox = new ParamStringEntry(this);
742     textbox->show();
743     hbox->pack_start(*textbox, false, false);
745     hbox->show();
747     return dynamic_cast<Gtk::Widget *>(hbox);
750 /** \brief  Return 'true' or 'false' */
751 Glib::ustring *
752 ParamBool::string (void)
754     Glib::ustring * mystring;
756     if (_value)
757         mystring = new Glib::ustring("true");
758     else
759         mystring = new Glib::ustring("false");
761     return mystring;
764 /** \brief  Return the value as a string */
765 Glib::ustring *
766 ParamInt::string (void)
768     char startstring[32];
769     sprintf(startstring, "%d", _value);
770     Glib::ustring * mystring = new Glib::ustring(startstring);
771     return mystring;
774 /** \brief  Return the value as a string */
775 Glib::ustring *
776 ParamFloat::string (void)
778     char startstring[G_ASCII_DTOSTR_BUF_SIZE];
779     g_ascii_dtostr(startstring, G_ASCII_DTOSTR_BUF_SIZE, _value);
780     Glib::ustring * mystring = new Glib::ustring(startstring);
781     return mystring;
784 /** \brief  Return the value as a string */
785 Glib::ustring *
786 ParamString::string (void)
788     Glib::ustring * mystring = new Glib::ustring("");
789     *mystring += "\"";
790     *mystring += _value;
791     *mystring += "\"";
792     return mystring;
796 }  /* namespace Extension */
797 }  /* namespace Inkscape */
799 /*
800   Local Variables:
801   mode:c++
802   c-file-style:"stroustrup"
803   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
804   indent-tabs-mode:nil
805   fill-column:99
806   End:
807 */
808 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :