Code

r18381@shi: ted | 2008-03-07 20:11:34 -0800
[inkscape.git] / src / extension / param / parameter.cpp
1 /** \file
2  * Parameters for extensions.
3  */
5 /*
6  * Author:
7  *   Ted Gould <ted@gould.cx>
8  *   Johan Engelen <johan@shouraizou.nl>
9  *
10  * Copyright (C) 2005-2007 Authors
11  *
12  * Released under GNU GPL, read the file 'COPYING' for more information
13  */
15 #ifdef HAVE_CONFIG_H
16 # include "config.h"
17 #endif
19 #ifdef linux  // does the dollar sign need escaping when passed as string parameter?
20 # define ESCAPE_DOLLAR_COMMANDLINE
21 #endif
23 #include <gtkmm/adjustment.h>
24 #include <gtkmm/box.h>
25 #include <gtkmm/spinbutton.h>
27 #include <xml/node.h>
29 #include <extension/extension.h>
30 #include "document-private.h"
31 #include "sp-object.h"
32 #include <color.h>
33 #include "widgets/sp-color-selector.h"
34 #include "widgets/sp-color-notebook.h"
36 #include "parameter.h"
37 #include "bool.h"
38 #include "color.h"
39 #include "description.h"
40 #include "enum.h"
41 #include "float.h"
42 #include "int.h"
43 #include "notebook.h"
44 #include "radiobutton.h"
45 #include "string.h"
47 namespace Inkscape {
48 namespace Extension {
50 /**
51     \return None
52     \brief  This function creates a parameter that can be used later.  This
53             is typically done in the creation of the extension and defined
54             in the XML file describing the extension (it's private so people
55             have to use the system) :)
56     \param  in_repr  The XML describing the parameter
58     This function first grabs all of the data out of the Repr and puts
59     it into local variables.  Actually, these are just pointers, and the
60     data is not duplicated so we need to be careful with it.  If there
61     isn't a name or a type in the XML, then no parameter is created as
62     the function just returns.
64     From this point on, we're pretty committed as we've allocated an
65     object and we're starting to fill it.  The name is set first, and
66     is created with a strdup to actually allocate memory for it.  Then
67     there is a case statement (roughly because strcmp requires 'ifs')
68     based on what type of parameter this is.  Depending which type it
69     is, the value is interpreted differently, but they are relatively
70     straight forward.  In all cases the value is set to the default
71     value from the XML and the type is set to the interpreted type.
72 */
73 Parameter *
74 Parameter::make (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext)
75 {
76     const char * name;
77     const char * type;
78     const char * guitext;
79     const char * desc;
80     const char * scope_str;
81     Parameter::_scope_t scope = Parameter::SCOPE_USER;
82         bool gui_hidden = false;
83         const char * gui_hide;
84         const char * gui_tip;
86     name = in_repr->attribute("name");
87     type = in_repr->attribute("type");
88     guitext = in_repr->attribute("gui-text");
89     if (guitext == NULL)
90         guitext = in_repr->attribute("_gui-text");
91     gui_tip = in_repr->attribute("gui-tip");
92     if (gui_tip == NULL)
93         gui_tip = in_repr->attribute("_gui-tip");
94     desc = in_repr->attribute("gui-description");
95     if (desc == NULL)
96         desc = in_repr->attribute("_gui-description");
97     scope_str = in_repr->attribute("scope");
98         gui_hide = in_repr->attribute("gui-hidden");
99         if (gui_hide != NULL) {
100                 if (strcmp(gui_hide, "1") == 0 ||
101                         strcmp(gui_hide, "true") == 0) {
102                         gui_hidden = true;
103                 }
104                 /* else stays false */
105         }
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     } else if (!strcmp(type, "description")) {
132         param = new ParamDescription(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
133     } else if (!strcmp(type, "enum")) {
134         param = new ParamComboBox(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
135     } else if (!strcmp(type, "notebook")) {
136         param = new ParamNotebook(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
137     } else if (!strcmp(type, "optiongroup")) {
138         param = new ParamRadioButton(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
139     } else if (!strcmp(type, "color")) {
140         param = new ParamColor(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
141     }
143     /* Note: param could equal NULL */
144     return param;
149 /** \brief  Wrapper to cast to the object and use it's function.  */
150 bool
151 Parameter::get_bool (const SPDocument * doc, const Inkscape::XML::Node * node)
153     ParamBool * boolpntr = dynamic_cast<ParamBool *>(this);
154     if (boolpntr == NULL)
155         throw Extension::param_not_bool_param();
156     return boolpntr->get(doc, node);
159 /** \brief  Wrapper to cast to the object and use it's function.  */
160 int
161 Parameter::get_int (const SPDocument * doc, const Inkscape::XML::Node * node)
163     ParamInt * intpntr = dynamic_cast<ParamInt *>(this);
164     if (intpntr == NULL)
165         throw Extension::param_not_int_param();
166     return intpntr->get(doc, node);
169 /** \brief  Wrapper to cast to the object and use it's function.  */
170 float
171 Parameter::get_float (const SPDocument * doc, const Inkscape::XML::Node * node)
173     ParamFloat * floatpntr = dynamic_cast<ParamFloat *>(this);
174     if (floatpntr == NULL)
175         throw Extension::param_not_float_param();
176     return floatpntr->get(doc, node);
179 /** \brief  Wrapper to cast to the object and use it's function.  */
180 const gchar *
181 Parameter::get_string (const SPDocument * doc, const Inkscape::XML::Node * node)
183     ParamString * stringpntr = dynamic_cast<ParamString *>(this);
184     if (stringpntr == NULL)
185         throw Extension::param_not_string_param();
186     return stringpntr->get(doc, node);
189 /** \brief  Wrapper to cast to the object and use it's function.  */
190 const gchar *
191 Parameter::get_enum (const SPDocument * doc, const Inkscape::XML::Node * node)
193     ParamComboBox * param = dynamic_cast<ParamComboBox *>(this);
194     if (param == NULL)
195         throw Extension::param_not_enum_param();
196     return param->get(doc, node);
199 guint32
200 Parameter::get_color(const SPDocument* doc, const Inkscape::XML::Node* node)
202     ParamColor* param = dynamic_cast<ParamColor *>(this);
203     if (param == NULL)
204         throw Extension::param_not_color_param();
205     return param->get(doc, node);
208 /** \brief  Wrapper to cast to the object and use it's function.  */
209 bool
210 Parameter::set_bool (bool in, SPDocument * doc, Inkscape::XML::Node * node)
212     ParamBool * boolpntr = dynamic_cast<ParamBool *>(this);
213     if (boolpntr == NULL)
214         throw Extension::param_not_bool_param();
215     return boolpntr->set(in, doc, node);
218 /** \brief  Wrapper to cast to the object and use it's function.  */
219 int
220 Parameter::set_int (int in, SPDocument * doc, Inkscape::XML::Node * node)
222     ParamInt * intpntr = dynamic_cast<ParamInt *>(this);
223     if (intpntr == NULL)
224         throw Extension::param_not_int_param();
225     return intpntr->set(in, doc, node);
228 /** \brief  Wrapper to cast to the object and use it's function.  */
229 float
230 Parameter::set_float (float in, SPDocument * doc, Inkscape::XML::Node * node)
232     ParamFloat * floatpntr;
233     floatpntr = dynamic_cast<ParamFloat *>(this);
234     if (floatpntr == NULL)
235         throw Extension::param_not_float_param();
236     return floatpntr->set(in, doc, node);
239 /** \brief  Wrapper to cast to the object and use it's function.  */
240 const gchar *
241 Parameter::set_string (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node)
243     ParamString * stringpntr = dynamic_cast<ParamString *>(this);
244     if (stringpntr == NULL)
245         throw Extension::param_not_string_param();
246     return stringpntr->set(in, doc, node);
248 /** \brief  Wrapper to cast to the object and use it's function.  */
249 guint32
250 Parameter::set_color (guint32 in, SPDocument * doc, Inkscape::XML::Node * node)
252     ParamColor* param = dynamic_cast<ParamColor *>(this);
253     if (param == NULL)
254         throw Extension::param_not_color_param();
255     return param->set(in, doc, node);
259 /** \brief  Oop, now that we need a parameter, we need it's name.  */
260 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) :
261     extension(ext), _name(NULL), _desc(NULL), _scope(scope), _text(NULL), _gui_hidden(gui_hidden), _gui_tip(NULL)
263     if (name != NULL) {
264         _name = g_strdup(name);
265     }
266     if (desc != NULL) {
267         _desc = g_strdup(desc);
268         // printf("Adding description: '%s' on '%s'\n", _desc, _name);
269     }
270     if (gui_tip != NULL) {
271         _gui_tip = g_strdup(gui_tip);
272     }
275     if (guitext != NULL)
276         _text = g_strdup(guitext);
277     else
278         _text = g_strdup(name);
280     return;
283 /** \brief  Just free the allocated name. */
284 Parameter::~Parameter (void)
286     g_free(_name);
287     g_free(_text);
288         g_free(_gui_tip);
291 /** \brief  Build the name to write the parameter from the extension's
292             ID and the name of this parameter. */
293 gchar *
294 Parameter::pref_name (void)
296     return g_strdup_printf("%s.%s", extension->get_id(), _name);
299 Inkscape::XML::Node *
300 Parameter::find_child (Inkscape::XML::Node * adult)
302     return sp_repr_lookup_child(adult, "name", _name);
305 Inkscape::XML::Node *
306 Parameter::new_child (Inkscape::XML::Node * parent)
308     Inkscape::XML::Node * retval;
309     retval = parent->document()->createElement("inkscape:extension-param");
310     retval->setAttribute("name", _name);
312     parent->appendChild(retval);
313     return retval;
316 Inkscape::XML::Node *
317 Parameter::document_param_node (SPDocument * doc)
319     Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
320     Inkscape::XML::Node * defs = SP_OBJECT_REPR(SP_DOCUMENT_DEFS(doc));
321     Inkscape::XML::Node * params = NULL;
323     GQuark const name_quark = g_quark_from_string("inkscape:extension-params");
325     for (Inkscape::XML::Node * child = defs->firstChild();
326             child != NULL;
327             child = child->next()) {
328         if ((GQuark)child->code() == name_quark &&
329                 !strcmp(child->attribute("extension"), extension->get_id())) {
330             params = child;
331             break;
332         }
333     }
335     if (params == NULL) {
336         params = xml_doc->createElement("inkscape:extension-param");
337         params->setAttribute("extension", extension->get_id());
338         defs->appendChild(params);
339     }
341     return params;
344 /** \brief  Basically, if there is no widget pass a NULL. */
345 Gtk::Widget *
346 Parameter::get_widget (SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/, sigc::signal<void> * /*changeSignal*/)
348     return NULL;
351 /** \brief  If I'm not sure which it is, just don't return a value. */
352 void
353 Parameter::string (std::string &/*string*/)
355     return;
358 void
359 Parameter::string (std::list <std::string> &list)
361     std::string value;
362     string(value);
363     if (value == "") {
364         return;
365     }
367     std::string final;
368     final += "--";
369     final += name();
370     final += "=";
371     final += value;
373     list.insert(list.end(), final);
374     return;
377 }  /* namespace Extension */
378 }  /* namespace Inkscape */
380 /*
381   Local Variables:
382   mode:c++
383   c-file-style:"stroustrup"
384   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
385   indent-tabs-mode:nil
386   fill-column:99
387   End:
388 */
389 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :