parameter.cpp revision e9b6af083e34e2397a8ddbe9781920733d09d151
5887N/A/** @file
5887N/A * @brief Parameters for extensions.
5887N/A */
5887N/A/* Author:
5887N/A * Ted Gould <ted@gould.cx>
5887N/A * Johan Engelen <johan@shouraizou.nl>
5887N/A *
5887N/A * Copyright (C) 2005-2007 Authors
5887N/A *
5887N/A * Released under GNU GPL, read the file 'COPYING' for more information
5887N/A */
5887N/A
5887N/A#ifdef HAVE_CONFIG_H
5887N/A# include "config.h"
5887N/A#endif
5887N/A
5887N/A#ifdef linux // does the dollar sign need escaping when passed as string parameter?
5887N/A# define ESCAPE_DOLLAR_COMMANDLINE
5887N/A#endif
5887N/A
5887N/A#include <gtkmm/adjustment.h>
5887N/A#include <gtkmm/box.h>
5887N/A#include <gtkmm/spinbutton.h>
5887N/A
5887N/A#include <xml/node.h>
5887N/A
5887N/A#include <extension/extension.h>
5887N/A#include "document-private.h"
5887N/A#include "sp-object.h"
5887N/A#include <color.h>
5887N/A#include "widgets/sp-color-selector.h"
5887N/A#include "widgets/sp-color-notebook.h"
5887N/A
5887N/A#include "parameter.h"
5887N/A#include "bool.h"
5887N/A#include "color.h"
5887N/A#include "description.h"
5887N/A#include "enum.h"
5887N/A#include "float.h"
5887N/A#include "int.h"
5887N/A#include "notebook.h"
5887N/A#include "radiobutton.h"
5887N/A#include "string.h"
5887N/A
5887N/Anamespace Inkscape {
5887N/Anamespace Extension {
5887N/A
5887N/A/**
5887N/A \return None
5887N/A \brief This function creates a parameter that can be used later. This
5887N/A is typically done in the creation of the extension and defined
5887N/A in the XML file describing the extension (it's private so people
5887N/A have to use the system) :)
5887N/A \param in_repr The XML describing the parameter
5887N/A
5887N/A This function first grabs all of the data out of the Repr and puts
5887N/A it into local variables. Actually, these are just pointers, and the
5887N/A data is not duplicated so we need to be careful with it. If there
5887N/A isn't a name or a type in the XML, then no parameter is created as
5887N/A the function just returns.
5887N/A
5887N/A From this point on, we're pretty committed as we've allocated an
5887N/A object and we're starting to fill it. The name is set first, and
5887N/A is created with a strdup to actually allocate memory for it. Then
5887N/A there is a case statement (roughly because strcmp requires 'ifs')
5887N/A based on what type of parameter this is. Depending which type it
5887N/A is, the value is interpreted differently, but they are relatively
5887N/A straight forward. In all cases the value is set to the default
5887N/A value from the XML and the type is set to the interpreted type.
5887N/A*/
5887N/AParameter *
5887N/AParameter::make (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext)
5887N/A{
5887N/A const char * name;
5887N/A const char * type;
5887N/A const char * guitext;
5887N/A const char * desc;
5887N/A const char * scope_str;
5887N/A Parameter::_scope_t scope = Parameter::SCOPE_USER;
5887N/A bool gui_hidden = false;
5887N/A const char * gui_hide;
5887N/A const char * gui_tip;
5887N/A
5887N/A name = in_repr->attribute("name");
5887N/A type = in_repr->attribute("type");
5887N/A guitext = in_repr->attribute("gui-text");
5887N/A if (guitext == NULL)
5887N/A guitext = in_repr->attribute("_gui-text");
5887N/A gui_tip = in_repr->attribute("gui-tip");
5887N/A if (gui_tip == NULL)
5887N/A gui_tip = in_repr->attribute("_gui-tip");
5887N/A desc = in_repr->attribute("gui-description");
5887N/A if (desc == NULL)
5887N/A desc = in_repr->attribute("_gui-description");
5887N/A scope_str = in_repr->attribute("scope");
5887N/A gui_hide = in_repr->attribute("gui-hidden");
5887N/A if (gui_hide != NULL) {
5887N/A if (strcmp(gui_hide, "1") == 0 ||
5887N/A strcmp(gui_hide, "true") == 0) {
5887N/A gui_hidden = true;
5887N/A }
5887N/A /* else stays false */
5887N/A }
5887N/A const gchar* appearance = in_repr->attribute("appearance");
5887N/A
5887N/A /* In this case we just don't have enough information */
5887N/A if (name == NULL || type == NULL) {
5887N/A return NULL;
5887N/A }
5887N/A
5887N/A if (scope_str != NULL) {
5887N/A if (!strcmp(scope_str, "user")) {
5887N/A scope = Parameter::SCOPE_USER;
5887N/A } else if (!strcmp(scope_str, "document")) {
5887N/A scope = Parameter::SCOPE_DOCUMENT;
5887N/A } else if (!strcmp(scope_str, "node")) {
5887N/A scope = Parameter::SCOPE_NODE;
5887N/A }
5887N/A }
5887N/A
5887N/A Parameter * param = NULL;
5887N/A if (!strcmp(type, "boolean")) {
5887N/A param = new ParamBool(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
5887N/A } else if (!strcmp(type, "int")) {
5887N/A param = new ParamInt(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
5887N/A } else if (!strcmp(type, "float")) {
5887N/A param = new ParamFloat(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
5887N/A } else if (!strcmp(type, "string")) {
5887N/A param = new ParamString(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
5887N/A const gchar * max_length = in_repr->attribute("max_length");
5887N/A if (max_length != NULL) {
5887N/A ParamString * ps = dynamic_cast<ParamString *>(param);
5887N/A ps->setMaxLength(atoi(max_length));
5887N/A }
5887N/A } else if (!strcmp(type, "description")) {
5887N/A param = new ParamDescription(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
5887N/A } else if (!strcmp(type, "enum")) {
5887N/A param = new ParamComboBox(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
5887N/A } else if (!strcmp(type, "notebook")) {
5887N/A param = new ParamNotebook(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
5887N/A } else if (!strcmp(type, "optiongroup")) {
5887N/A if (appearance && !strcmp(appearance, "minimal")) {
5887N/A param = new ParamRadioButton(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr, ParamRadioButton::MINIMAL);
5887N/A } else {
5887N/A param = new ParamRadioButton(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr, ParamRadioButton::FULL);
5887N/A }
5887N/A } else if (!strcmp(type, "color")) {
5887N/A param = new ParamColor(name, guitext, desc, scope, gui_hidden, gui_tip, in_ext, in_repr);
5887N/A }
5887N/A
5887N/A /* Note: param could equal NULL */
5887N/A return param;
5887N/A}
5887N/A
5887N/A
5887N/A
5887N/A/** \brief Wrapper to cast to the object and use it's function. */
5887N/Abool
5887N/AParameter::get_bool (const SPDocument * doc, const Inkscape::XML::Node * node)
5887N/A{
ParamBool * boolpntr = dynamic_cast<ParamBool *>(this);
if (boolpntr == NULL)
throw Extension::param_not_bool_param();
return boolpntr->get(doc, node);
}
/** \brief Wrapper to cast to the object and use it's function. */
int
Parameter::get_int (const SPDocument * doc, const Inkscape::XML::Node * node)
{
ParamInt * intpntr = dynamic_cast<ParamInt *>(this);
if (intpntr == NULL)
throw Extension::param_not_int_param();
return intpntr->get(doc, node);
}
/** \brief Wrapper to cast to the object and use it's function. */
float
Parameter::get_float (const SPDocument * doc, const Inkscape::XML::Node * node)
{
ParamFloat * floatpntr = dynamic_cast<ParamFloat *>(this);
if (floatpntr == NULL)
throw Extension::param_not_float_param();
return floatpntr->get(doc, node);
}
/** \brief Wrapper to cast to the object and use it's function. */
const gchar *
Parameter::get_string (const SPDocument * doc, const Inkscape::XML::Node * node)
{
ParamString * stringpntr = dynamic_cast<ParamString *>(this);
if (stringpntr == NULL)
throw Extension::param_not_string_param();
return stringpntr->get(doc, node);
}
/** \brief Wrapper to cast to the object and use it's function. */
const gchar *
Parameter::get_enum (const SPDocument * doc, const Inkscape::XML::Node * node)
{
ParamComboBox * param = dynamic_cast<ParamComboBox *>(this);
if (param == NULL)
throw Extension::param_not_enum_param();
return param->get(doc, node);
}
guint32
Parameter::get_color(const SPDocument* doc, const Inkscape::XML::Node* node)
{
ParamColor* param = dynamic_cast<ParamColor *>(this);
if (param == NULL)
throw Extension::param_not_color_param();
return param->get(doc, node);
}
/** \brief Wrapper to cast to the object and use it's function. */
bool
Parameter::set_bool (bool in, SPDocument * doc, Inkscape::XML::Node * node)
{
ParamBool * boolpntr = dynamic_cast<ParamBool *>(this);
if (boolpntr == NULL)
throw Extension::param_not_bool_param();
return boolpntr->set(in, doc, node);
}
/** \brief Wrapper to cast to the object and use it's function. */
int
Parameter::set_int (int in, SPDocument * doc, Inkscape::XML::Node * node)
{
ParamInt * intpntr = dynamic_cast<ParamInt *>(this);
if (intpntr == NULL)
throw Extension::param_not_int_param();
return intpntr->set(in, doc, node);
}
/** \brief Wrapper to cast to the object and use it's function. */
float
Parameter::set_float (float in, SPDocument * doc, Inkscape::XML::Node * node)
{
ParamFloat * floatpntr;
floatpntr = dynamic_cast<ParamFloat *>(this);
if (floatpntr == NULL)
throw Extension::param_not_float_param();
return floatpntr->set(in, doc, node);
}
/** \brief Wrapper to cast to the object and use it's function. */
const gchar *
Parameter::set_string (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node)
{
ParamString * stringpntr = dynamic_cast<ParamString *>(this);
if (stringpntr == NULL)
throw Extension::param_not_string_param();
return stringpntr->set(in, doc, node);
}
/** \brief Wrapper to cast to the object and use it's function. */
guint32
Parameter::set_color (guint32 in, SPDocument * doc, Inkscape::XML::Node * node)
{
ParamColor* param = dynamic_cast<ParamColor *>(this);
if (param == NULL)
throw Extension::param_not_color_param();
return param->set(in, doc, node);
}
/** \brief Oop, now that we need a parameter, we need it's name. */
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) :
extension(ext), _name(NULL), _desc(NULL), _scope(scope), _text(NULL), _gui_hidden(gui_hidden), _gui_tip(NULL)
{
if (name != NULL) {
_name = g_strdup(name);
}
if (desc != NULL) {
_desc = g_strdup(desc);
// printf("Adding description: '%s' on '%s'\n", _desc, _name);
}
if (gui_tip != NULL) {
_gui_tip = g_strdup(gui_tip);
}
if (guitext != NULL)
_text = g_strdup(guitext);
else
_text = g_strdup(name);
return;
}
/** \brief Just free the allocated name. */
Parameter::~Parameter (void)
{
g_free(_name);
g_free(_text);
g_free(_gui_tip);
}
/** \brief Build the name to write the parameter from the extension's
ID and the name of this parameter. */
gchar *
Parameter::pref_name (void)
{
return g_strdup_printf("%s.%s", extension->get_id(), _name);
}
Inkscape::XML::Node *
Parameter::find_child (Inkscape::XML::Node * adult)
{
return sp_repr_lookup_child(adult, "name", _name);
}
Inkscape::XML::Node *
Parameter::new_child (Inkscape::XML::Node * parent)
{
Inkscape::XML::Node * retval;
retval = parent->document()->createElement("inkscape:extension-param");
retval->setAttribute("name", _name);
parent->appendChild(retval);
Inkscape::GC::release(retval);
return retval;
}
Inkscape::XML::Node *
Parameter::document_param_node (SPDocument * doc)
{
Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
Inkscape::XML::Node * defs = SP_OBJECT_REPR(SP_DOCUMENT_DEFS(doc));
Inkscape::XML::Node * params = NULL;
GQuark const name_quark = g_quark_from_string("inkscape:extension-params");
for (Inkscape::XML::Node * child = defs->firstChild();
child != NULL;
child = child->next()) {
if ((GQuark)child->code() == name_quark &&
!strcmp(child->attribute("extension"), extension->get_id())) {
params = child;
break;
}
}
if (params == NULL) {
params = xml_doc->createElement("inkscape:extension-param");
params->setAttribute("extension", extension->get_id());
defs->appendChild(params);
Inkscape::GC::release(params);
}
return params;
}
/** \brief Basically, if there is no widget pass a NULL. */
Gtk::Widget *
Parameter::get_widget (SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/, sigc::signal<void> * /*changeSignal*/)
{
return NULL;
}
/** \brief If I'm not sure which it is, just don't return a value. */
void
Parameter::string (std::string &/*string*/)
{
return;
}
void
Parameter::string (std::list <std::string> &list)
{
std::string value;
string(value);
if (value == "") {
return;
}
std::string final;
final += "--";
final += name();
final += "=";
final += value;
list.insert(list.end(), final);
return;
}
Glib::ustring const extension_pref_root = "/extensions/";
} /* namespace Extension */
} /* namespace Inkscape */
/*
Local Variables:
mode:c++
c-file-style:"stroustrup"
c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
indent-tabs-mode:nil
fill-column:99
End:
*/
// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :