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