Code

continue switching sp_repr_new* over to XML::Document::create*
[inkscape.git] / src / extension / paramradiobutton.cpp
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