Code

Pot and Dutch translation update
[inkscape.git] / src / extension / param / parameter.cpp
1 /** @file
2  * @brief Parameters for extensions.
3  */
4 /* Author:
5  *   Ted Gould <ted@gould.cx>
6  *   Johan Engelen <johan@shouraizou.nl>
7  *
8  * Copyright (C) 2005-2007 Authors
9  *
10  * Released under GNU GPL, read the file 'COPYING' for more information
11  */
13 #ifdef HAVE_CONFIG_H
14 # include "config.h"
15 #endif
17 #ifdef linux  // does the dollar sign need escaping when passed as string parameter?
18 # define ESCAPE_DOLLAR_COMMANDLINE
19 #endif
21 #include <gtkmm/adjustment.h>
22 #include <gtkmm/box.h>
23 #include <gtkmm/spinbutton.h>
25 #include <xml/node.h>
27 #include <extension/extension.h>
28 #include "document-private.h"
29 #include "sp-object.h"
30 #include <color.h>
31 #include "widgets/sp-color-selector.h"
32 #include "widgets/sp-color-notebook.h"
34 #include "parameter.h"
35 #include "bool.h"
36 #include "color.h"
37 #include "description.h"
38 #include "groupheader.h"
39 #include "enum.h"
40 #include "float.h"
41 #include "int.h"
42 #include "notebook.h"
43 #include "radiobutton.h"
44 #include "string.h"
46 namespace Inkscape {
47 namespace Extension {
49 /**
50     \return None
51     \brief  This function creates a parameter that can be used later.  This
52             is typically done in the creation of the extension and defined
53             in the XML file describing the extension (it's private so people
54             have to use the system) :)
55     \param  in_repr  The XML describing the parameter
57     This function first grabs all of the data out of the Repr and puts
58     it into local variables.  Actually, these are just pointers, and the
59     data is not duplicated so we need to be careful with it.  If there
60     isn't a name or a type in the XML, then no parameter is created as
61     the function just returns.
63     From this point on, we're pretty committed as we've allocated an
64     object and we're starting to fill it.  The name is set first, and
65     is created with a strdup to actually allocate memory for it.  Then
66     there is a case statement (roughly because strcmp requires 'ifs')
67     based on what type of parameter this is.  Depending which type it
68     is, the value is interpreted differently, but they are relatively
69     straight forward.  In all cases the value is set to the default
70     value from the XML and the type is set to the interpreted type.
71 */
72 Parameter *
73 Parameter::make (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext)
74 {
75     const char * name;
76     const char * type;
77     const char * guitext;
78     const char * desc;
79     const char * scope_str;
80     Parameter::_scope_t scope = Parameter::SCOPE_USER;
81         bool gui_hidden = false;
82         const char * gui_hide;
83         const char * gui_tip;
85     name = in_repr->attribute("name");
86     type = in_repr->attribute("type");
87     guitext = in_repr->attribute("gui-text");
88     if (guitext == NULL)
89         guitext = in_repr->attribute("_gui-text");
90     gui_tip = in_repr->attribute("gui-tip");
91     if (gui_tip == NULL)
92         gui_tip = in_repr->attribute("_gui-tip");
93     desc = in_repr->attribute("gui-description");
94     if (desc == NULL)
95         desc = in_repr->attribute("_gui-description");
96     scope_str = in_repr->attribute("scope");
97         gui_hide = in_repr->attribute("gui-hidden");
98         if (gui_hide != NULL) {
99                 if (strcmp(gui_hide, "1") == 0 ||
100                         strcmp(gui_hide, "true") == 0) {
101                         gui_hidden = true;
102                 }
103                 /* else stays false */
104         }
105     const gchar* appearance = in_repr->attribute("appearance");
107     /* In this case we just don't have enough information */
108     if (name == NULL || type == NULL) {
109         return NULL;
110     }
112     if (scope_str != NULL) {
113         if (!strcmp(scope_str, "user")) {
114             scope = Parameter::SCOPE_USER;
115         } else if (!strcmp(scope_str, "document")) {
116             scope = Parameter::SCOPE_DOCUMENT;
117         } else if (!strcmp(scope_str, "node")) {
118             scope = Parameter::SCOPE_NODE;
119         }
120     }
122     Parameter * param = NULL;
123     if (!strcmp(type, "boolean")) {
124         param = new ParamBool(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
125     } else if (!strcmp(type, "int")) {
126         param = new ParamInt(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
127     } else if (!strcmp(type, "float")) {
128         param = new ParamFloat(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
129     } else if (!strcmp(type, "string")) {
130         param = new ParamString(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
131         const gchar * max_length = in_repr->attribute("max_length");
132         if (max_length != NULL) {
133                 ParamString * ps = dynamic_cast<ParamString *>(param);
134                 ps->setMaxLength(atoi(max_length));
135         }
136     } else if (!strcmp(type, "description")) {
137         param = new ParamDescription(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
138     } else if (!strcmp(type, "groupheader")) {
139         param = new ParamGroupHeader(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);        
140     } else if (!strcmp(type, "enum")) {
141         param = new ParamComboBox(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
142     } else if (!strcmp(type, "notebook")) {
143         param = new ParamNotebook(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
144     } else if (!strcmp(type, "optiongroup")) {
145         if (appearance && !strcmp(appearance, "minimal")) {
146             param = new ParamRadioButton(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr, ParamRadioButton::MINIMAL);
147         } else {
148             param = new ParamRadioButton(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr, ParamRadioButton::FULL);
149         }
150     } else if (!strcmp(type, "color")) {
151         param = new ParamColor(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
152     }
154     /* Note: param could equal NULL */
155     return param;
158 /** \brief  Wrapper to cast to the object and use it's function.  */
159 bool
160 Parameter::get_bool (const SPDocument * doc, const Inkscape::XML::Node * node)
162     ParamBool * boolpntr = dynamic_cast<ParamBool *>(this);
163     if (boolpntr == NULL)
164         throw Extension::param_not_bool_param();
165     return boolpntr->get(doc, node);
168 /** \brief  Wrapper to cast to the object and use it's function.  */
169 int
170 Parameter::get_int (const SPDocument * doc, const Inkscape::XML::Node * node)
172     ParamInt * intpntr = dynamic_cast<ParamInt *>(this);
173     if (intpntr == NULL)
174         throw Extension::param_not_int_param();
175     return intpntr->get(doc, node);
178 /** \brief  Wrapper to cast to the object and use it's function.  */
179 float
180 Parameter::get_float (const SPDocument * doc, const Inkscape::XML::Node * node)
182     ParamFloat * floatpntr = dynamic_cast<ParamFloat *>(this);
183     if (floatpntr == NULL)
184         throw Extension::param_not_float_param();
185     return floatpntr->get(doc, node);
188 /** \brief  Wrapper to cast to the object and use it's function.  */
189 const gchar *
190 Parameter::get_string (const SPDocument * doc, const Inkscape::XML::Node * node)
192     ParamString * stringpntr = dynamic_cast<ParamString *>(this);
193     if (stringpntr == NULL)
194         throw Extension::param_not_string_param();
195     return stringpntr->get(doc, node);
198 /** \brief  Wrapper to cast to the object and use it's function.  */
199 const gchar *
200 Parameter::get_enum (const SPDocument * doc, const Inkscape::XML::Node * node)
202     ParamComboBox * param = dynamic_cast<ParamComboBox *>(this);
203     if (param == NULL)
204         throw Extension::param_not_enum_param();
205     return param->get(doc, node);
208 /** \brief  Wrapper to cast to the object and use it's function.  */
209 gchar const *Parameter::get_optiongroup(SPDocument const * doc, Inkscape::XML::Node const * node)
211     ParamRadioButton * param = dynamic_cast<ParamRadioButton *>(this);
212     if (!param) {
213         throw Extension::param_not_optiongroup_param();
214     }
215     return param->get(doc, node);
218 guint32
219 Parameter::get_color(const SPDocument* doc, const Inkscape::XML::Node* node)
221     ParamColor* param = dynamic_cast<ParamColor *>(this);
222     if (param == NULL)
223         throw Extension::param_not_color_param();
224     return param->get(doc, node);
227 /** \brief  Wrapper to cast to the object and use it's function.  */
228 bool
229 Parameter::set_bool (bool in, SPDocument * doc, Inkscape::XML::Node * node)
231     ParamBool * boolpntr = dynamic_cast<ParamBool *>(this);
232     if (boolpntr == NULL)
233         throw Extension::param_not_bool_param();
234     return boolpntr->set(in, doc, node);
237 /** \brief  Wrapper to cast to the object and use it's function.  */
238 int
239 Parameter::set_int (int in, SPDocument * doc, Inkscape::XML::Node * node)
241     ParamInt * intpntr = dynamic_cast<ParamInt *>(this);
242     if (intpntr == NULL)
243         throw Extension::param_not_int_param();
244     return intpntr->set(in, doc, node);
247 /** \brief  Wrapper to cast to the object and use it's function.  */
248 float
249 Parameter::set_float (float in, SPDocument * doc, Inkscape::XML::Node * node)
251     ParamFloat * floatpntr;
252     floatpntr = dynamic_cast<ParamFloat *>(this);
253     if (floatpntr == NULL)
254         throw Extension::param_not_float_param();
255     return floatpntr->set(in, doc, node);
258 /** \brief  Wrapper to cast to the object and use it's function.  */
259 const gchar *
260 Parameter::set_string (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node)
262     ParamString * stringpntr = dynamic_cast<ParamString *>(this);
263     if (stringpntr == NULL)
264         throw Extension::param_not_string_param();
265     return stringpntr->set(in, doc, node);
268 gchar const * Parameter::set_optiongroup( gchar const * in, SPDocument * doc, Inkscape::XML::Node * node )
270     ParamRadioButton *param = dynamic_cast<ParamRadioButton *>(this);
271     if (!param) {
272         throw Extension::param_not_optiongroup_param();
273     }
274     return param->set(in, doc, node);
278 /** \brief  Wrapper to cast to the object and use it's function.  */
279 guint32
280 Parameter::set_color (guint32 in, SPDocument * doc, Inkscape::XML::Node * node)
282     ParamColor* param = dynamic_cast<ParamColor *>(this);
283     if (param == NULL)
284         throw Extension::param_not_color_param();
285     return param->set(in, doc, node);
289 /** \brief  Oop, now that we need a parameter, we need it's name.  */
290 Parameter::Parameter (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, bool gui_hidden, const gchar * gui_tip, Inkscape::Extension::Extension * ext) :
291     extension(ext), _name(NULL), _desc(NULL), _scope(scope), _text(NULL), _gui_hidden(gui_hidden), _gui_tip(NULL)
293     if (name != NULL) {
294         _name = g_strdup(name);
295     }
296     if (desc != NULL) {
297         _desc = g_strdup(desc);
298 //        printf("Adding description: '%s' on '%s'\n", _desc, _name);
299     }
300     if (gui_tip != NULL) {
301         _gui_tip = g_strdup(gui_tip);
302     }
305     if (guitext != NULL)
306         _text = g_strdup(guitext);
307     else
308         _text = g_strdup(name);
310     return;
313 /** \brief  Just free the allocated name. */
314 Parameter::~Parameter (void)
316     g_free(_name);
317     g_free(_text);
318         g_free(_gui_tip);
319     g_free(_desc);
322 /** \brief  Build the name to write the parameter from the extension's
323             ID and the name of this parameter. */
324 gchar *
325 Parameter::pref_name (void)
327     return g_strdup_printf("%s.%s", extension->get_id(), _name);
330 Inkscape::XML::Node *
331 Parameter::find_child (Inkscape::XML::Node * adult)
333     return sp_repr_lookup_child(adult, "name", _name);
336 Inkscape::XML::Node *
337 Parameter::new_child (Inkscape::XML::Node * parent)
339     Inkscape::XML::Node * retval;
340     retval = parent->document()->createElement("inkscape:extension-param");
341     retval->setAttribute("name", _name);
343     parent->appendChild(retval);
344     Inkscape::GC::release(retval);
345     return retval;
348 Inkscape::XML::Node *
349 Parameter::document_param_node (SPDocument * doc)
351     Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
352     Inkscape::XML::Node * defs = SP_OBJECT_REPR(SP_DOCUMENT_DEFS(doc));
353     Inkscape::XML::Node * params = NULL;
355     GQuark const name_quark = g_quark_from_string("inkscape:extension-params");
357     for (Inkscape::XML::Node * child = defs->firstChild();
358             child != NULL;
359             child = child->next()) {
360         if ((GQuark)child->code() == name_quark &&
361                 !strcmp(child->attribute("extension"), extension->get_id())) {
362             params = child;
363             break;
364         }
365     }
367     if (params == NULL) {
368         params = xml_doc->createElement("inkscape:extension-param");
369         params->setAttribute("extension", extension->get_id());
370         defs->appendChild(params);
371         Inkscape::GC::release(params);
372     }
374     return params;
377 /** \brief  Basically, if there is no widget pass a NULL. */
378 Gtk::Widget *
379 Parameter::get_widget (SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/, sigc::signal<void> * /*changeSignal*/)
381     return NULL;
384 /** \brief  If I'm not sure which it is, just don't return a value. */
385 void
386 Parameter::string (std::string &/*string*/)
388     return;
391 void
392 Parameter::string (std::list <std::string> &list)
394     std::string value;
395     string(value);
396     if (value == "") {
397         return;
398     }
400     std::string final;
401     final += "--";
402     final += name();
403     final += "=";
404     final += value;
406     list.insert(list.end(), final);
407     return;
410 /** \brief  All the code in Notebook::get_param to get the notebook content */
411 Parameter *
412 Parameter::get_param(const gchar * name)
414     return NULL;
417 Glib::ustring const extension_pref_root = "/extensions/";
419 }  /* namespace Extension */
420 }  /* namespace Inkscape */
422 /*
423   Local Variables:
424   mode:c++
425   c-file-style:"stroustrup"
426   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
427   indent-tabs-mode:nil
428   fill-column:99
429   End:
430 */
431 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :