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