summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: de654a4)
raw | patch | inline | side by side (parent: de654a4)
author | johanengelen <johanengelen@users.sourceforge.net> | |
Thu, 14 Sep 2006 22:14:19 +0000 (22:14 +0000) | ||
committer | johanengelen <johanengelen@users.sourceforge.net> | |
Thu, 14 Sep 2006 22:14:19 +0000 (22:14 +0000) |
src/extension/parameter.cpp | patch | blob | history | |
src/extension/paramnotebook.cpp | [new file with mode: 0644] | patch | blob |
src/extension/paramnotebook.h | [new file with mode: 0644] | patch | blob |
index a034022d9f8a5b2413626569ffa86d35ad516010..a821a626dfec18909790205504af6d35b1496974 100644 (file)
*/
/*
- * Authors:
+ * Author:
* Ted Gould <ted@gould.cx>
*
- * Copyright (C) 2005-2006 Authors
+ * Copyright (C) 2006 Johan Engelen <johan@shouraizou.nl>
+ * Copyright (C) 2005-2006 Author
*
* Released under GNU GPL, read the file 'COPYING' for more information
*/
#include "sp-object.h"
#include "parameter.h"
+#include "paramnotebook.h"
/** \brief The root directory in the preferences database for extension
related parameters. */
Glib::ustring * string (void);
}; /* class ParamEnum */
+
/**
\return None
\brief This function creates a parameter that can be used later. This
@@ -310,6 +313,8 @@ Parameter::make (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension *
param = new ParamDescription(name, guitext, desc, scope, in_ext, in_repr);
} else if (!strcmp(type, "enum")) {
param = new ParamEnum(name, guitext, desc, scope, in_ext, in_repr);
+ } else if (!strcmp(type, "notebook")) {
+ param = new ParamNotebook(name, guitext, desc, scope, in_ext, in_repr);
}
/* Note: param could equal NULL */
diff --git a/src/extension/paramnotebook.cpp b/src/extension/paramnotebook.cpp
--- /dev/null
@@ -0,0 +1,431 @@
+/** \file\r
+ * Notebook and NotebookPage parameters for extensions.\r
+ */\r
+\r
+/*\r
+ * Author:\r
+ * Johan Engelen <johan@shouraizou.nl>\r
+ *\r
+ * Copyright (C) 2006 Author\r
+ *\r
+ * Released under GNU GPL, read the file 'COPYING' for more information\r
+ */\r
+\r
+#ifdef HAVE_CONFIG_H\r
+# include "config.h"\r
+#endif\r
+\r
+\r
+#include <gtkmm/adjustment.h>\r
+#include <gtkmm/box.h>\r
+#include <gtkmm/spinbutton.h>\r
+#include <gtkmm/notebook.h>\r
+#include <gtkmm/tooltips.h>\r
+\r
+#include <glibmm/i18n.h>\r
+\r
+#include <xml/node.h>\r
+\r
+#include "extension.h"\r
+#include "prefs-utils.h"\r
+#include "document-private.h"\r
+#include "sp-object.h"\r
+\r
+#include "paramnotebook.h"\r
+\r
+/** \brief The root directory in the preferences database for extension\r
+ related parameters. */\r
+#define PREF_DIR "extensions"\r
+\r
+namespace Inkscape {\r
+namespace Extension {\r
+\r
+\r
+// \brief A class to represent the pages of a notebookparameter of an extension\r
+class ParamNotebookPage : public Parameter {\r
+private:\r
+ GSList * parameters; /**< A table to store the parameters for this page.\r
+ This only gets created if there are parameters on this\r
+ page */\r
+ Gtk::Tooltips _tooltips;\r
+ \r
+public:\r
+ static ParamNotebookPage * makepage (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext);\r
+\r
+ ParamNotebookPage(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);\r
+ ~ParamNotebookPage(void);\r
+ Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);\r
+ Glib::ustring * paramString (void);\r
+ gchar * get_guitext (void) {return _text;};\r
+ \r
+}; /* class ParamNotebookPage */\r
+\r
+\r
+ParamNotebookPage::ParamNotebookPage (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :\r
+ Parameter(name, guitext, desc, scope, ext)\r
+{\r
+ parameters = NULL;\r
+ \r
+ // Read XML to build page\r
+ if (xml != NULL) {\r
+ Inkscape::XML::Node *child_repr = sp_repr_children(xml);\r
+ while (child_repr != NULL) {\r
+ char const * chname = child_repr->name();\r
+ if (chname[0] == '_') /* Allow _ for translation of tags */\r
+ chname++;\r
+ if (!strcmp(chname, "param") || !strcmp(chname, "_param")) {\r
+ Parameter * param;\r
+ param = Parameter::make(child_repr, ext);\r
+ if (param != NULL)\r
+ parameters = g_slist_append(parameters, param);\r
+ }\r
+ child_repr = sp_repr_next(child_repr);\r
+ }\r
+ }\r
+ \r
+ return;\r
+}\r
+\r
+ParamNotebookPage::~ParamNotebookPage (void)\r
+{\r
+ //destroy parameters\r
+ for (GSList * list = parameters; list != NULL; list = g_slist_next(list)) {\r
+ Parameter * param = reinterpret_cast<Parameter *>(list->data);\r
+ delete param;\r
+ }\r
+ g_slist_free(parameters);\r
+}\r
+\r
+/** \brief Return the value as a string */\r
+Glib::ustring *\r
+ParamNotebookPage::paramString (void)\r
+{\r
+ Glib::ustring * param_string = new Glib::ustring("");\r
+\r
+ for (GSList * list = parameters; list != NULL; list = g_slist_next(list)) {\r
+ Parameter * param = reinterpret_cast<Parameter *>(list->data);\r
+\r
+ *param_string += " --";\r
+ *param_string += param->name();\r
+ *param_string += "=";\r
+ Glib::ustring * paramstr = param->string();\r
+ *param_string += *paramstr;\r
+ delete paramstr;\r
+ }\r
+\r
+ return param_string;\r
+}\r
+\r
+\r
+/**\r
+ \return None\r
+ \brief This function creates a page that can be used later. This\r
+ is typically done in the creation of the notebook and defined\r
+ in the XML file describing the extension (it's private so people\r
+ have to use the system) :)\r
+ \param in_repr The XML describing the page\r
+\r
+ This function first grabs all of the data out of the Repr and puts\r
+ it into local variables. Actually, these are just pointers, and the\r
+ data is not duplicated so we need to be careful with it. If there\r
+ isn't a name in the XML, then no page is created as\r
+ the function just returns.\r
+\r
+ From this point on, we're pretty committed as we've allocated an\r
+ object and we're starting to fill it. The name is set first, and\r
+ is created with a strdup to actually allocate memory for it. Then\r
+ there is a case statement (roughly because strcmp requires 'ifs')\r
+ based on what type of parameter this is. Depending which type it\r
+ is, the value is interpreted differently, but they are relatively\r
+ straight forward. In all cases the value is set to the default\r
+ value from the XML and the type is set to the interpreted type.\r
+*/\r
+ParamNotebookPage *\r
+ParamNotebookPage::makepage (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext)\r
+{\r
+ const char * name;\r
+ const char * guitext;\r
+ const char * desc;\r
+ const char * scope_str;\r
+ Parameter::_scope_t scope = Parameter::SCOPE_USER;\r
+\r
+ name = in_repr->attribute("name");\r
+ guitext = in_repr->attribute("gui-text");\r
+ if (guitext == NULL)\r
+ guitext = in_repr->attribute("_gui-text");\r
+ desc = in_repr->attribute("gui-description");\r
+ if (desc == NULL)\r
+ desc = in_repr->attribute("_gui-description");\r
+ scope_str = in_repr->attribute("scope");\r
+\r
+ /* In this case we just don't have enough information */\r
+ if (name == NULL) {\r
+ return NULL;\r
+ }\r
+\r
+ if (scope_str != NULL) {\r
+ if (!strcmp(scope_str, "user")) {\r
+ scope = Parameter::SCOPE_USER;\r
+ } else if (!strcmp(scope_str, "document")) {\r
+ scope = Parameter::SCOPE_DOCUMENT;\r
+ } else if (!strcmp(scope_str, "node")) {\r
+ scope = Parameter::SCOPE_NODE;\r
+ }\r
+ }\r
+\r
+ ParamNotebookPage * page = new ParamNotebookPage(name, guitext, desc, scope, in_ext, in_repr);\r
+ \r
+ /* Note: page could equal NULL */\r
+ return page;\r
+}\r
+\r
+\r
+\r
+/**\r
+ \brief Creates a notebookpage widget for a notebook\r
+\r
+ Builds a notebook page (a vbox) and puts parameters on it.\r
+*/\r
+Gtk::Widget *\r
+ParamNotebookPage::get_widget (SPDocument * doc, Inkscape::XML::Node * node)\r
+{\r
+ Gtk::VBox * vbox = Gtk::manage(new Gtk::VBox);\r
+ vbox->set_border_width(5); \r
+ \r
+ // add parameters onto page (if any) \r
+ for (GSList * list = parameters; list != NULL; list = g_slist_next(list)) {\r
+ Parameter * param = reinterpret_cast<Parameter *>(list->data);\r
+ Gtk::Widget * widg = param->get_widget(doc, node);\r
+ gchar const * tip = param->get_tooltip();\r
+ \r
+ vbox->pack_start(*widg, true, true, 2);\r
+ if (tip != NULL) {\r
+ _tooltips.set_tip(*widg, Glib::ustring(tip));\r
+ // printf("Setting tooltip: %s\n", tooltip);\r
+ }\r
+ }\r
+ \r
+ vbox->show();\r
+ \r
+ return dynamic_cast<Gtk::Widget *>(vbox);\r
+}\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+\r
+ParamNotebook::ParamNotebook (const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml) :\r
+ Parameter(name, guitext, desc, scope, ext)\r
+{\r
+ pages = NULL;\r
+ \r
+ // Read XML tree to add pages:\r
+ // printf("Extension Constructor: ");\r
+ if (xml != NULL) {\r
+ Inkscape::XML::Node *child_repr = sp_repr_children(xml);\r
+ while (child_repr != NULL) {\r
+ char const * chname = child_repr->name();\r
+ if (chname[0] == '_') /* Allow _ for translation of tags */\r
+ chname++;\r
+ if (!strcmp(chname, "page")) {\r
+ ParamNotebookPage * page;\r
+ page = ParamNotebookPage::makepage(child_repr, ext);\r
+ if (page != NULL) pages = g_slist_append(pages, page);\r
+ }\r
+ child_repr = sp_repr_next(child_repr);\r
+ }\r
+ }\r
+ \r
+ // Initialize _value with the current page\r
+ const char * defaultval = NULL;\r
+ // set first page as default\r
+ if (pages != NULL) {\r
+ ParamNotebookPage * defpage = reinterpret_cast<ParamNotebookPage *>(pages->data);\r
+ defaultval = defpage->name();\r
+ }\r
+\r
+ gchar * pref_name = this->pref_name();\r
+ const gchar * paramval = prefs_get_string_attribute(PREF_DIR, pref_name);\r
+ g_free(pref_name);\r
+\r
+ if (paramval != NULL)\r
+ defaultval = paramval;\r
+ if (defaultval != NULL)\r
+ _value = g_strdup(defaultval); // allocate space for _value\r
+ \r
+ return;\r
+}\r
+\r
+ParamNotebook::~ParamNotebook (void)\r
+{\r
+ //destroy pages\r
+ for (GSList * list = pages; list != NULL; list = g_slist_next(list)) {\r
+ ParamNotebookPage * page = reinterpret_cast<ParamNotebookPage *>(list->data);\r
+ delete page;\r
+ }\r
+ g_slist_free(pages);\r
+\r
+ g_free(_value);\r
+}\r
+\r
+\r
+/** \brief A function to set the \c _value\r
+ \param in The number of the page which value must be set\r
+ \param doc A document that should be used to set the value.\r
+ \param node The node where the value may be placed\r
+\r
+ This function sets the internal value, but it also sets the value\r
+ in the preferences structure. To put it in the right place, \c PREF_DIR\r
+ and \c pref_name() are used.\r
+\r
+ To copy the data into _value the old memory must be free'd first.\r
+ It is important to note that \c g_free handles \c NULL just fine. Then\r
+ the passed in value is duplicated using \c g_strdup().\r
+*/\r
+const gchar *\r
+ParamNotebook::set (const int in, SPDocument * doc, Inkscape::XML::Node * node)\r
+{\r
+ ParamNotebookPage * page = NULL;\r
+ int i = 0;\r
+ for (GSList * list = pages; (list != NULL) && (i <= in); list = g_slist_next(list)) {\r
+ page = reinterpret_cast<ParamNotebookPage *>(list->data);\r
+ i++;\r
+ }\r
+ \r
+ if (page == NULL) return _value;\r
+ \r
+ if (_value != NULL) g_free(_value);\r
+ _value = g_strdup(page->name());\r
+\r
+ gchar * prefname = this->pref_name();\r
+ prefs_set_string_attribute(PREF_DIR, prefname, _value);\r
+ g_free(prefname);\r
+\r
+ return _value;\r
+}\r
+\r
+\r
+/**\r
+ \brief A function to get the currentpage and the parameters in a string form\r
+ \return A string with the 'value' and all the parameters on all pages as command line arguments\r
+\r
+ This is really a hack. The function is called by Extension::paramString() to build\r
+ the commandline string like: '--param1name=\"param1value\" --param2name=\"param2value\" ...'\r
+ Extension::paramString expects this function to return '\"param1value\"'; but instead, \r
+ this function returns: '\"param1value\" --page1param1name=\"page1param1value\" ...'\r
+\r
+ \TODO Do this better. For example, make Parameter::paramString() that returns '--name=\"value\"'\r
+ instead of just returning '\"value\"'.\r
+*/\r
+Glib::ustring *\r
+ParamNotebook::string (void)\r
+{\r
+ Glib::ustring * param_string = new Glib::ustring("");\r
+\r
+ *param_string += "\"";\r
+ *param_string += _value; // the name of the current page\r
+ *param_string += "\"";\r
+\r
+ for (GSList * list = pages; list != NULL; list = g_slist_next(list)) {\r
+ ParamNotebookPage * page = reinterpret_cast<ParamNotebookPage *>(list->data);\r
+\r
+ Glib::ustring * pageparamstr = page->paramString();\r
+ *param_string += *pageparamstr;\r
+ delete pageparamstr;\r
+ }\r
+ \r
+ // this function is called when the user pressed OK. This means the dialog will close\r
+ // very soon, and we should deactivate the 'switch-page' hook, so the last page is remembered.\r
+ \r
+\r
+ return param_string;\r
+}\r
+\r
+/** \brief A special category of Gtk::Notebook to handle notebook parameters */\r
+class ParamNotebookWdg : public Gtk::Notebook {\r
+private:\r
+ ParamNotebook * _pref;\r
+ SPDocument * _doc;\r
+ Inkscape::XML::Node * _node;\r
+public:\r
+ /** \brief Build a notebookpage preference for the given parameter\r
+ \param pref Where to get the string (pagename) from, and where to put it\r
+ when it changes.\r
+ */\r
+ ParamNotebookWdg (ParamNotebook * pref, SPDocument * doc, Inkscape::XML::Node * node) :\r
+ Gtk::Notebook(), _pref(pref), _doc(doc), _node(node), activated(false) {\r
+ // don't have to set the correct page: this is done in ParamNotebook::get_widget.\r
+ // hook function\r
+ this->signal_switch_page().connect(sigc::mem_fun(this, &ParamNotebookWdg::changed_page));\r
+ return;\r
+ };\r
+ void changed_page(GtkNotebookPage *page, guint pagenum);\r
+ bool activated;\r
+};\r
+\r
+/** \brief Respond to the selected page of notebook changing\r
+ This function responds to the changing by reporting it to\r
+ ParamNotebook. The change is only reported when the notebook\r
+ is actually visible. This to exclude 'fake' changes when the\r
+ notebookpages are added or removed.\r
+*/\r
+void\r
+ParamNotebookWdg::changed_page(GtkNotebookPage *page,\r
+ guint pagenum)\r
+{\r
+ if (is_visible()) {\r
+ _pref->set((int)pagenum, _doc, _node);\r
+ }\r
+ return;\r
+}\r
+\r
+\r
+\r
+/**\r
+ \brief Creates a Notebook widget for a notebook parameter\r
+\r
+ Builds a notebook and puts pages in it.\r
+*/\r
+Gtk::Widget *\r
+ParamNotebook::get_widget (SPDocument * doc, Inkscape::XML::Node * node)\r
+{\r
+ ParamNotebookWdg * nb = Gtk::manage(new ParamNotebookWdg(this, doc, node));\r
+\r
+ // add pages (if any) \r
+ int i = -1;\r
+ int pagenr = i;\r
+ for (GSList * list = pages; list != NULL; list = g_slist_next(list)) {\r
+ i++; \r
+ ParamNotebookPage * page = reinterpret_cast<ParamNotebookPage *>(list->data);\r
+ Gtk::Widget * widg = page->get_widget(doc, node);\r
+ nb->append_page(*widg, _(page->get_guitext()));\r
+ if (!strcmp(_value, page->name())) {\r
+ pagenr = i; // this is the page to be displayed?\r
+ }\r
+ }\r
+\r
+ nb->show();\r
+ \r
+ if (pagenr >= 0) nb->set_current_page(pagenr);\r
+\r
+ return dynamic_cast<Gtk::Widget *>(nb);\r
+}\r
+\r
+\r
+} /* namespace Extension */\r
+} /* namespace Inkscape */\r
+\r
+/*\r
+ Local Variables:\r
+ mode:c++\r
+ c-file-style:"stroustrup"\r
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
+ indent-tabs-mode:nil\r
+ fill-column:99\r
+ End:\r
+*/\r
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r
diff --git a/src/extension/paramnotebook.h b/src/extension/paramnotebook.h
--- /dev/null
@@ -0,0 +1,68 @@
+#ifndef __INK_EXTENSION_PARAMNOTEBOOK_H__\r
+#define __INK_EXTENSION_PARAMNOTEBOOK_H__\r
+\r
+/** \file\r
+ * Notebook parameter for extensions.\r
+ */\r
+\r
+/*\r
+ * Author:\r
+ * Johan Engelen <johan@shouraizou.nl>\r
+ *\r
+ * Copyright (C) 2006 Author\r
+ *\r
+ * Released under GNU GPL, read the file 'COPYING' for more information\r
+ */\r
+\r
+#include <gtkmm/widget.h>\r
+\r
+#include "xml/document.h"\r
+#include "extension-forward.h"\r
+\r
+#include "parameter.h"\r
+\r
+namespace Inkscape {\r
+namespace Extension {\r
+\r
+\r
+\r
+// \brief A class to represent a notebookparameter of an extension\r
+class ParamNotebook : public Parameter {\r
+private:\r
+ /** \brief Internal value. This should point to a string that has\r
+ been allocated in memory. And should be free'd. \r
+ It is the name of the current page. */\r
+ gchar * _value;\r
+ \r
+ GSList * pages; /**< A table to store the pages with parameters for this notebook.\r
+ This only gets created if there are pages in this\r
+ notebook */\r
+public:\r
+ ParamNotebook(const gchar * name, const gchar * guitext, const gchar * desc, const Parameter::_scope_t scope, Inkscape::Extension::Extension * ext, Inkscape::XML::Node * xml);\r
+ ~ParamNotebook(void);\r
+ Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node);\r
+ Glib::ustring * string (void);\r
+ \r
+ const gchar * get (const SPDocument * doc, const Inkscape::XML::Node * node) { return _value; }\r
+ const gchar * set (const int in, SPDocument * doc, Inkscape::XML::Node * node);\r
+}; /* class ParamNotebook */\r
+\r
+\r
+\r
+\r
+\r
+} /* namespace Extension */\r
+} /* namespace Inkscape */\r
+\r
+#endif /* __INK_EXTENSION_PARAMNOTEBOOK_H__ */\r
+\r
+/*\r
+ Local Variables:\r
+ mode:c++\r
+ c-file-style:"stroustrup"\r
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))\r
+ indent-tabs-mode:nil\r
+ fill-column:99\r
+ End:\r
+*/\r
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :\r