Code

a034022d9f8a5b2413626569ffa86d35ad516010
[inkscape.git] / src / extension / parameter.cpp
1 /** \file
2  * Parameters for extensions.
3  */
5 /*
6  * Authors:
7  *   Ted Gould <ted@gould.cx>
8  *
9  * Copyright (C) 2005-2006 Authors
10  *
11  * Released under GNU GPL, read the file 'COPYING' for more information
12  */
14 #ifdef HAVE_CONFIG_H
15 # include "config.h"
16 #endif
19 #include <gtkmm/adjustment.h>
20 #include <gtkmm/box.h>
21 #include <gtkmm/spinbutton.h>
23 #include <glibmm/i18n.h>
25 #include <xml/node.h>
27 #include "extension.h"
28 #include "prefs-utils.h"
29 #include "document-private.h"
30 #include "sp-object.h"
32 #include "parameter.h"
34 /** \brief  The root directory in the preferences database for extension
35             related parameters. */
36 #define PREF_DIR "extensions"
38 namespace Inkscape {
39 namespace Extension {
41 /** \brief  A description parameter */
42 class ParamDescription : public Parameter {
43 private:
44     /** \brief  Internal value. */
45     gchar * _value;
46 public:
47     ParamDescription(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
48     Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);
49 };
51 /** \brief  A boolean parameter */
52 class ParamBool : public Parameter {
53 private:
54     /** \brief  Internal value. */
55     bool _value;
56 public:
57     ParamBool(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
58     /** \brief  Returns \c _value */
59     bool get (const SPDocument * doc, const Inkscape::XML::Node * node) { return _value; }
60     bool set (bool in, SPDocument * doc, Inkscape::XML::Node * node);
61     Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);
62     Glib::ustring * string (void);
63 };
65 /** \brief  Use the superclass' allocator and set the \c _value */
66 ParamBool::ParamBool (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
67         Parameter(name, guitext, desc, scope, ext), _value(false)
68 {
69     const char * defaultval = NULL;
70     if (sp_repr_children(xml) != NULL)
71         defaultval = sp_repr_children(xml)->content();
73     if (defaultval != NULL && (!strcmp(defaultval, "TRUE") || !strcmp(defaultval, "true") || !strcmp(defaultval, "1"))) {
74         _value = true;
75     } else {
76         _value = false;
77     }
79     gchar * pref_name = this->pref_name();
80     _value = (bool)prefs_get_int_attribute(PREF_DIR, pref_name, _value);
81     g_free(pref_name);
83     return;
84 }
86 class ParamInt : public Parameter {
87 private:
88     /** \brief  Internal value. */
89     int _value;
90     int _min;
91     int _max;
92 public:
93     ParamInt (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
94     /** \brief  Returns \c _value */
95     int get (const SPDocument * doc, const Inkscape::XML::Node * node) { return _value; }
96     int set (int in, SPDocument * doc, Inkscape::XML::Node * node);
97     int max (void) { return _max; }
98     int min (void) { return _min; }
99     Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);
100     Glib::ustring * string (void);
101 };
103 /** \brief  Use the superclass' allocator and set the \c _value */
104 ParamInt::ParamInt (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
105         Parameter(name, guitext, desc, scope, ext), _value(0), _min(0), _max(10)
107     const char * defaultval = NULL;
108     if (sp_repr_children(xml) != NULL)
109         defaultval = sp_repr_children(xml)->content();
110     if (defaultval != NULL) {
111         _value = atoi(defaultval);
112     }
114     const char * maxval = xml->attribute("max");
115     if (maxval != NULL)
116         _max = atoi(maxval);
118     const char * minval = xml->attribute("min");
119     if (minval != NULL)
120         _min = atoi(minval);
122     /* We're handling this by just killing both values */
123     if (_max < _min) {
124         _max = 10;
125         _min = 0;
126     }
128     gchar * pref_name = this->pref_name();
129     _value = prefs_get_int_attribute(PREF_DIR, pref_name, _value);
130     g_free(pref_name);
132     // std::cout << "New Int::  value: " << _value << "  max: " << _max << "  min: " << _min << std::endl;
134     if (_value > _max) _value = _max;
135     if (_value < _min) _value = _min;
137     return;
140 class ParamFloat : public Parameter {
141 private:
142     /** \brief  Internal value. */
143     float _value;
144     float _min;
145     float _max;
146 public:
147     ParamFloat (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
148     /** \brief  Returns \c _value */
149     float get (const SPDocument * doc, const Inkscape::XML::Node * node) { return _value; }
150     float set (float in, SPDocument * doc, Inkscape::XML::Node * node);
151     float max (void) { return _max; }
152     float min (void) { return _min; }
153     Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);
154     Glib::ustring * string (void);
155 };
157 /** \brief  Use the superclass' allocator and set the \c _value */
158 ParamFloat::ParamFloat (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
159         Parameter(name, guitext, desc, scope, ext), _value(0.0), _min(0.0), _max(10.0)
161     const char * defaultval = NULL;
162     if (sp_repr_children(xml) != NULL)
163         defaultval = sp_repr_children(xml)->content();
164     if (defaultval != NULL) {
165         _value = atof(defaultval);
166     }
168     const char * maxval = xml->attribute("max");
169     if (maxval != NULL)
170         _max = atof(maxval);
172     const char * minval = xml->attribute("min");
173     if (minval != NULL)
174         _min = atof(minval);
176     /* We're handling this by just killing both values */
177     if (_max < _min) {
178         _max = 10.0;
179         _min = 0.0;
180     }
182     gchar * pref_name = this->pref_name();
183     _value = prefs_get_double_attribute(PREF_DIR, pref_name, _value);
184     g_free(pref_name);
186     // std::cout << "New Float::  value: " << _value << "  max: " << _max << "  min: " << _min << std::endl;
188     if (_value > _max) _value = _max;
189     if (_value < _min) _value = _min;
191     return;
194 class ParamString : public Parameter {
195 private:
196     /** \brief  Internal value.  This should point to a string that has
197                 been allocated in memory.  And should be free'd. */
198     gchar * _value;
199 public:
200     ParamString(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
201     ~ParamString(void);
202     /** \brief  Returns \c _value, with a \i const to protect it. */
203     const gchar * get (const SPDocument * doc, const Inkscape::XML::Node * node) { return _value; }
204     const gchar * set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node);
205     Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);
206     Glib::ustring * string (void);
207 };
209 class ParamEnum : public Parameter {
210 private:
211     class Choice {
212     public:
213         gchar * _gui_name;
214         gchar * _value;
215         Choice(gchar * gui_name, gchar * value) : _gui_name(NULL), _value(NULL) {
216             if (gui_name != NULL)
217                 _gui_name = g_strdup(_(gui_name));
218             if (value != NULL)
219                 _value = g_strdup(value);
220             return;
221         };
222         ~Choice (void) {
223             g_free(_gui_name);
224             g_free(_value);
225         };
226     }; /* class Choice */
227     /** \brief  Internal value.  This should point to a string that has
228                 been allocated in memory.  And should be free'd. */
229     Choice * _current_choice;
230     typedef std::list<Choice *> choice_list_t;
231     choice_list_t _choice_list;
232 public:
233     ParamEnum(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);
234     ~ParamEnum(void);
235     /** \brief  Returns \c _value, with a \i const to protect it. */
236     const gchar * get (const SPDocument * doc, const Inkscape::XML::Node * node) { return _current_choice != NULL ? _current_choice->_value : NULL; }
237     const gchar * set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node);
238     Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);
239     Glib::ustring * string (void);
240 }; /* class ParamEnum */
242 /**
243     \return None
244     \brief  This function creates a parameter that can be used later.  This
245             is typically done in the creation of the extension and defined
246             in the XML file describing the extension (it's private so people
247             have to use the system) :)
248     \param  in_repr  The XML describing the parameter
250     This function first grabs all of the data out of the Repr and puts
251     it into local variables.  Actually, these are just pointers, and the
252     data is not duplicated so we need to be careful with it.  If there
253     isn't a name or a type in the XML, then no parameter is created as
254     the function just returns.
256     From this point on, we're pretty committed as we've allocated an
257     object and we're starting to fill it.  The name is set first, and
258     is created with a strdup to actually allocate memory for it.  Then
259     there is a case statement (roughly because strcmp requires 'ifs')
260     based on what type of parameter this is.  Depending which type it
261     is, the value is interpreted differently, but they are relatively
262     straight forward.  In all cases the value is set to the default
263     value from the XML and the type is set to the interpreted type.
264 */
265 Parameter *
266 Parameter::make (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext)
268     const char * name;
269     const char * type;
270     const char * guitext;
271     const char * desc;
272     const char * scope_str;
273     Parameter::_scope_t scope = Parameter::SCOPE_USER;
275     name = in_repr->attribute("name");
276     type = in_repr->attribute("type");
277     guitext = in_repr->attribute("gui-text");
278     if (guitext == NULL)
279         guitext = in_repr->attribute("_gui-text");
280     desc = in_repr->attribute("gui-description");
281     if (desc == NULL)
282         desc = in_repr->attribute("_gui-description");
283     scope_str = in_repr->attribute("scope");
285     /* In this case we just don't have enough information */
286     if (name == NULL || type == NULL) {
287         return NULL;
288     }
290     if (scope_str != NULL) {
291         if (!strcmp(scope_str, "user")) {
292             scope = Parameter::SCOPE_USER;
293         } else if (!strcmp(scope_str, "document")) {
294             scope = Parameter::SCOPE_DOCUMENT;
295         } else if (!strcmp(scope_str, "node")) {
296             scope = Parameter::SCOPE_NODE;
297         }
298     }
300     Parameter * param = NULL;
301     if (!strcmp(type, "boolean")) {
302         param = new ParamBool(name, guitext, desc, scope, in_ext, in_repr);
303     } else if (!strcmp(type, "int")) {
304         param = new ParamInt(name, guitext, desc, scope, in_ext, in_repr);
305     } else if (!strcmp(type, "float")) {
306         param = new ParamFloat(name, guitext, desc, scope, in_ext, in_repr);
307     } else if (!strcmp(type, "string")) {
308         param = new ParamString(name, guitext, desc, scope, in_ext, in_repr);
309     } else if (!strcmp(type, "description")) {
310         param = new ParamDescription(name, guitext, desc, scope, in_ext, in_repr);
311     } else if (!strcmp(type, "enum")) {
312         param = new ParamEnum(name, guitext, desc, scope, in_ext, in_repr);
313     }
315     /* Note: param could equal NULL */
316     return param;
319 /** \brief  A function to set the \c _value
320     \param  in   The value to set to
321     \param  doc  A document that should be used to set the value.
322     \param  node The node where the value may be placed
324     This function sets the internal value, but it also sets the value
325     in the preferences structure.  To put it in the right place, \c PREF_DIR
326     and \c pref_name() are used.
327 */
328 bool
329 ParamBool::set (bool in, SPDocument * doc, Inkscape::XML::Node * node)
331     _value = in;
333     gchar * prefname = this->pref_name();
334     prefs_set_int_attribute(PREF_DIR, prefname, _value == true ? 1 : 0);
335     g_free(prefname);
337     return _value;
340 /** \brief  A function to set the \c _value
341     \param  in   The value to set to
342     \param  doc  A document that should be used to set the value.
343     \param  node The node where the value may be placed
345     This function sets the internal value, but it also sets the value
346     in the preferences structure.  To put it in the right place, \c PREF_DIR
347     and \c pref_name() are used.
348 */
349 int
350 ParamInt::set (int in, SPDocument * doc, Inkscape::XML::Node * node)
352     _value = in;
353     if (_value > _max) _value = _max;
354     if (_value < _min) _value = _min;
356     gchar * prefname = this->pref_name();
357     prefs_set_int_attribute(PREF_DIR, prefname, _value);
358     g_free(prefname);
360     return _value;
363 /** \brief  A function to set the \c _value
364     \param  in   The value to set to
365     \param  doc  A document that should be used to set the value.
366     \param  node The node where the value may be placed
368     This function sets the internal value, but it also sets the value
369     in the preferences structure.  To put it in the right place, \c PREF_DIR
370     and \c pref_name() are used.
371 */
372 float
373 ParamFloat::set (float in, SPDocument * doc, Inkscape::XML::Node * node)
375     _value = in;
376     if (_value > _max) _value = _max;
377     if (_value < _min) _value = _min;
379     gchar * prefname = this->pref_name();
380     prefs_set_double_attribute(PREF_DIR, prefname, _value);
381     g_free(prefname);
383     return _value;
386 /** \brief  A function to set the \c _value
387     \param  in   The value to set to
388     \param  doc  A document that should be used to set the value.
389     \param  node The node where the value may be placed
391     This function sets the internal value, but it also sets the value
392     in the preferences structure.  To put it in the right place, \c PREF_DIR
393     and \c pref_name() are used.
395     To copy the data into _value the old memory must be free'd first.
396     It is important to note that \c g_free handles \c NULL just fine.  Then
397     the passed in value is duplicated using \c g_strdup().
398 */
399 const gchar *
400 ParamString::set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node)
402     if (in == NULL) return NULL; /* Can't have NULL string */
404     if (_value != NULL)
405         g_free(_value);
406     _value = g_strdup(in);
408     gchar * prefname = this->pref_name();
409     prefs_set_string_attribute(PREF_DIR, prefname, _value);
410     g_free(prefname);
412     return _value;
415 /** \brief  Wrapper to cast to the object and use it's function.  */
416 bool
417 Parameter::get_bool (const SPDocument * doc, const Inkscape::XML::Node * node)
419     ParamBool * boolpntr;
420     boolpntr = dynamic_cast<ParamBool *>(this);
421     if (boolpntr == NULL)
422         throw Extension::param_wrong_type();
423     return boolpntr->get(doc, node);
426 /** \brief  Wrapper to cast to the object and use it's function.  */
427 int
428 Parameter::get_int (const SPDocument * doc, const Inkscape::XML::Node * node)
430     ParamInt * intpntr;
431     intpntr = dynamic_cast<ParamInt *>(this);
432     if (intpntr == NULL)
433         throw Extension::param_wrong_type();
434     return intpntr->get(doc, node);
437 /** \brief  Wrapper to cast to the object and use it's function.  */
438 float
439 Parameter::get_float (const SPDocument * doc, const Inkscape::XML::Node * node)
441     ParamFloat * floatpntr;
442     floatpntr = dynamic_cast<ParamFloat *>(this);
443     if (floatpntr == NULL)
444         throw Extension::param_wrong_type();
445     return floatpntr->get(doc, node);
448 /** \brief  Wrapper to cast to the object and use it's function.  */
449 const gchar *
450 Parameter::get_string (const SPDocument * doc, const Inkscape::XML::Node * node)
452     ParamString * stringpntr;
453     stringpntr = dynamic_cast<ParamString *>(this);
454     if (stringpntr == NULL)
455         throw Extension::param_wrong_type();
456     return stringpntr->get(doc, node);
459 /** \brief  Wrapper to cast to the object and use it's function.  */
460 bool
461 Parameter::set_bool (bool in, SPDocument * doc, Inkscape::XML::Node * node)
463     ParamBool * boolpntr;
464     boolpntr = dynamic_cast<ParamBool *>(this);
465     if (boolpntr == NULL)
466         throw Extension::param_wrong_type();
467     return boolpntr->set(in, doc, node);
470 /** \brief  Wrapper to cast to the object and use it's function.  */
471 int
472 Parameter::set_int (int in, SPDocument * doc, Inkscape::XML::Node * node)
474     ParamInt * intpntr;
475     intpntr = dynamic_cast<ParamInt *>(this);
476     if (intpntr == NULL)
477         throw Extension::param_wrong_type();
478     return intpntr->set(in, doc, node);
481 /** \brief  Wrapper to cast to the object and use it's function.  */
482 float
483 Parameter::set_float (float in, SPDocument * doc, Inkscape::XML::Node * node)
485     ParamFloat * floatpntr;
486     floatpntr = dynamic_cast<ParamFloat *>(this);
487     if (floatpntr == NULL)
488         throw Extension::param_wrong_type();
489     return floatpntr->set(in, doc, node);
492 /** \brief  Wrapper to cast to the object and use it's function.  */
493 const gchar *
494 Parameter::set_string (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node)
496     ParamString * stringpntr;
497     stringpntr = dynamic_cast<ParamString *>(this);
498     if (stringpntr == NULL)
499         throw Extension::param_wrong_type();
500     return stringpntr->set(in, doc, node);
503 /** \brief  Initialize the object, to do that, copy the data. */
504 ParamString::ParamString (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
505     Parameter(name, guitext, desc, scope, ext), _value(NULL)
507     const char * defaultval = NULL;
508     if (sp_repr_children(xml) != NULL)
509         defaultval = sp_repr_children(xml)->content();
511     gchar * pref_name = this->pref_name();
512     const gchar * paramval = prefs_get_string_attribute(PREF_DIR, pref_name);
513     g_free(pref_name);
515     if (paramval != NULL)
516         defaultval = paramval;
517     if (defaultval != NULL)
518         _value = g_strdup(defaultval);
520     return;
523 /** \brief  Free the allocated data. */
524 ParamString::~ParamString(void)
526     g_free(_value);
529 /** \brief  Oop, now that we need a parameter, we need it's name.  */
530 Parameter::Parameter (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext) :
531     extension(ext), _name(NULL), _desc(NULL), _scope(scope), _text(NULL)
533     if (name != NULL)
534         _name = g_strdup(name);
535     if (desc != NULL) {
536         _desc = g_strdup(desc);
537         // printf("Adding description: '%s' on '%s'\n", _desc, _name);
538     }
541     if (guitext != NULL)
542         _text = g_strdup(guitext);
543     else
544         _text = g_strdup(name);
546     return;
549 /** \brief  Just free the allocated name. */
550 Parameter::~Parameter (void)
552     g_free(_name);
553     g_free(_text);
556 /** \brief  Build the name to write the parameter from the extension's
557             ID and the name of this parameter. */
558 gchar *
559 Parameter::pref_name (void)
561     return g_strdup_printf("%s.%s", extension->get_id(), _name);
564 Inkscape::XML::Node *
565 Parameter::find_child (Inkscape::XML::Node * adult)
567     return sp_repr_lookup_child(adult, "name", _name);
570 Inkscape::XML::Node *
571 Parameter::new_child (Inkscape::XML::Node * parent)
573     Inkscape::XML::Node * retval;
574     retval = sp_repr_new("inkscape:extension-param");
575     retval->setAttribute("name", _name);
577     parent->appendChild(retval);
578     return retval;
581 Inkscape::XML::Node *
582 Parameter::document_param_node (SPDocument * doc)
584     Inkscape::XML::Node * defs = SP_OBJECT_REPR(SP_DOCUMENT_DEFS(doc));
585     Inkscape::XML::Node * params = NULL;
587     GQuark const name_quark = g_quark_from_string("inkscape:extension-params");
589     for (Inkscape::XML::Node * child = defs->firstChild();
590             child != NULL;
591             child = child->next()) {
592         if ((GQuark)child->code() == name_quark &&
593                 !strcmp(child->attribute("extension"), extension->get_id())) {
594             params = child;
595             break;
596         }
597     }
599     if (params == NULL) {
600         params = sp_repr_new("inkscape:extension-param");
601         params->setAttribute("extension", extension->get_id());
602         defs->appendChild(params);
603     }
605     return params;
608 /** \brief  Basically, if there is no widget pass a NULL. */
609 Gtk::Widget *
610 Parameter::get_widget (SPDocument * doc, Inkscape::XML::Node * node)
612     return NULL;
615 /** \brief  If I'm not sure which it is, just don't return a value. */
616 Glib::ustring *
617 Parameter::string (void)
619     Glib::ustring * mystring = new Glib::ustring("");
620     return mystring;
623 /** \brief  A class to make an adjustment that uses Extension params */
624 class ParamFloatAdjustment : public Gtk::Adjustment {
625     /** The parameter to adjust */
626     ParamFloat * _pref;
627     SPDocument * _doc;
628     Inkscape::XML::Node * _node;
629 public:
630     /** \brief  Make the adjustment using an extension and the string
631                 describing the parameter. */
632     ParamFloatAdjustment (ParamFloat * param, SPDocument * doc, Inkscape::XML::Node * node) :
633             Gtk::Adjustment(0.0, param->min(), param->max(), 0.1), _pref(param), _doc(doc), _node(node) {
634         this->set_value(_pref->get(NULL, NULL) /* \todo fix */);
635         this->signal_value_changed().connect(sigc::mem_fun(this, &ParamFloatAdjustment::val_changed));
636         return;
637     };
639     void val_changed (void);
640 }; /* class ParamFloatAdjustment */
642 /** \brief  A function to respond to the value_changed signal from the
643             adjustment.
645     This function just grabs the value from the adjustment and writes
646     it to the parameter.  Very simple, but yet beautiful.
647 */
648 void
649 ParamFloatAdjustment::val_changed (void)
651     // std::cout << "Value Changed to: " << this->get_value() << std::endl;
652     _pref->set(this->get_value(), _doc, _node);
653     return;
656 /** \brief  A class to make an adjustment that uses Extension params */
657 class ParamIntAdjustment : public Gtk::Adjustment {
658     /** The parameter to adjust */
659     ParamInt * _pref;
660     SPDocument * _doc;
661     Inkscape::XML::Node * _node;
662 public:
663     /** \brief  Make the adjustment using an extension and the string
664                 describing the parameter. */
665     ParamIntAdjustment (ParamInt * param, SPDocument * doc, Inkscape::XML::Node * node) :
666             Gtk::Adjustment(0.0, param->min(), param->max(), 1.0), _pref(param), _doc(doc), _node(node) {
667         this->set_value(_pref->get(NULL, NULL) /* \todo fix */);
668         this->signal_value_changed().connect(sigc::mem_fun(this, &ParamIntAdjustment::val_changed));
669         return;
670     };
672     void val_changed (void);
673 }; /* class ParamIntAdjustment */
675 /** \brief  A function to respond to the value_changed signal from the
676             adjustment.
678     This function just grabs the value from the adjustment and writes
679     it to the parameter.  Very simple, but yet beautiful.
680 */
681 void
682 ParamIntAdjustment::val_changed (void)
684     // std::cout << "Value Changed to: " << this->get_value() << std::endl;
685     _pref->set((int)this->get_value(), _doc, _node);
686     return;
689 /**
690     \brief  Creates a Float Adjustment for a float parameter
692     Builds a hbox with a label and a float adjustment in it.
693 */
694 Gtk::Widget *
695 ParamFloat::get_widget (SPDocument * doc, Inkscape::XML::Node * node)
697     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
699     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
700     label->show();
701     hbox->pack_start(*label, true, true);
703     ParamFloatAdjustment * fadjust = Gtk::manage(new ParamFloatAdjustment(this, doc, node));
704     Gtk::SpinButton * spin = Gtk::manage(new Gtk::SpinButton(*fadjust, 0.1, 1));
705     spin->show();
706     hbox->pack_start(*spin, false, false);
708     hbox->show();
710     return dynamic_cast<Gtk::Widget *>(hbox);
713 /**
714     \brief  Creates a Int Adjustment for a int parameter
716     Builds a hbox with a label and a int adjustment in it.
717 */
718 Gtk::Widget *
719 ParamInt::get_widget (SPDocument * doc, Inkscape::XML::Node * node)
721     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
723     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
724     label->show();
725     hbox->pack_start(*label, true, true);
727     ParamIntAdjustment * fadjust = Gtk::manage(new ParamIntAdjustment(this, doc, node));
728     Gtk::SpinButton * spin = Gtk::manage(new Gtk::SpinButton(*fadjust, 1.0, 0));
729     spin->show();
730     hbox->pack_start(*spin, false, false);
732     hbox->show();
734     return dynamic_cast<Gtk::Widget *>(hbox);
737 /** \brief  A check button which is Param aware.  It works with the
738             parameter to change it's value as the check button changes
739             value. */
740 class ParamBoolCheckButton : public Gtk::CheckButton {
741 private:
742     /** \brief  Param to change */
743     ParamBool * _pref;
744     SPDocument * _doc;
745     Inkscape::XML::Node * _node;
746 public:
747     /** \brief  Initialize the check button
748         \param  param  Which parameter to adjust on changing the check button
750         This function sets the value of the checkbox to be that of the
751         parameter, and then sets up a callback to \c on_toggle.
752     */
753     ParamBoolCheckButton (ParamBool * param, SPDocument * doc, Inkscape::XML::Node * node) :
754             Gtk::CheckButton(), _pref(param), _doc(doc), _node(node) {
755         this->set_active(_pref->get(NULL, NULL) /**\todo fix */);
756         this->signal_toggled().connect(sigc::mem_fun(this, &ParamBoolCheckButton::on_toggle));
757         return;
758     }
759     void on_toggle (void);
760 };
762 /**
763     \brief  A function to respond to the check box changing
765     Adjusts the value of the preference to match that in the check box.
766 */
767 void
768 ParamBoolCheckButton::on_toggle (void)
770     _pref->set(this->get_active(), NULL /**\todo fix this */, NULL);
771     return;
774 /**
775     \brief  Creates a bool check button for a bool parameter
777     Builds a hbox with a label and a check button in it.
778 */
779 Gtk::Widget *
780 ParamBool::get_widget (SPDocument * doc, Inkscape::XML::Node * node)
782     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
784     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
785     label->show();
786     hbox->pack_start(*label, true, true);
788     ParamBoolCheckButton * checkbox = new ParamBoolCheckButton(this, doc, node);
789     checkbox->show();
790     hbox->pack_start(*checkbox, false, false);
792     hbox->show();
794     return dynamic_cast<Gtk::Widget *>(hbox);
797 /** \brief  A special category of Gtk::Entry to handle string parameteres */
798 class ParamStringEntry : public Gtk::Entry {
799 private:
800     ParamString * _pref;
801     SPDocument * _doc;
802     Inkscape::XML::Node * _node;
803 public:
804     /** \brief  Build a string preference for the given parameter
805         \param  pref  Where to get the string from, and where to put it
806                       when it changes.
807     */
808     ParamStringEntry (ParamString * pref, SPDocument * doc, Inkscape::XML::Node * node) :
809         Gtk::Entry(), _pref(pref), _doc(doc), _node(node) {
810         if (_pref->get(NULL, NULL) != NULL)
811             this->set_text(Glib::ustring(_pref->get(NULL, NULL)));
812         this->signal_changed().connect(sigc::mem_fun(this, &ParamStringEntry::changed_text));
813     };
814     void changed_text (void);
815 };
817 /** \brief  Respond to the text box changing
819     This function responds to the box changing by grabbing the value
820     from the text box and putting it in the parameter.
821 */
822 void
823 ParamStringEntry::changed_text (void)
825     Glib::ustring data = this->get_text();
826     _pref->set(data.c_str(), _doc, _node);
827     return;
830 /**
831     \brief  Creates a text box for the string parameter
833     Builds a hbox with a label and a text box in it.
834 */
835 Gtk::Widget *
836 ParamString::get_widget (SPDocument * doc, Inkscape::XML::Node * node)
838     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
840     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT));
841     label->show();
842     hbox->pack_start(*label, false, false);
844     ParamStringEntry * textbox = new ParamStringEntry(this, doc, node);
845     textbox->show();
846     hbox->pack_start(*textbox, true, true);
848     hbox->show();
850     return dynamic_cast<Gtk::Widget *>(hbox);
853 /** \brief  Return 'true' or 'false' */
854 Glib::ustring *
855 ParamBool::string (void)
857     Glib::ustring * mystring;
859     if (_value)
860         mystring = new Glib::ustring("true");
861     else
862         mystring = new Glib::ustring("false");
864     return mystring;
867 /** \brief  Return the value as a string */
868 Glib::ustring *
869 ParamInt::string (void)
871     char startstring[32];
872     sprintf(startstring, "%d", _value);
873     Glib::ustring * mystring = new Glib::ustring(startstring);
874     return mystring;
877 /** \brief  Return the value as a string */
878 Glib::ustring *
879 ParamFloat::string (void)
881     char startstring[G_ASCII_DTOSTR_BUF_SIZE];
882     g_ascii_dtostr(startstring, G_ASCII_DTOSTR_BUF_SIZE, _value);
883     Glib::ustring * mystring = new Glib::ustring(startstring);
884     return mystring;
887 /** \brief  Return the value as a string */
888 Glib::ustring *
889 ParamString::string (void)
891     Glib::ustring * mystring = new Glib::ustring("");
892     *mystring += "\"";
893     *mystring += _value;
894     *mystring += "\"";
895     return mystring;
898 /** \brief  Create a label for the description */
899 Gtk::Widget *
900 ParamDescription::get_widget (SPDocument * doc, Inkscape::XML::Node * node)
902     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_value)));
903     label->set_line_wrap();
904     label->show();
906     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
907     hbox->pack_start(*label, true, true, 5);
908     hbox->show();
910     return hbox;
913 /** \brief  Initialize the object, to do that, copy the data. */
914 ParamDescription::ParamDescription (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
915     Parameter(name, guitext, desc, scope, ext), _value(NULL)
917     // printf("Building Description\n");
918     const char * defaultval = NULL;
919     if (sp_repr_children(xml) != NULL)
920         defaultval = sp_repr_children(xml)->content();
922     if (defaultval != NULL)
923         _value = g_strdup(defaultval);
925     return;
928 ParamEnum::ParamEnum (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
929     Parameter(name, guitext, desc, scope, ext), _current_choice(NULL)
931     return;
934 ParamEnum::~ParamEnum (void)
939 /** \brief  Return the value as a string */
940 Glib::ustring *
941 ParamEnum::string (void)
943     Glib::ustring * mystring = new Glib::ustring("");
944     *mystring += "\"";
945     *mystring += this->get(NULL, NULL);
946     *mystring += "\"";
947     return mystring;
950 Gtk::Widget *
951 ParamEnum::get_widget (SPDocument * doc, Inkscape::XML::Node * node)
953     return NULL;
956 const gchar *
957 ParamEnum::set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node)
959     return NULL;
963 }  /* namespace Extension */
964 }  /* namespace Inkscape */
966 /*
967   Local Variables:
968   mode:c++
969   c-file-style:"stroustrup"
970   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
971   indent-tabs-mode:nil
972   fill-column:99
973   End:
974 */
975 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :