57bc98fcc55c04043d99297464a4b7b19d9446df
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;
124 }
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)
146 {
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;
178 }
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)
220 {
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;
266 }
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)
279 {
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;
287 }
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)
300 {
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;
310 }
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)
323 {
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;
333 }
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)
350 {
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;
362 }
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)
367 {
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);
373 }
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)
378 {
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);
384 }
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)
389 {
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);
395 }
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)
400 {
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);
406 }
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)
411 {
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);
417 }
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)
422 {
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);
428 }
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)
433 {
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);
439 }
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)
444 {
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);
450 }
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)
455 {
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;
470 }
472 /** \brief Free the allocated data. */
473 ParamString::~ParamString(void)
474 {
475 g_free(_value);
476 }
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)
481 {
482 if (name != NULL)
483 _name = g_strdup(name);
484 if (desc != NULL)
485 _desc = g_strdup(desc);
488 if (guitext != NULL)
489 _text = g_strdup(guitext);
490 else
491 _text = g_strdup(name);
493 return;
494 }
496 /** \brief Just free the allocated name. */
497 Parameter::~Parameter (void)
498 {
499 g_free(_name);
500 g_free(_text);
501 }
503 /** \brief Build the name to write the parameter from the extension's
504 ID and the name of this parameter. */
505 gchar *
506 Parameter::pref_name (void)
507 {
508 return g_strdup_printf("%s.%s", extension->get_id(), _name);
509 }
511 /** \brief Basically, if there is no widget pass a NULL. */
512 Gtk::Widget *
513 Parameter::get_widget (void)
514 {
515 return NULL;
516 }
518 /** \brief If I'm not sure which it is, just don't return a value. */
519 Glib::ustring *
520 Parameter::string (void)
521 {
522 Glib::ustring * mystring = new Glib::ustring("");
523 return mystring;
524 }
526 /** \brief A class to make an adjustment that uses Extension params */
527 class ParamFloatAdjustment : public Gtk::Adjustment {
528 /** The parameter to adjust */
529 ParamFloat * _pref;
530 public:
531 /** \brief Make the adjustment using an extension and the string
532 describing the parameter. */
533 ParamFloatAdjustment (ParamFloat * param) :
534 Gtk::Adjustment(0.0, param->min(), param->max(), 0.1), _pref(param) {
535 this->set_value(_pref->get(NULL, NULL) /* \todo fix */);
536 this->signal_value_changed().connect(sigc::mem_fun(this, &ParamFloatAdjustment::val_changed));
537 return;
538 };
540 void val_changed (void);
541 }; /* class ParamFloatAdjustment */
543 /** \brief A function to respond to the value_changed signal from the
544 adjustment.
546 This function just grabs the value from the adjustment and writes
547 it to the parameter. Very simple, but yet beautiful.
548 */
549 void
550 ParamFloatAdjustment::val_changed (void)
551 {
552 // std::cout << "Value Changed to: " << this->get_value() << std::endl;
553 _pref->set(this->get_value(), NULL /* \todo fix */, NULL);
554 return;
555 }
557 /** \brief A class to make an adjustment that uses Extension params */
558 class ParamIntAdjustment : public Gtk::Adjustment {
559 /** The parameter to adjust */
560 ParamInt * _pref;
561 public:
562 /** \brief Make the adjustment using an extension and the string
563 describing the parameter. */
564 ParamIntAdjustment (ParamInt * param) :
565 Gtk::Adjustment(0.0, param->min(), param->max(), 1.0), _pref(param) {
566 this->set_value(_pref->get(NULL, NULL) /* \todo fix */);
567 this->signal_value_changed().connect(sigc::mem_fun(this, &ParamIntAdjustment::val_changed));
568 return;
569 };
571 void val_changed (void);
572 }; /* class ParamIntAdjustment */
574 /** \brief A function to respond to the value_changed signal from the
575 adjustment.
577 This function just grabs the value from the adjustment and writes
578 it to the parameter. Very simple, but yet beautiful.
579 */
580 void
581 ParamIntAdjustment::val_changed (void)
582 {
583 // std::cout << "Value Changed to: " << this->get_value() << std::endl;
584 _pref->set((int)this->get_value(), NULL /* \todo fix */, NULL);
585 return;
586 }
588 /**
589 \brief Creates a Float Adjustment for a float parameter
591 Builds a hbox with a label and a float adjustment in it.
592 */
593 Gtk::Widget *
594 ParamFloat::get_widget (void)
595 {
596 Gtk::HBox * hbox = new Gtk::HBox();
598 Gtk::Label * label = new Gtk::Label(_(_text), Gtk::ALIGN_LEFT);
599 label->show();
600 hbox->pack_start(*label, true, true);
602 ParamFloatAdjustment * fadjust = new ParamFloatAdjustment(this);
603 Gtk::SpinButton * spin = new Gtk::SpinButton(*fadjust, 0.1, 1);
604 spin->show();
605 hbox->pack_start(*spin, false, false);
607 hbox->show();
609 return dynamic_cast<Gtk::Widget *>(hbox);
610 }
612 /**
613 \brief Creates a Int Adjustment for a int parameter
615 Builds a hbox with a label and a int adjustment in it.
616 */
617 Gtk::Widget *
618 ParamInt::get_widget (void)
619 {
620 Gtk::HBox * hbox = new Gtk::HBox();
622 Gtk::Label * label = new Gtk::Label(_(_text), Gtk::ALIGN_LEFT);
623 label->show();
624 hbox->pack_start(*label, true, true);
626 ParamIntAdjustment * fadjust = new ParamIntAdjustment(this);
627 Gtk::SpinButton * spin = new Gtk::SpinButton(*fadjust, 1.0, 0);
628 spin->show();
629 hbox->pack_start(*spin, false, false);
631 hbox->show();
633 return dynamic_cast<Gtk::Widget *>(hbox);
634 }
636 /** \brief A check button which is Param aware. It works with the
637 parameter to change it's value as the check button changes
638 value. */
639 class ParamBoolCheckButton : public Gtk::CheckButton {
640 private:
641 /** \brief Param to change */
642 ParamBool * _pref;
643 public:
644 /** \brief Initialize the check button
645 \param param Which parameter to adjust on changing the check button
647 This function sets the value of the checkbox to be that of the
648 parameter, and then sets up a callback to \c on_toggle.
649 */
650 ParamBoolCheckButton (ParamBool * param) :
651 Gtk::CheckButton(), _pref(param) {
652 this->set_active(_pref->get(NULL, NULL) /**\todo fix */);
653 this->signal_toggled().connect(sigc::mem_fun(this, &ParamBoolCheckButton::on_toggle));
654 return;
655 }
656 void on_toggle (void);
657 };
659 /**
660 \brief A function to respond to the check box changing
662 Adjusts the value of the preference to match that in the check box.
663 */
664 void
665 ParamBoolCheckButton::on_toggle (void)
666 {
667 _pref->set(this->get_active(), NULL /**\todo fix this */, NULL);
668 return;
669 }
671 /**
672 \brief Creates a bool check button for a bool parameter
674 Builds a hbox with a label and a check button in it.
675 */
676 Gtk::Widget *
677 ParamBool::get_widget (void)
678 {
679 Gtk::HBox * hbox = new Gtk::HBox();
681 Gtk::Label * label = new Gtk::Label(_(_text), Gtk::ALIGN_LEFT);
682 label->show();
683 hbox->pack_start(*label, true, true);
685 ParamBoolCheckButton * checkbox = new ParamBoolCheckButton(this);
686 checkbox->show();
687 hbox->pack_start(*checkbox, false, false);
689 hbox->show();
691 return dynamic_cast<Gtk::Widget *>(hbox);
692 }
694 /** \brief A special category of Gtk::Entry to handle string parameteres */
695 class ParamStringEntry : public Gtk::Entry {
696 private:
697 ParamString * _pref;
698 public:
699 /** \brief Build a string preference for the given parameter
700 \param pref Where to get the string from, and where to put it
701 when it changes.
702 */
703 ParamStringEntry (ParamString * pref) :
704 Gtk::Entry(), _pref(pref) {
705 if (_pref->get(NULL, NULL) != NULL)
706 this->set_text(Glib::ustring(_pref->get(NULL, NULL)));
707 this->signal_changed().connect(sigc::mem_fun(this, &ParamStringEntry::changed_text));
708 };
709 void changed_text (void);
710 };
712 /** \brief Respond to the text box changing
714 This function responds to the box changing by grabbing the value
715 from the text box and putting it in the parameter.
716 */
717 void
718 ParamStringEntry::changed_text (void)
719 {
720 Glib::ustring data = this->get_text();
721 _pref->set(data.c_str(), NULL, NULL);
722 return;
723 }
725 /**
726 \brief Creates a text box for the string parameter
728 Builds a hbox with a label and a text box in it.
729 */
730 Gtk::Widget *
731 ParamString::get_widget (void)
732 {
733 Gtk::HBox * hbox = new Gtk::HBox();
735 Gtk::Label * label = new Gtk::Label(_(_text), Gtk::ALIGN_LEFT);
736 label->show();
737 hbox->pack_start(*label, true, true);
739 ParamStringEntry * textbox = new ParamStringEntry(this);
740 textbox->show();
741 hbox->pack_start(*textbox, false, false);
743 hbox->show();
745 return dynamic_cast<Gtk::Widget *>(hbox);
746 }
748 /** \brief Return 'true' or 'false' */
749 Glib::ustring *
750 ParamBool::string (void)
751 {
752 Glib::ustring * mystring;
754 if (_value)
755 mystring = new Glib::ustring("true");
756 else
757 mystring = new Glib::ustring("false");
759 return mystring;
760 }
762 /** \brief Return the value as a string */
763 Glib::ustring *
764 ParamInt::string (void)
765 {
766 char startstring[32];
767 sprintf(startstring, "%d", _value);
768 Glib::ustring * mystring = new Glib::ustring(startstring);
769 return mystring;
770 }
772 /** \brief Return the value as a string */
773 Glib::ustring *
774 ParamFloat::string (void)
775 {
776 char startstring[G_ASCII_DTOSTR_BUF_SIZE];
777 g_ascii_dtostr(startstring, G_ASCII_DTOSTR_BUF_SIZE, _value);
778 Glib::ustring * mystring = new Glib::ustring(startstring);
779 return mystring;
780 }
782 /** \brief Return the value as a string */
783 Glib::ustring *
784 ParamString::string (void)
785 {
786 Glib::ustring * mystring = new Glib::ustring("");
787 *mystring += "\"";
788 *mystring += _value;
789 *mystring += "\"";
790 return mystring;
791 }
794 } /* namespace Extension */
795 } /* namespace Inkscape */
797 /*
798 Local Variables:
799 mode:c++
800 c-file-style:"stroustrup"
801 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
802 indent-tabs-mode:nil
803 fill-column:99
804 End:
805 */
806 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :