Code

Changed preference to use file chooser button
[inkscape.git] / src / extension / paramradiobutton.cpp
1 /** \file
2  * extension parameter for radiobuttons.
3  *
4  * It uses a Gtk:ComboBoxText widget in the extension UI.
5  */
7 /*
8  * Author:
9  *   Johan Engelen <johan@shouraizou.nl>
10  *
11  * Copyright (C) 2006-2007 Johan Engelen
12  *
13  * Released under GNU GPL, read the file 'COPYING' for more information
14  */
16 #ifdef HAVE_CONFIG_H
17 # include "config.h"
18 #endif
21 #include <gtkmm/box.h>
22 #include <gtkmm/radiobutton.h>
23 #include <gtkmm/radiobuttongroup.h>
24 #include <gtkmm/tooltips.h>
25 #include <gtkmm/label.h>
27 #include <glibmm/i18n.h>
29 #include <xml/node.h>
31 #include "extension.h"
32 #include "prefs-utils.h"
33 #include "document-private.h"
34 #include "sp-object.h"
36 #include "paramradiobutton.h"
38 /** \brief  The root directory in the preferences database for extension
39             related parameters. */
40 #define PREF_DIR "extensions"
42 namespace Inkscape {
43 namespace Extension {
45 /* For internal use only.
46      Note that value and guitext MUST be non-NULL. This is ensured by newing only at one location in the code where non-NULL checks are made. */
47 class optionentry {
48 public:
49     optionentry (Glib::ustring * val, Glib::ustring * text) {
50         value = val;
51         guitext = text;
52     }
53     ~optionentry() {
54         delete value;
55         delete guitext;
56     }
58     Glib::ustring * value;
59     Glib::ustring * guitext;
60 };
62 ParamRadioButton::ParamRadioButton (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :
63     Parameter(name, guitext, desc, scope, ext)
64 {
65     choices = NULL;
66     _value = NULL;
68     // Read XML tree to add enumeration items:
69     // printf("Extension Constructor: ");
70     if (xml != NULL) {
71         Inkscape::XML::Node *child_repr = sp_repr_children(xml);
72         while (child_repr != NULL) {
73             char const * chname = child_repr->name();
74             if (!strcmp(chname, "option")) {
75                 Glib::ustring * newguitext = NULL;
76                 Glib::ustring * newvalue = NULL;
77                 const char * contents = sp_repr_children(child_repr)->content();
78                 if (contents != NULL)
79                      newguitext = new Glib::ustring(contents);
80                 else
81                     continue;  
82                     
83                 const char * val = child_repr->attribute("value");
84                 if (val != NULL)
85                     newvalue = new Glib::ustring(val);
86                 else
87                     newvalue = new Glib::ustring(*newguitext);
88                             
89                 if ( (newguitext) && (newvalue) ) {   // logical error if this is not true here
90                     choices = g_slist_append( choices, new optionentry(newvalue, newguitext) );
91                 }
92             }
93             child_repr = sp_repr_next(child_repr);
94         }
95     }
97     // Initialize _value with the default value from xml
98     // for simplicity : default to the contents of the first xml-child
99     const char * defaultval = NULL;
100     if (choices)
101         defaultval = ((optionentry*) choices->data)->value->c_str();
103     gchar * pref_name = this->pref_name();
104     const gchar * paramval = prefs_get_string_attribute(PREF_DIR, pref_name);
105     g_free(pref_name);
107     if (paramval != NULL)
108         defaultval = paramval;
109     if (defaultval != NULL)
110         _value = g_strdup(defaultval);  // allocate space for _value
112     return;
115 ParamRadioButton::~ParamRadioButton (void)
117     //destroy choice strings
118     for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
119         delete (reinterpret_cast<optionentry *>(list->data));
120     }
121     g_slist_free(choices);
123     g_free(_value);
127 /** \brief  A function to set the \c _value
128     \param  in   The value to set
129     \param  doc  A document that should be used to set the value.
130     \param  node The node where the value may be placed
132     This function sets ONLY the internal value, but it also sets the value
133     in the preferences structure.  To put it in the right place, \c PREF_DIR
134     and \c pref_name() are used.
136     To copy the data into _value the old memory must be free'd first.
137     It is important to note that \c g_free handles \c NULL just fine.  Then
138     the passed in value is duplicated using \c g_strdup().
139 */
140 const gchar *
141 ParamRadioButton::set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node)
143     if (in == NULL) return NULL; /* Can't have NULL string */
145     Glib::ustring * settext = NULL;
146     for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
147         optionentry * entr = reinterpret_cast<optionentry *>(list->data);
148         if ( !entr->guitext->compare(in) ) {
149             settext = entr->value;
150             break;  // break out of for loop
151         }
152     }
153     if (settext) {
154         if (_value != NULL) g_free(_value);
155         _value = g_strdup(settext->c_str());
156         gchar * prefname = this->pref_name();
157         prefs_set_string_attribute(PREF_DIR, prefname, _value);
158         g_free(prefname);
159     }
161     return _value;
165 /**
166     \brief  A function to get the current value of the parameter in a string form
167     \return A string with the 'value' as command line argument
168 */
169 Glib::ustring *
170 ParamRadioButton::string (void)
172     Glib::ustring * param_string = new Glib::ustring("");
173     *param_string += _value;
174     return param_string;
177 /** \brief  A special radiobutton class to use in ParamRadioButton */
178 class ParamRadioButtonWdg : public Gtk::RadioButton {
179 private:
180     ParamRadioButton * _pref;
181     SPDocument * _doc;
182     Inkscape::XML::Node * _node;
183 public:
184     /** \brief  Build a string preference for the given parameter
185         \param  pref  Where to put the radiobutton's string when it is selected.
186     */
187     ParamRadioButtonWdg ( Gtk::RadioButtonGroup& group, const Glib::ustring& label,
188                           ParamRadioButton * pref, SPDocument * doc, Inkscape::XML::Node * node ) :
189         Gtk::RadioButton(group, label), _pref(pref), _doc(doc), _node(node) {
190         add_changesignal();
191     };
192     ParamRadioButtonWdg ( const Glib::ustring& label,
193                           ParamRadioButton * pref, SPDocument * doc, Inkscape::XML::Node * node ) :
194         Gtk::RadioButton(label), _pref(pref), _doc(doc), _node(node) {
195         add_changesignal();
196     };
197     void add_changesignal() {
198         this->signal_toggled().connect(sigc::mem_fun(this, &ParamRadioButtonWdg::changed));
199     };
200     void changed (void);
201 };
203 /** \brief  Respond to the selected radiobutton changing
205     This function responds to the radiobutton selection changing by grabbing the value
206     from the text box and putting it in the parameter.
207 */
208 void
209 ParamRadioButtonWdg::changed (void)
211     if (this->get_active()) {
212         Glib::ustring data = this->get_label();
213         _pref->set(data.c_str(), _doc, _node);
214     }
219 /**
220     \brief  Creates a combobox widget for an enumeration parameter
221 */
222 Gtk::Widget *
223 ParamRadioButton::get_widget (SPDocument * doc, Inkscape::XML::Node * node, sigc::signal<void> * changeSignal)
225     Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, 4));
226     Gtk::VBox * vbox = Gtk::manage(new Gtk::VBox(false, 0));
228     Gtk::Label * label = Gtk::manage(new Gtk::Label(_(_text), Gtk::ALIGN_LEFT, Gtk::ALIGN_TOP));
229     label->show();
230     hbox->pack_start(*label, false, false);
232     // add choice strings as radiobuttons
233     // and select last selected option (_value)
234     bool first = true;
235     ParamRadioButtonWdg * radio;
236     Gtk::RadioButtonGroup group;
237     for (GSList * list = choices; list != NULL; list = g_slist_next(list)) {
238         optionentry * entr = reinterpret_cast<optionentry *>(list->data);
239         Glib::ustring * text = entr->guitext;
240         if (first) {
241             radio = Gtk::manage(new ParamRadioButtonWdg(*text, this, doc, node));
242             group = radio->get_group();
243             first = false;
244         } else {
245             radio = Gtk::manage(new ParamRadioButtonWdg(group, *text, this, doc, node));
246         }
247         radio->show();
248         vbox->pack_start(*radio, true, true);
249         if (!entr->value->compare(_value)) {
250             radio->set_active();
251         }
252     }
254     vbox->show();
255     hbox->pack_end(*vbox, false, false);
256     hbox->show();
259     return dynamic_cast<Gtk::Widget *>(hbox);
263 }  /* namespace Extension */
264 }  /* namespace Inkscape */