From 7311f3ac5161a4d53cf2ed7e0a5a97993f646321 Mon Sep 17 00:00:00 2001 From: Patrick Storz Date: Sun, 21 Jul 2019 15:24:05 +0200 Subject: Move prefdialog to own directory --- src/extension/CMakeLists.txt | 47 +-- src/extension/effect.cpp | 13 +- src/extension/execution-env.cpp | 2 +- src/extension/extension.cpp | 2 +- src/extension/input.cpp | 2 +- src/extension/output.cpp | 2 +- src/extension/param/bool.cpp | 154 --------- src/extension/param/bool.h | 95 ----- src/extension/param/color.cpp | 119 ------- src/extension/param/color.h | 74 ---- src/extension/param/description.cpp | 134 ------- src/extension/param/description.h | 63 ---- src/extension/param/enum.cpp | 268 -------------- src/extension/param/enum.h | 106 ------ src/extension/param/float.cpp | 205 ----------- src/extension/param/float.h | 83 ----- src/extension/param/int.cpp | 201 ----------- src/extension/param/int.h | 80 ----- src/extension/param/notebook.cpp | 413 ---------------------- src/extension/param/notebook.h | 117 ------- src/extension/param/parameter.cpp | 461 ------------------------- src/extension/param/parameter.h | 219 ------------ src/extension/param/radiobutton.cpp | 349 ------------------- src/extension/param/radiobutton.h | 107 ------ src/extension/param/string.cpp | 181 ---------- src/extension/param/string.h | 67 ---- src/extension/prefdialog.cpp | 276 --------------- src/extension/prefdialog.h | 94 ----- src/extension/prefdialog/param/bool.cpp | 154 +++++++++ src/extension/prefdialog/param/bool.h | 95 +++++ src/extension/prefdialog/param/color.cpp | 119 +++++++ src/extension/prefdialog/param/color.h | 74 ++++ src/extension/prefdialog/param/description.cpp | 134 +++++++ src/extension/prefdialog/param/description.h | 63 ++++ src/extension/prefdialog/param/enum.cpp | 268 ++++++++++++++ src/extension/prefdialog/param/enum.h | 106 ++++++ src/extension/prefdialog/param/float.cpp | 205 +++++++++++ src/extension/prefdialog/param/float.h | 83 +++++ src/extension/prefdialog/param/int.cpp | 201 +++++++++++ src/extension/prefdialog/param/int.h | 80 +++++ src/extension/prefdialog/param/notebook.cpp | 413 ++++++++++++++++++++++ src/extension/prefdialog/param/notebook.h | 117 +++++++ src/extension/prefdialog/param/parameter.cpp | 461 +++++++++++++++++++++++++ src/extension/prefdialog/param/parameter.h | 219 ++++++++++++ src/extension/prefdialog/param/radiobutton.cpp | 349 +++++++++++++++++++ src/extension/prefdialog/param/radiobutton.h | 107 ++++++ src/extension/prefdialog/param/string.cpp | 181 ++++++++++ src/extension/prefdialog/param/string.h | 67 ++++ src/extension/prefdialog/prefdialog.cpp | 277 +++++++++++++++ src/extension/prefdialog/prefdialog.h | 94 +++++ 50 files changed, 3902 insertions(+), 3899 deletions(-) delete mode 100644 src/extension/param/bool.cpp delete mode 100644 src/extension/param/bool.h delete mode 100644 src/extension/param/color.cpp delete mode 100644 src/extension/param/color.h delete mode 100644 src/extension/param/description.cpp delete mode 100644 src/extension/param/description.h delete mode 100644 src/extension/param/enum.cpp delete mode 100644 src/extension/param/enum.h delete mode 100644 src/extension/param/float.cpp delete mode 100644 src/extension/param/float.h delete mode 100644 src/extension/param/int.cpp delete mode 100644 src/extension/param/int.h delete mode 100644 src/extension/param/notebook.cpp delete mode 100644 src/extension/param/notebook.h delete mode 100644 src/extension/param/parameter.cpp delete mode 100644 src/extension/param/parameter.h delete mode 100644 src/extension/param/radiobutton.cpp delete mode 100644 src/extension/param/radiobutton.h delete mode 100644 src/extension/param/string.cpp delete mode 100644 src/extension/param/string.h delete mode 100644 src/extension/prefdialog.cpp delete mode 100644 src/extension/prefdialog.h create mode 100644 src/extension/prefdialog/param/bool.cpp create mode 100644 src/extension/prefdialog/param/bool.h create mode 100644 src/extension/prefdialog/param/color.cpp create mode 100644 src/extension/prefdialog/param/color.h create mode 100644 src/extension/prefdialog/param/description.cpp create mode 100644 src/extension/prefdialog/param/description.h create mode 100644 src/extension/prefdialog/param/enum.cpp create mode 100644 src/extension/prefdialog/param/enum.h create mode 100644 src/extension/prefdialog/param/float.cpp create mode 100644 src/extension/prefdialog/param/float.h create mode 100644 src/extension/prefdialog/param/int.cpp create mode 100644 src/extension/prefdialog/param/int.h create mode 100644 src/extension/prefdialog/param/notebook.cpp create mode 100644 src/extension/prefdialog/param/notebook.h create mode 100644 src/extension/prefdialog/param/parameter.cpp create mode 100644 src/extension/prefdialog/param/parameter.h create mode 100644 src/extension/prefdialog/param/radiobutton.cpp create mode 100644 src/extension/prefdialog/param/radiobutton.h create mode 100644 src/extension/prefdialog/param/string.cpp create mode 100644 src/extension/prefdialog/param/string.h create mode 100644 src/extension/prefdialog/prefdialog.cpp create mode 100644 src/extension/prefdialog/prefdialog.h diff --git a/src/extension/CMakeLists.txt b/src/extension/CMakeLists.txt index eaa9b4956..c00111209 100644 --- a/src/extension/CMakeLists.txt +++ b/src/extension/CMakeLists.txt @@ -11,7 +11,6 @@ set(extension_SRC input.cpp output.cpp patheffect.cpp - prefdialog.cpp print.cpp system.cpp timer.cpp @@ -21,17 +20,6 @@ set(extension_SRC implementation/xslt.cpp implementation/script.cpp - param/bool.cpp - param/color.cpp - param/description.cpp - param/enum.cpp - param/float.cpp - param/int.cpp - param/notebook.cpp - param/parameter.cpp - param/radiobutton.cpp - param/string.cpp - internal/bluredge.cpp internal/cairo-ps-out.cpp internal/cairo-render-context.cpp @@ -64,6 +52,18 @@ set(extension_SRC internal/pdfinput/pdf-parser.cpp internal/pdfinput/svg-builder.cpp + prefdialog/prefdialog.cpp + prefdialog/param/bool.cpp + prefdialog/param/color.cpp + prefdialog/param/description.cpp + prefdialog/param/enum.cpp + prefdialog/param/float.cpp + prefdialog/param/int.cpp + prefdialog/param/notebook.cpp + prefdialog/param/parameter.cpp + prefdialog/param/radiobutton.cpp + prefdialog/param/string.cpp + # ------ # Header db.h @@ -75,18 +75,7 @@ set(extension_SRC init.h input.h output.h - param/bool.h - param/color.h - param/description.h - param/enum.h - param/float.h - param/int.h - param/notebook.h - param/parameter.h - param/radiobutton.h - param/string.h patheffect.h - prefdialog.h print.h system.h timer.h @@ -137,6 +126,18 @@ set(extension_SRC internal/text_reassemble.h internal/wmf-inout.h internal/wmf-print.h + + prefdialog/prefdialog.h + prefdialog/param/bool.h + prefdialog/param/color.h + prefdialog/param/description.h + prefdialog/param/enum.h + prefdialog/param/float.h + prefdialog/param/int.h + prefdialog/param/notebook.h + prefdialog/param/parameter.h + prefdialog/param/radiobutton.h + prefdialog/param/string.h ) if(WIN32) diff --git a/src/extension/effect.cpp b/src/extension/effect.cpp index 3c9940240..c10ad10bd 100644 --- a/src/extension/effect.cpp +++ b/src/extension/effect.cpp @@ -9,16 +9,17 @@ * Released under GNU GPL v2+, read the file 'COPYING' for more information. */ -#include "prefdialog.h" -#include "inkscape.h" -#include "helper/action.h" -#include "ui/view/view.h" - -#include "implementation/implementation.h" #include "effect.h" + #include "execution-env.h" +#include "inkscape.h" #include "timer.h" +#include "helper/action.h" +#include "implementation/implementation.h" +#include "prefdialog/prefdialog.h" +#include "ui/view/view.h" + /* Inkscape::Extension::Effect */ diff --git a/src/extension/execution-env.cpp b/src/extension/execution-env.cpp index ca770e1f6..a2bae3832 100644 --- a/src/extension/execution-env.cpp +++ b/src/extension/execution-env.cpp @@ -13,7 +13,7 @@ #include #include "execution-env.h" -#include "prefdialog.h" +#include "prefdialog/prefdialog.h" #include "implementation/implementation.h" #include "selection.h" diff --git a/src/extension/extension.cpp b/src/extension/extension.cpp index 77a171487..f85be2a70 100644 --- a/src/extension/extension.cpp +++ b/src/extension/extension.cpp @@ -29,7 +29,7 @@ #include "db.h" #include "dependency.h" #include "timer.h" -#include "param/parameter.h" +#include "prefdialog/param/parameter.h" #include "io/resource.h" namespace Inkscape { diff --git a/src/extension/input.cpp b/src/extension/input.cpp index 708324de2..792b794c8 100644 --- a/src/extension/input.cpp +++ b/src/extension/input.cpp @@ -11,7 +11,7 @@ #ifdef HAVE_CONFIG_H #endif -#include "prefdialog.h" +#include "prefdialog/prefdialog.h" #include "implementation/implementation.h" #include "timer.h" #include "input.h" diff --git a/src/extension/output.cpp b/src/extension/output.cpp index c6cf399b8..51d58bc89 100644 --- a/src/extension/output.cpp +++ b/src/extension/output.cpp @@ -9,7 +9,7 @@ * Released under GNU GPL v2+, read the file 'COPYING' for more information. */ -#include "prefdialog.h" +#include "prefdialog/prefdialog.h" #include "document.h" #include "implementation/implementation.h" #include "output.h" diff --git a/src/extension/param/bool.cpp b/src/extension/param/bool.cpp deleted file mode 100644 index 10121f7ab..000000000 --- a/src/extension/param/bool.cpp +++ /dev/null @@ -1,154 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2005-2007 Authors: - * Ted Gould - * Johan Engelen * - * Jon A. Cruz - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include -#include -#include -#include - -#include "xml/node.h" -#include "../extension.h" -#include "bool.h" -#include "preferences.h" - -namespace Inkscape { -namespace Extension { - -ParamBool::ParamBool(const gchar * name, - const gchar * text, - const gchar * description, - bool hidden, - int indent, - Inkscape::Extension::Extension * ext, - Inkscape::XML::Node * xml) - : Parameter(name, text, description, hidden, indent, ext) - , _value(false) -{ - const char * defaultval = nullptr; - if (xml->firstChild() != nullptr) { - defaultval = xml->firstChild()->content(); - } - - if (defaultval != nullptr && (!strcmp(defaultval, "true") || !strcmp(defaultval, "1"))) { - _value = true; - } else { - _value = false; - } - - gchar * pref_name = this->pref_name(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - _value = prefs->getBool(extension_pref_root + pref_name, _value); - g_free(pref_name); - - return; -} - -bool ParamBool::set( bool in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/ ) -{ - _value = in; - - gchar * prefname = this->pref_name(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setBool(extension_pref_root + prefname, _value); - g_free(prefname); - - return _value; -} - -bool ParamBool::get(const SPDocument * /*doc*/, const Inkscape::XML::Node * /*node*/) const -{ - return _value; -} - -/** - * A check button which is Param aware. It works with the - * parameter to change it's value as the check button changes - * value. - */ -class ParamBoolCheckButton : public Gtk::CheckButton { -public: - /** - * Initialize the check button. - * This function sets the value of the checkbox to be that of the - * parameter, and then sets up a callback to \c on_toggle. - * - * @param param Which parameter to adjust on changing the check button - */ - ParamBoolCheckButton (ParamBool * param, gchar * label, SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) : - Gtk::CheckButton(label), _pref(param), _doc(doc), _node(node), _changeSignal(changeSignal) { - this->set_active(_pref->get(nullptr, nullptr) /**\todo fix */); - this->signal_toggled().connect(sigc::mem_fun(this, &ParamBoolCheckButton::on_toggle)); - return; - } - - /** - * A function to respond to the check box changing. - * Adjusts the value of the preference to match that in the check box. - */ - void on_toggle (); - -private: - /** Param to change. */ - ParamBool * _pref; - SPDocument * _doc; - Inkscape::XML::Node * _node; - sigc::signal * _changeSignal; -}; - -void ParamBoolCheckButton::on_toggle() -{ - _pref->set(this->get_active(), nullptr /**\todo fix this */, nullptr); - if (_changeSignal != nullptr) { - _changeSignal->emit(); - } - return; -} - -void ParamBool::string(std::string &string) const -{ - if (_value) { - string += "true"; - } else { - string += "false"; - } - - return; -} - -Gtk::Widget *ParamBool::get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) -{ - if (_hidden) { - return nullptr; - } - - auto hbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, Parameter::GUI_PARAM_WIDGETS_SPACING)); - hbox->set_homogeneous(false); - - ParamBoolCheckButton * checkbox = Gtk::manage(new ParamBoolCheckButton(this, _text, doc, node, changeSignal)); - checkbox->show(); - hbox->pack_start(*checkbox, false, false); - - hbox->show(); - - return dynamic_cast(hbox); -} - -} /* 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/extension/param/bool.h b/src/extension/param/bool.h deleted file mode 100644 index 9864cac38..000000000 --- a/src/extension/param/bool.h +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -#ifndef SEEN_INK_EXTENSION_PARAMBOOL_H -#define SEEN_INK_EXTENSION_PARAMBOOL_H -/* - * Copyright (C) 2005-2007 Authors: - * Ted Gould - * Johan Engelen * - * Jon A. Cruz - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include "parameter.h" - -class SPDocument; - -namespace Gtk { -class Widget; -} - -namespace Inkscape { -namespace XML { -class Node; -} - -namespace Extension { - -/** - * A boolean parameter. - */ -class ParamBool : public Parameter { -public: - - /** - * Use the superclass' allocator and set the \c _value. - */ - ParamBool(const gchar * name, - const gchar * text, - const gchar * description, - bool hidden, - int indent, - Inkscape::Extension::Extension * ext, - Inkscape::XML::Node * xml); - - /** - * Returns the current state/value. - */ - bool get(const SPDocument *doc, const Inkscape::XML::Node *node) const; - - /** - * A function to set the state/value. - * 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. - * - * @param in The value to set to - * @param doc A document that should be used to set the value. - * @param node The node where the value may be placed - */ - bool set(bool in, SPDocument * doc, Inkscape::XML::Node * node); - - /** - * Creates a bool check button for a bool parameter. - * Builds a hbox with a label and a check button in it. - */ - Gtk::Widget *get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) override; - - // Explicitly call superclass version to avoid method being hidden. - void string(std::list &list) const override { return Parameter::string(list); } - - /** - * Appends 'true' or 'false'. - * @todo investigate. Returning a value that can then be appended would probably work better/safer. - */ - void string(std::string &string) const override; - -private: - /** Internal value. */ - bool _value; -}; - -} // namespace Extension -} // namespace Inkscape - -#endif // SEEN_INK_EXTENSION_PARAMBOOL_H - -/* - 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 : diff --git a/src/extension/param/color.cpp b/src/extension/param/color.cpp deleted file mode 100644 index f71670cb2..000000000 --- a/src/extension/param/color.cpp +++ /dev/null @@ -1,119 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2005-2007 Authors: - * Ted Gould - * Johan Engelen - * Christopher Brown - * Jon A. Cruz - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include -#include - -#include -#include -#include - -#include - -#include "../extension.h" -#include "color.h" - -#include -#include "ui/widget/color-notebook.h" -#include "preferences.h" - -namespace Inkscape { -namespace Extension { - -ParamColor::~ParamColor() -{ - _color_changed.disconnect(); -} - -guint32 ParamColor::set( guint32 in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/ ) -{ - _color_changed.block(true); - _color.setValue(in); - _color_changed.block(false); - - gchar * prefname = this->pref_name(); - std::string value; - string(value); - - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setString(extension_pref_root + prefname, value); - g_free(prefname); - - return in; -} - -ParamColor::ParamColor(const gchar * name, - const gchar * text, - const gchar * description, - bool hidden, - int indent, - Inkscape::Extension::Extension * ext, - Inkscape::XML::Node * xml) - : Parameter(name, text, description, hidden, indent, ext) - , _changeSignal(nullptr) -{ - const char * defaulthex = nullptr; - if (xml->firstChild() != nullptr) - defaulthex = xml->firstChild()->content(); - - gchar * pref_name = this->pref_name(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Glib::ustring paramval = prefs->getString(extension_pref_root + pref_name); - g_free(pref_name); - - if (!paramval.empty()) - defaulthex = paramval.data(); - - if (defaulthex) { - _color.setValue(atoi(defaulthex)); - } - _color_changed = _color.signal_changed.connect(sigc::mem_fun(this, &ParamColor::_onColorChanged)); - -} - -void ParamColor::string(std::string &string) const -{ - char str[16]; - snprintf(str, 16, "%i", _color.value()); - string += str; -} - -Gtk::Widget *ParamColor::get_widget( SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/, sigc::signal * changeSignal ) -{ - using Inkscape::UI::Widget::ColorNotebook; - - if (_hidden) return nullptr; - - if (changeSignal) { - _changeSignal = new sigc::signal(*changeSignal); - } - - if (_color.value() < 1) { - _color_changed.block(true); - _color.setValue(0xFF000000); - _color_changed.block(false); - } - - Gtk::HBox *hbox = Gtk::manage(new Gtk::HBox(false, Parameter::GUI_PARAM_WIDGETS_SPACING)); - Gtk::Widget *selector = Gtk::manage(new ColorNotebook(_color)); - hbox->pack_start(*selector, true, true, 0); - selector->show(); - hbox->show(); - return hbox; -} - -void ParamColor::_onColorChanged() -{ - if (_changeSignal) - _changeSignal->emit(); -} - -}; /* namespace Extension */ -}; /* namespace Inkscape */ diff --git a/src/extension/param/color.h b/src/extension/param/color.h deleted file mode 100644 index c2d3c2ccb..000000000 --- a/src/extension/param/color.h +++ /dev/null @@ -1,74 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -#ifndef SEEN_INK_EXTENSION_PARAMCOLOR_H__ -#define SEEN_INK_EXTENSION_PARAMCOLOR_H__ -/* - * Copyright (C) 2005-2007 Authors: - * Ted Gould - * Johan Engelen * - * Jon A. Cruz - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include "parameter.h" -#include "ui/selected-color.h" - -class SPDocument; - -namespace Gtk { -class Widget; -} - -namespace Inkscape { -namespace XML { -class Node; -} - -namespace Extension { - -class ParamColor : public Parameter { -private: - void _onColorChanged(); - - Inkscape::UI::SelectedColor _color; - sigc::connection _color_changed; -public: - ParamColor(const gchar * name, - const gchar * text, - const gchar * description, - bool hidden, - int indent, - Inkscape::Extension::Extension * ext, - Inkscape::XML::Node * xml); - ~ParamColor() override; - - /** Returns \c _value, with a \i const to protect it. */ - guint32 get( SPDocument const * /*doc*/, Inkscape::XML::Node const * /*node*/ ) const { return _color.value(); } - - guint32 set (guint32 in, SPDocument * doc, Inkscape::XML::Node * node); - - Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) override; - - // Explicitly call superclass version to avoid method being hidden. - void string(std::list &list) const override { return Parameter::string(list); } - - void string (std::string &string) const override; - - sigc::signal * _changeSignal; - -}; // class ParamColor - -} // namespace Extension -} // namespace Inkscape - -#endif // SEEN_INK_EXTENSION_PARAMCOLOR_H__ - -/* - 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 : diff --git a/src/extension/param/description.cpp b/src/extension/param/description.cpp deleted file mode 100644 index 60e2d02c8..000000000 --- a/src/extension/param/description.cpp +++ /dev/null @@ -1,134 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2005-2007 Authors: - * Ted Gould - * Johan Engelen * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#ifdef linux // does the dollar sign need escaping when passed as string parameter? -# define ESCAPE_DOLLAR_COMMANDLINE -#endif - -#include -#include -#include -#include -#include - -#include "xml/node.h" -#include "extension/extension.h" -#include "description.h" - -namespace Inkscape { -namespace Extension { - - -/** \brief Initialize the object, to do that, copy the data. */ -ParamDescription::ParamDescription(const gchar * name, - const gchar * text, - const gchar * description, - bool hidden, - int indent, - Inkscape::Extension::Extension * ext, - Inkscape::XML::Node * xml, - AppearanceMode mode) - : Parameter(name, text, description, hidden, indent, ext) - , _value(nullptr) - , _mode(mode) -{ - // construct the text content by concatenating all (non-empty) text nodes, - // removing all other nodes (e.g. comment nodes) and replacing elements with "
" - Glib::ustring value; - Inkscape::XML::Node * cur_child = xml->firstChild(); - while (cur_child != nullptr) { - if (cur_child->type() == XML::TEXT_NODE && cur_child->content() != nullptr) { - value += cur_child->content(); - } else if (cur_child->type() == XML::ELEMENT_NODE && !g_strcmp0(cur_child->name(), "extension:br")) { - value += "
"; - } - cur_child = cur_child->next(); - } - - // if there is no text content we can return immediately (the description will be invisible) - if (value == Glib::ustring("")) { - return; - } - - // do replacements in the source string to account for the attribute xml:space="preserve" - // (those should match replacements potentially performed by xgettext to allow for proper translation) - if (g_strcmp0(xml->attribute("xml:space"), "preserve") == 0) { - // xgettext copies the source string verbatim in this case, so no changes needed - } else { - // remove all whitespace from start/end of string and replace intermediate whitespace with a single space - value = Glib::Regex::create("^\\s+|\\s+$")->replace_literal(value, 0, "", (Glib::RegexMatchFlags)0); - value = Glib::Regex::create("\\s+")->replace_literal(value, 0, " ", (Glib::RegexMatchFlags)0); - } - - // translate if underscored version (_param) was used - if (g_str_has_prefix(xml->name(), "extension:_")) { - const gchar * context = xml->attribute("msgctxt"); - if (context != nullptr) { - value = g_dpgettext2(nullptr, context, value.c_str()); - } else { - value = _(value.c_str()); - } - } - - // finally replace all remaining
with a real newline character - value = Glib::Regex::create("
")->replace_literal(value, 0, "\n", (Glib::RegexMatchFlags)0); - - _value = g_strdup(value.c_str()); - - return; -} - -/** \brief Create a label for the description */ -Gtk::Widget * -ParamDescription::get_widget (SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/, sigc::signal * /*changeSignal*/) -{ - if (_hidden) { - return nullptr; - } - if (_value == nullptr) { - return nullptr; - } - - Glib::ustring newtext = _value; - - Gtk::Label * label = Gtk::manage(new Gtk::Label()); - if (_mode == HEADER) { - label->set_markup(Glib::ustring("") + Glib::Markup::escape_text(newtext) + Glib::ustring("")); - label->set_margin_top(5); - label->set_margin_bottom(5); - } else if (_mode == URL) { - Glib::ustring escaped_url = Glib::Markup::escape_text(newtext); - label->set_markup(Glib::ustring::compose("%1", escaped_url)); - } else { - label->set_text(newtext); - } - label->set_line_wrap(); - label->set_xalign(0); - - // TODO: Ugly "fix" for gtk3 width/height calculation of labels. - // - If not applying any limits long labels will make the window grow horizontally until it uses up - // most of the available space (i.e. most of the screen area) which is ridicously wide - // - By using "set_default_size(0,0)" in prefidalog.cpp we tell the window to shrink as much as possible, - // however this can result in a much to narrow dialog instead and much unnecessary wrapping - // - Here we set a lower limit of GUI_MAX_LINE_LENGTH characters per line that long texts will always use - // This means texts can not shrink anymore (they can still grow, though) and it's also necessary - // to prevent https://bugzilla.gnome.org/show_bug.cgi?id=773572 - int len = newtext.length(); - label->set_width_chars(len > Parameter::GUI_MAX_LINE_LENGTH ? Parameter::GUI_MAX_LINE_LENGTH : len); - - label->show(); - - Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox()); - hbox->pack_start(*label, true, true); - hbox->show(); - - return hbox; -} - -} /* namespace Extension */ -} /* namespace Inkscape */ diff --git a/src/extension/param/description.h b/src/extension/param/description.h deleted file mode 100644 index 822370b82..000000000 --- a/src/extension/param/description.h +++ /dev/null @@ -1,63 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -#ifndef __INK_EXTENSION_PARAMDESCRIPTION_H__ -#define __INK_EXTENSION_PARAMDESCRIPTION_H__ - -/* - * Copyright (C) 2005-2007 Authors: - * Ted Gould - * Johan Engelen * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include "parameter.h" - -class SPDocument; - -namespace Gtk { - class Widget; -} - -namespace Inkscape { -namespace Xml { - class Node; -} - -namespace Extension { - -/** \brief A description parameter */ -class ParamDescription : public Parameter { -public: - enum AppearanceMode { - DESCRIPTION, HEADER, URL - }; - ParamDescription(const gchar * name, - const gchar * text, - const gchar * description, - bool hidden, - int indent, - Inkscape::Extension::Extension * ext, - Inkscape::XML::Node * xml, - AppearanceMode mode); - - Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) override; -private: - /** \brief Internal value. */ - gchar * _value; - AppearanceMode _mode; -}; - -} /* namespace Extension */ -} /* namespace Inkscape */ - -#endif /* __INK_EXTENSION_PARAMDESCRIPTION_H__ */ - -/* - 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 : diff --git a/src/extension/param/enum.cpp b/src/extension/param/enum.cpp deleted file mode 100644 index 5ba3e5772..000000000 --- a/src/extension/param/enum.cpp +++ /dev/null @@ -1,268 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/** \file - * extension parameter for enumerations. - * - * It uses a Gtk:ComboBoxText widget in the extension UI. - */ - -/* - * Author: - * Johan Engelen - * Jon A. Cruz - * - * Copyright (C) 2006-2007 Johan Engelen - * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include -#include -#include - -#include "xml/node.h" -#include "extension/extension.h" -#include "enum.h" -#include "preferences.h" - -namespace Inkscape { -namespace Extension { - -ParamComboBox::ParamComboBox(const gchar * name, - const gchar * text, - const gchar * description, - bool hidden, - int indent, - Inkscape::Extension::Extension * ext, - Inkscape::XML::Node * xml) - : Parameter(name, text, description, hidden, indent, ext) - , _value(nullptr) -{ - const char *xmlval = nullptr; // the value stored in XML - - if (xml != nullptr) { - // Read XML tree to add enumeration items: - for (Inkscape::XML::Node *node = xml->firstChild(); node; node = node->next()) { - char const * chname = node->name(); - if (!strcmp(chname, INKSCAPE_EXTENSION_NS "item") || !strcmp(chname, INKSCAPE_EXTENSION_NS "_item")) { - Glib::ustring newtext, newvalue; - const char * contents = nullptr; - if (node->firstChild()) { - contents = node->firstChild()->content(); - } - if (contents != nullptr) { - // don't translate when 'item' but do translate when '_item' - // NOTE: internal extensions use build_from_mem and don't need _item but - // still need to include if are to be localized - if (!strcmp(chname, INKSCAPE_EXTENSION_NS "_item")) { - if (node->attribute("msgctxt") != nullptr) { - newtext = g_dpgettext2(nullptr, node->attribute("msgctxt"), contents); - } else { - newtext = _(contents); - } - } else { - newtext = contents; - } - } else - continue; - - const char * val = node->attribute("value"); - if (val != nullptr) { - newvalue = val; - } else { - newvalue = contents; - } - - if ( (!newtext.empty()) && (!newvalue.empty()) ) { // logical error if this is not true here - choices.push_back(new enumentry(newvalue, newtext) ); - } - } - } - - // Initialize _value with the default value from xml - // for simplicity : default to the contents of the first xml-child - if (xml->firstChild() && xml->firstChild()->firstChild()) { - xmlval = xml->firstChild()->attribute("value"); - } - } - - gchar * pref_name = this->pref_name(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Glib::ustring paramval = prefs ? prefs->getString(extension_pref_root + pref_name) : ""; - g_free(pref_name); - - if (!paramval.empty()) { - _value = g_strdup(paramval.data()); - } else if (xmlval) { - _value = g_strdup(xmlval); - } -} - -ParamComboBox::~ParamComboBox () -{ - //destroy choice strings - for (auto i:choices) { - delete i; - } - g_free(_value); -} - - -/** - * A function to set the \c _value. - * - * This function sets ONLY 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(). - * - * @param in The value to set. - * @param doc A document that should be used to set the value. - * @param node The node where the value may be placed. - */ -const gchar *ParamComboBox::set(const gchar * in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/) -{ - if (in == nullptr) { - return nullptr; /* Can't have NULL string */ - } - - Glib::ustring settext; - for (auto entr:choices) { - if ( !entr->text.compare(in) ) { - settext = entr->value; - break; // break out of for loop - } - } - if (!settext.empty()) { - if (_value != nullptr) { - g_free(_value); - } - _value = g_strdup(settext.data()); - gchar * prefname = this->pref_name(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setString(extension_pref_root + prefname, _value); - g_free(prefname); - } - - return _value; -} - -/** - * function to test if \c text is selectable - */ -bool ParamComboBox::contains(const gchar * text, SPDocument const * /*doc*/, Inkscape::XML::Node const * /*node*/) const -{ - if (text == nullptr) { - return false; /* Can't have NULL string */ - } - - for (auto entr:choices) { - if ( !entr->text.compare(text) ) - return true; - } - // if we did not find the text in this ParamComboBox: - return false; -} - -void -ParamComboBox::changed () { - -} - -void ParamComboBox::string(std::string &string) const -{ - string += _value; -} - - - - -/** A special category of Gtk::Entry to handle string parameteres. */ -class ParamComboBoxEntry : public Gtk::ComboBoxText { -private: - ParamComboBox * _pref; - SPDocument * _doc; - Inkscape::XML::Node * _node; - sigc::signal * _changeSignal; -public: - /** - * Build a string preference for the given parameter. - * @param pref Where to get the string from, and where to put it - * when it changes. - */ - ParamComboBoxEntry (ParamComboBox * pref, SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) : - Gtk::ComboBoxText(), _pref(pref), _doc(doc), _node(node), _changeSignal(changeSignal) { - this->signal_changed().connect(sigc::mem_fun(this, &ParamComboBoxEntry::changed)); - }; - void changed (); -}; - -/** - * Respond to the text box changing. - * - * This function responds to the box changing by grabbing the value - * from the text box and putting it in the parameter. - */ -void -ParamComboBoxEntry::changed () -{ - Glib::ustring data = this->get_active_text(); - _pref->set(data.c_str(), _doc, _node); - if (_changeSignal != nullptr) { - _changeSignal->emit(); - } -} - -/** - * Creates a combobox widget for an enumeration parameter. - */ -Gtk::Widget *ParamComboBox::get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) -{ - if (_hidden) { - return nullptr; - } - - Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, Parameter::GUI_PARAM_WIDGETS_SPACING)); - Gtk::Label * label = Gtk::manage(new Gtk::Label(_text, Gtk::ALIGN_START)); - label->show(); - hbox->pack_start(*label, false, false); - - ParamComboBoxEntry * combo = Gtk::manage(new ParamComboBoxEntry(this, doc, node, changeSignal)); - // add choice strings: - Glib::ustring settext; - for (auto entr:choices) { - Glib::ustring text = entr->text; - combo->append(text); - - if ( _value && !entr->value.compare(_value) ) { - settext = entr->text; - } - } - if (!settext.empty()) { - combo->set_active_text(settext); - } - - combo->show(); - hbox->pack_start(*combo, true, true); - - hbox->show(); - - return dynamic_cast(hbox); -} - - -} // 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 : diff --git a/src/extension/param/enum.h b/src/extension/param/enum.h deleted file mode 100644 index 329bb26f9..000000000 --- a/src/extension/param/enum.h +++ /dev/null @@ -1,106 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -#ifndef INK_EXTENSION_PARAMENUM_H_SEEN -#define INK_EXTENSION_PARAMENUM_H_SEEN - -/** \file - * Enumeration parameter for extensions. - */ - -/* - * Authors: - * Johan Engelen - * Jon A. Cruz - * - * Copyright (C) 2006-2007 Johan Engelen - * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include - -#include "parameter.h" -#include "document.h" - -namespace Gtk { -class Widget; -} - -namespace Inkscape { -namespace Extension { - -class Extension; - - -// \brief A class to represent a notebookparameter of an extension -class ParamComboBox : public Parameter { -private: - /** \brief Internal value. This should point to a string that has - been allocated in memory. And should be free'd. - It is the value of the current selected string */ - gchar * _value; - - /* For internal use only. - * Note that value and text MUST be non-NULL. - * This is ensured by newing only at one location in the code where non-NULL checks are made. - */ - class enumentry { - public: - enumentry (Glib::ustring &val, Glib::ustring &text) : - value(val), - text(text) - {} - - Glib::ustring value; - Glib::ustring text; - }; - - std::vector choices; /**< A table to store the choice strings */ - -public: - ParamComboBox(const gchar * name, - const gchar * text, - const gchar * description, - bool hidden, - int indent, - Inkscape::Extension::Extension * ext, - Inkscape::XML::Node * xml); - ~ParamComboBox() override; - - Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) override; - - // Explicitly call superclass version to avoid method being hidden. - void string(std::list &list) const override { return Parameter::string(list); } - - void string(std::string &string) const override; - - gchar const *get(SPDocument const * /*doc*/, Inkscape::XML::Node const * /*node*/) const { return _value; } - - const gchar * set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node); - - /** - * @returns true if text is part of this enum - */ - bool contains(const gchar * text, SPDocument const * /*doc*/, Inkscape::XML::Node const * /*node*/) const; - - void changed (); -}; /* class ParamComboBox */ - - - - - -} /* namespace Extension */ -} /* namespace Inkscape */ - -#endif /* INK_EXTENSION_PARAMENUM_H_SEEN */ - -/* - 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 : diff --git a/src/extension/param/float.cpp b/src/extension/param/float.cpp deleted file mode 100644 index 661c533ca..000000000 --- a/src/extension/param/float.cpp +++ /dev/null @@ -1,205 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2005-2007 Authors: - * Ted Gould - * Johan Engelen * - * Jon A. Cruz - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include -#include -#include -#include "ui/widget/spinbutton.h" -#include "ui/widget/spin-scale.h" - -#include "xml/node.h" -#include "extension/extension.h" -#include "preferences.h" -#include "./float.h" - -namespace Inkscape { -namespace Extension { - - -/** Use the superclass' allocator and set the \c _value. */ -ParamFloat::ParamFloat(const gchar * name, - const gchar * text, - const gchar * description, - bool hidden, - int indent, - Inkscape::Extension::Extension * ext, - Inkscape::XML::Node * xml, - AppearanceMode mode) - : Parameter(name, text, description, hidden, indent, ext) - , _value(0.0) - , _mode(mode) - , _min(0.0) - , _max(10.0) -{ - const gchar * defaultval = nullptr; - if (xml->firstChild() != nullptr) { - defaultval = xml->firstChild()->content(); - } - if (defaultval != nullptr) { - _value = g_ascii_strtod (defaultval,nullptr); - } - - const char * maxval = xml->attribute("max"); - if (maxval != nullptr) { - _max = g_ascii_strtod (maxval,nullptr); - } - - const char * minval = xml->attribute("min"); - if (minval != nullptr) { - _min = g_ascii_strtod (minval,nullptr); - } - - _precision = 1; - const char * precision = xml->attribute("precision"); - if (precision != nullptr) { - _precision = atoi(precision); - } - - /* We're handling this by just killing both values */ - if (_max < _min) { - _max = 10.0; - _min = 0.0; - } - - gchar * pref_name = this->pref_name(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - _value = prefs->getDouble(extension_pref_root + pref_name, _value); - g_free(pref_name); - - // std::cout << "New Float:: value: " << _value << " max: " << _max << " min: " << _min << std::endl; - - if (_value > _max) { - _value = _max; - } - if (_value < _min) { - _value = _min; - } - - return; -} - -/** - * A function to set the \c _value. - * - * 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. - * - * @param in The value to set to. - * @param doc A document that should be used to set the value. - * @param node The node where the value may be placed. - */ -float ParamFloat::set(float in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/) -{ - _value = in; - if (_value > _max) { - _value = _max; - } - if (_value < _min) { - _value = _min; - } - - gchar * prefname = this->pref_name(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setDouble(extension_pref_root + prefname, _value); - g_free(prefname); - - return _value; -} - -void ParamFloat::string(std::string &string) const -{ - char startstring[G_ASCII_DTOSTR_BUF_SIZE]; - g_ascii_dtostr(startstring, G_ASCII_DTOSTR_BUF_SIZE, _value); - string += startstring; - return; -} - -/** A class to make an adjustment that uses Extension params. */ -class ParamFloatAdjustment : public Gtk::Adjustment { - /** The parameter to adjust. */ - ParamFloat * _pref; - SPDocument * _doc; - Inkscape::XML::Node * _node; - sigc::signal * _changeSignal; -public: - /** Make the adjustment using an extension and the string - describing the parameter. */ - ParamFloatAdjustment (ParamFloat * param, SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) : - Gtk::Adjustment(0.0, param->min(), param->max(), 0.1, 1.0, 0), _pref(param), _doc(doc), _node(node), _changeSignal(changeSignal) { - this->set_value(_pref->get(nullptr, nullptr) /* \todo fix */); - this->signal_value_changed().connect(sigc::mem_fun(this, &ParamFloatAdjustment::val_changed)); - return; - }; - - void val_changed (); -}; /* class ParamFloatAdjustment */ - -/** - * A function to respond to the value_changed signal from the adjustment. - * - * This function just grabs the value from the adjustment and writes - * it to the parameter. Very simple, but yet beautiful. - */ -void ParamFloatAdjustment::val_changed() -{ - //std::cout << "Value Changed to: " << this->get_value() << std::endl; - _pref->set(this->get_value(), _doc, _node); - if (_changeSignal != nullptr) { - _changeSignal->emit(); - } - return; -} - -/** - * Creates a Float Adjustment for a float parameter. - * - * Builds a hbox with a label and a float adjustment in it. - */ -Gtk::Widget * ParamFloat::get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) -{ - if (_hidden) { - return nullptr; - } - - Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, Parameter::GUI_PARAM_WIDGETS_SPACING)); - - auto pfa = new ParamFloatAdjustment(this, doc, node, changeSignal); - Glib::RefPtr fadjust(pfa); - - if (_mode == FULL) { - - Glib::ustring text; - if (_text != nullptr) - text = _text; - UI::Widget::SpinScale *scale = new UI::Widget::SpinScale(text, fadjust, _precision); - scale->set_size_request(400, -1); - scale->show(); - hbox->pack_start(*scale, true, true); - - } - else if (_mode == MINIMAL) { - - Gtk::Label * label = Gtk::manage(new Gtk::Label(_text, Gtk::ALIGN_START)); - label->show(); - hbox->pack_start(*label, true, true); - - auto spin = Gtk::manage(new Inkscape::UI::Widget::SpinButton(fadjust, 0.1, _precision)); - spin->show(); - hbox->pack_start(*spin, false, false); - } - - hbox->show(); - - return dynamic_cast(hbox); -} - - -} /* namespace Extension */ -} /* namespace Inkscape */ diff --git a/src/extension/param/float.h b/src/extension/param/float.h deleted file mode 100644 index c1d0f0f79..000000000 --- a/src/extension/param/float.h +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -#ifndef INK_EXTENSION_PARAMFLOAT_H_SEEN -#define INK_EXTENSION_PARAMFLOAT_H_SEEN - -/* - * Copyright (C) 2005-2007 Authors: - * Ted Gould - * Johan Engelen * - * Jon A. Cruz - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include "parameter.h" - -class SPDocument; - -namespace Gtk { -class Widget; -} - -namespace Inkscape { -namespace XML { -class Node; -} - -namespace Extension { - -class ParamFloat : public Parameter { -public: - enum AppearanceMode { - FULL, MINIMAL - }; - ParamFloat(const gchar * name, - const gchar * text, - const gchar * description, - bool hidden, - int indent, - Inkscape::Extension::Extension * ext, - Inkscape::XML::Node * xml, - AppearanceMode mode); - - /** Returns \c _value. */ - float get(const SPDocument * /*doc*/, const Inkscape::XML::Node * /*node*/) const { return _value; } - - float set (float in, SPDocument * doc, Inkscape::XML::Node * node); - - float max () { return _max; } - - float min () { return _min; } - - float precision () { return _precision; } - - Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) override; - - // Explicitly call superclass version to avoid method being hidden. - void string(std::list &list) const override { return Parameter::string(list); } - - void string(std::string &string) const override; - -private: - /** Internal value. */ - float _value; - AppearanceMode _mode; - float _min; - float _max; - int _precision; -}; - -} /* namespace Extension */ -} /* namespace Inkscape */ - -#endif /* INK_EXTENSION_PARAMFLOAT_H_SEEN */ - -/* - 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 : diff --git a/src/extension/param/int.cpp b/src/extension/param/int.cpp deleted file mode 100644 index 1c41c0834..000000000 --- a/src/extension/param/int.cpp +++ /dev/null @@ -1,201 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2005-2007 Authors: - * Ted Gould - * Johan Engelen * - * Jon A. Cruz - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include -#include -#include -#include "ui/widget/spinbutton.h" -#include "ui/widget/spin-scale.h" - -#include "xml/node.h" -#include "extension/extension.h" -#include "preferences.h" -#include "int.h" - -namespace Inkscape { -namespace Extension { - - -/** Use the superclass' allocator and set the \c _value. */ -ParamInt::ParamInt(const gchar * name, - const gchar * text, - const gchar * description, - bool hidden, - int indent, - Inkscape::Extension::Extension * ext, - Inkscape::XML::Node * xml, - AppearanceMode mode) - : Parameter(name, text, description, hidden, indent, ext) - , _value(0) - , _mode(mode) - , _min(0) - , _max(10) -{ - const char * defaultval = nullptr; - if (xml->firstChild() != nullptr) { - defaultval = xml->firstChild()->content(); - } - if (defaultval != nullptr) { - _value = atoi(defaultval); - } - - const char * maxval = xml->attribute("max"); - if (maxval != nullptr) { - _max = atoi(maxval); - } - - const char * minval = xml->attribute("min"); - if (minval != nullptr) { - _min = atoi(minval); - } - /* We're handling this by just killing both values */ - if (_max < _min) { - _max = 10; - _min = 0; - } - - gchar *pref_name = this->pref_name(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - _value = prefs->getInt(extension_pref_root + pref_name, _value); - g_free(pref_name); - - // std::cout << "New Int:: value: " << _value << " max: " << _max << " min: " << _min << std::endl; - - if (_value > _max) { - _value = _max; - } - if (_value < _min) { - _value = _min; - } -} - -/** - * A function to set the \c _value. - * 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. - * - * @param in The value to set to. - * @param doc A document that should be used to set the value. - * @param node The node where the value may be placed. - */ -int ParamInt::set(int in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/) -{ - _value = in; - if (_value > _max) { - _value = _max; - } - if (_value < _min) { - _value = _min; - } - - gchar * prefname = this->pref_name(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setInt(extension_pref_root + prefname, _value); - g_free(prefname); - - return _value; -} - -/** A class to make an adjustment that uses Extension params. */ -class ParamIntAdjustment : public Gtk::Adjustment { - /** The parameter to adjust. */ - ParamInt * _pref; - SPDocument * _doc; - Inkscape::XML::Node * _node; - sigc::signal * _changeSignal; -public: - /** Make the adjustment using an extension and the string - describing the parameter. */ - ParamIntAdjustment (ParamInt * param, SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) : - Gtk::Adjustment(0.0, param->min(), param->max(), 1.0, 10.0, 0), _pref(param), _doc(doc), _node(node), _changeSignal(changeSignal) { - this->set_value(_pref->get(nullptr, nullptr) /* \todo fix */); - this->signal_value_changed().connect(sigc::mem_fun(this, &ParamIntAdjustment::val_changed)); - }; - - void val_changed (); -}; /* class ParamIntAdjustment */ - -/** - * A function to respond to the value_changed signal from the adjustment. - * - * This function just grabs the value from the adjustment and writes - * it to the parameter. Very simple, but yet beautiful. - */ -void ParamIntAdjustment::val_changed() -{ - //std::cout << "Value Changed to: " << this->get_value() << std::endl; - _pref->set((int)this->get_value(), _doc, _node); - if (_changeSignal != nullptr) { - _changeSignal->emit(); - } -} - -/** - * Creates a Int Adjustment for a int parameter. - * - * Builds a hbox with a label and a int adjustment in it. - */ -Gtk::Widget * -ParamInt::get_widget (SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) -{ - if (_hidden) { - return nullptr; - } - - Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, Parameter::GUI_PARAM_WIDGETS_SPACING)); - - auto pia = new ParamIntAdjustment(this, doc, node, changeSignal); - Glib::RefPtr fadjust(pia); - - if (_mode == FULL) { - - Glib::ustring text; - if (_text != nullptr) - text = _text; - UI::Widget::SpinScale *scale = new UI::Widget::SpinScale(text, fadjust, 0); - scale->set_size_request(400, -1); - scale->show(); - hbox->pack_start(*scale, true, true); - } - else if (_mode == MINIMAL) { - Gtk::Label * label = Gtk::manage(new Gtk::Label(_text, Gtk::ALIGN_START)); - label->show(); - hbox->pack_start(*label, true, true); - - auto spin = Gtk::manage(new Inkscape::UI::Widget::SpinButton(fadjust, 1.0, 0)); - spin->show(); - hbox->pack_start(*spin, false, false); - } - - hbox->show(); - - return dynamic_cast(hbox); -} - -void ParamInt::string(std::string &string) const -{ - char startstring[32]; - sprintf(startstring, "%d", _value); - string += startstring; -} - -} // 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/extension/param/int.h b/src/extension/param/int.h deleted file mode 100644 index fac481267..000000000 --- a/src/extension/param/int.h +++ /dev/null @@ -1,80 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -#ifndef INK_EXTENSION_PARAMINT_H_SEEN -#define INK_EXTENSION_PARAMINT_H_SEEN - -/* - * Copyright (C) 2005-2007 Authors: - * Ted Gould - * Johan Engelen * - * Jon A. Cruz - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include "parameter.h" - -class SPDocument; - -namespace Gtk { -class Widget; -} - -namespace Inkscape { -namespace XML { -class Node; -} - -namespace Extension { - -class ParamInt : public Parameter { -public: - enum AppearanceMode { - FULL, MINIMAL - }; - ParamInt(const gchar * name, - const gchar * text, - const gchar * description, - bool hidden, - int indent, - Inkscape::Extension::Extension * ext, - Inkscape::XML::Node * xml, - AppearanceMode mode); - - /** Returns \c _value. */ - int get(const SPDocument * /*doc*/, const Inkscape::XML::Node * /*node*/) const { return _value; } - - int set (int in, SPDocument * doc, Inkscape::XML::Node * node); - - int max () { return _max; } - - int min () { return _min; } - - Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) override; - - // Explicitly call superclass version to avoid method being hidden. - void string(std::list &list) const override { return Parameter::string(list); } - - void string(std::string &string) const override; - -private: - /** Internal value. */ - int _value; - AppearanceMode _mode; - int _min; - int _max; -}; - -} /* namespace Extension */ -} /* namespace Inkscape */ - -#endif /* INK_EXTENSION_PARAMINT_H_SEEN */ - -/* - 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 : diff --git a/src/extension/param/notebook.cpp b/src/extension/param/notebook.cpp deleted file mode 100644 index 838c09d5b..000000000 --- a/src/extension/param/notebook.cpp +++ /dev/null @@ -1,413 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/** \file - * Notebook and NotebookPage parameters for extensions. - */ - -/* - * Authors: - * Johan Engelen - * Jon A. Cruz - * - * Copyright (C) 2006 Author - * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include -#include -#include -#include - -#include - -#include - -#include -#include "preferences.h" - -#include "notebook.h" - -/** - * The root directory in the preferences database for extension - * related parameters. - */ -#define PREF_DIR "extensions" - -namespace Inkscape { -namespace Extension { - - -ParamNotebook::ParamNotebookPage::ParamNotebookPage(const gchar * name, - const gchar * text, - const gchar * description, - bool hidden, - Inkscape::Extension::Extension * ext, - Inkscape::XML::Node * xml) - : Parameter(name, text, description, hidden, /*indent*/ 0, ext) -{ - - // Read XML to build page - if (xml != nullptr) { - Inkscape::XML::Node *child_repr = xml->firstChild(); - while (child_repr != nullptr) { - char const * chname = child_repr->name(); - if (!strncmp(chname, INKSCAPE_EXTENSION_NS_NC, strlen(INKSCAPE_EXTENSION_NS_NC))) { - chname += strlen(INKSCAPE_EXTENSION_NS); - } - 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 != nullptr) parameters.push_back(param); - } - child_repr = child_repr->next(); - } - } -} - -ParamNotebook::ParamNotebookPage::~ParamNotebookPage () -{ - //destroy parameters - for (auto param:parameters) { - delete param; - } -} - -/** Return the value as a string. */ -void ParamNotebook::ParamNotebookPage::paramString(std::list &list) -{ - for (auto param:parameters) { - param->string(list); - } -} - - -/** - \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 - \todo the 'gui-hidden' attribute is read but not used! - - 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. -*/ -ParamNotebook::ParamNotebookPage * -ParamNotebook::ParamNotebookPage::makepage (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext) -{ - const char * name; - const char * text; - const char * description; - bool hidden = false; - const char * hide; - - name = in_repr->attribute("name"); - text = in_repr->attribute("gui-text"); - if (text == nullptr) - text = in_repr->attribute("_gui-text"); - description = in_repr->attribute("gui-description"); - if (description == nullptr) - description = in_repr->attribute("_gui-description"); - hide = in_repr->attribute("gui-hidden"); - if (hide != nullptr) { - if (strcmp(hide, "1") == 0 || - strcmp(hide, "true") == 0) { - hidden = true; - } - /* else stays false */ - } - - /* In this case we just don't have enough information */ - if (name == nullptr) { - return nullptr; - } - - ParamNotebookPage * page = new ParamNotebookPage(name, text, description, hidden, in_ext, in_repr); - - /* Note: page could equal NULL */ - return page; -} - - - -/** - * Creates a notebookpage widget for a notebook. - * - * Builds a notebook page (a vbox) and puts parameters on it. - */ -Gtk::Widget * ParamNotebook::ParamNotebookPage::get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) -{ - if (_hidden) { - return nullptr; - } - - Gtk::VBox * vbox = Gtk::manage(new Gtk::VBox); - vbox->set_border_width(Parameter::GUI_BOX_MARGIN); - vbox->set_spacing(Parameter::GUI_BOX_SPACING); - - // add parameters onto page (if any) - for (auto param:parameters) { - Gtk::Widget * widg = param->get_widget(doc, node, changeSignal); - if (widg) { - int indent = param->get_indent(); - widg->set_margin_start(indent * Parameter::GUI_INDENTATION); - vbox->pack_start(*widg, false, false, 0); - - gchar const * tip = param->get_tooltip(); - if (tip) { - widg->set_tooltip_text(tip); - } else { - widg->set_tooltip_text(""); - widg->set_has_tooltip(false); - } - } - } - - vbox->show(); - - return dynamic_cast(vbox); -} - -/** Search the parameter's name in the page content. */ -Parameter *ParamNotebook::ParamNotebookPage::get_param(const gchar * name) -{ - if (name == nullptr) { - throw Extension::param_not_exist(); - } - if (this->parameters.empty()) { - // the list of parameters is empty - throw Extension::param_not_exist(); - } - - for (auto param:parameters) { - if (!strcmp(param->name(), name)) { - return param; - } - } - - return nullptr; -} - -/** End ParamNotebookPage **/ -/** ParamNotebook **/ - -ParamNotebook::ParamNotebook(const gchar * name, - const gchar * text, - const gchar * description, - bool hidden, - int indent, - Inkscape::Extension::Extension * ext, - Inkscape::XML::Node * xml) - : Parameter(name, text, description, hidden, indent, ext) -{ - // Read XML tree to add pages: - if (xml != nullptr) { - Inkscape::XML::Node *child_repr = xml->firstChild(); - while (child_repr != nullptr) { - char const * chname = child_repr->name(); - if (!strncmp(chname, INKSCAPE_EXTENSION_NS_NC, strlen(INKSCAPE_EXTENSION_NS_NC))) { - chname += strlen(INKSCAPE_EXTENSION_NS); - } - if (chname[0] == '_') // Allow _ for translation of tags - chname++; - if (!strcmp(chname, "page")) { - ParamNotebookPage * page; - page = ParamNotebookPage::makepage(child_repr, ext); - if (page != nullptr) pages.push_back(page); - } - child_repr = child_repr->next(); - } - } - - // Initialize _value with the current page - const char * defaultval = nullptr; - // set first page as default - if (!pages.empty()) { - defaultval = pages[0]->name(); - } - - gchar * pref_name = this->pref_name(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Glib::ustring paramval = prefs->getString(extension_pref_root + pref_name); - g_free(pref_name); - - if (!paramval.empty()) - defaultval = paramval.data(); - if (defaultval != nullptr) - _value = g_strdup(defaultval); // allocate space for _value -} - -ParamNotebook::~ParamNotebook () -{ - //destroy pages - for (auto page:pages) { - delete page; - } - g_free(_value); -} - - -/** - * A function to set the \c _value. - * - * 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(). - * - * @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. - */ -const gchar *ParamNotebook::set(const int in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/) -{ - int i = in < pages.size() ? in : pages.size()-1; - ParamNotebookPage * page = pages[i]; - - if (page == nullptr) return _value; - - if (_value != nullptr) g_free(_value); - _value = g_strdup(page->name()); - - gchar * prefname = this->pref_name(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setString(extension_pref_root + prefname, _value); - g_free(prefname); - - return _value; -} - -void ParamNotebook::string(std::list &list) const -{ - std::string param_string; - param_string += "--"; - param_string += name(); - param_string += "="; - - param_string += "\""; - param_string += _value; // the name of the current page - param_string += "\""; - list.insert(list.end(), param_string); - - for (auto page:pages) { - page->paramString(list); - } -} - -/** 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: - /** - * 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)); - }; - void changed_page(Gtk::Widget *page, guint pagenum); - bool activated; -}; - -/** - * 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(Gtk::Widget * /*page*/, guint pagenum) -{ - if (get_visible()) { - _pref->set((int)pagenum, _doc, _node); - } -} - -/** Search the parameter's name in the notebook content. */ -Parameter *ParamNotebook::get_param(const gchar * name) -{ - if (name == nullptr) { - throw Extension::param_not_exist(); - } - for (auto page:pages) { - Parameter * subparam = page->get_param(name); - if (subparam) { - return subparam; - } - } - - return nullptr; -} - - -/** - * 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, sigc::signal * changeSignal) -{ - if (_hidden) { - return nullptr; - } - - ParamNotebookWdg * nb = Gtk::manage(new ParamNotebookWdg(this, doc, node)); - - // add pages (if any) - int i = -1; - int pagenr = i; - for (auto page:pages) { - i++; - Gtk::Widget * widg = page->get_widget(doc, node, changeSignal); - nb->append_page(*widg, _(page->get_text())); - 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(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:fileencoding=utf-8:textwidth=99 : diff --git a/src/extension/param/notebook.h b/src/extension/param/notebook.h deleted file mode 100644 index dd7154f06..000000000 --- a/src/extension/param/notebook.h +++ /dev/null @@ -1,117 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -#ifndef INK_EXTENSION_PARAMNOTEBOOK_H_SEEN -#define INK_EXTENSION_PARAMNOTEBOOK_H_SEEN - -/** \file - * Notebook parameter for extensions. - */ - -/* - * Author: - * Johan Engelen - * Jon A. Cruz - * - * Copyright (C) 2006 Author - * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include "parameter.h" - -namespace Gtk { -class Widget; -} - -namespace Inkscape { -namespace Extension { - -class Extension; - - -/** A class to represent a notebookparameter of an extension. */ -class ParamNotebook : public Parameter { -private: - /** - * Internal value. This should point to a string that has - * been allocated in memory. And should be free'd. - * It is the name of the current page. - */ - gchar * _value; - - /** - * A class to represent the pages of a notebookparameter of an extension. - */ - class ParamNotebookPage : public Parameter { - private: - std::vector parameters; /**< A table to store the parameters for this page. - This only gets created if there are parameters on this - page */ - - public: - static ParamNotebookPage * makepage (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext); - - ParamNotebookPage(const gchar * name, - const gchar * text, - const gchar * description, - bool hidden, - Inkscape::Extension::Extension * ext, - Inkscape::XML::Node * xml); - ~ParamNotebookPage() override; - - Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) override; - void paramString (std::list &list); - gchar * get_text () {return _text;}; - Parameter * get_param (const gchar * name) override; - }; /* class ParamNotebookPage */ - - - std::vector pages; /**< A table to store the pages with parameters for this notebook. - This only gets created if there are pages in this - notebook */ -public: - ParamNotebook(const gchar * name, - const gchar * text, - const gchar * description, - bool hidden, - int indent, - Inkscape::Extension::Extension * ext, - Inkscape::XML::Node * xml); - ~ParamNotebook() override; - - Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) override; - - /** - * 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. - */ - void string (std::list &list) const override; - - // Explicitly call superclass version to avoid method being hidden. - void string(std::string &string) const override {return Parameter::string(string);} - - - Parameter * get_param (const gchar * name) override; - - const gchar * get (const SPDocument * /*doc*/, const Inkscape::XML::Node * /*node*/) { return _value; } - const gchar * set (const int in, SPDocument * doc, Inkscape::XML::Node * node); -}; /* class ParamNotebook */ - - - - - -} // namespace Extension -} // namespace Inkscape - -#endif /* INK_EXTENSION_PARAMNOTEBOOK_H_SEEN */ - -/* - 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 : diff --git a/src/extension/param/parameter.cpp b/src/extension/param/parameter.cpp deleted file mode 100644 index 1a60ef32e..000000000 --- a/src/extension/param/parameter.cpp +++ /dev/null @@ -1,461 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/** @file - * Parameters for extensions. - */ -/* Author: - * Ted Gould - * Johan Engelen - * Jon A. Cruz - * - * Copyright (C) 2005-2007 Authors - * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#ifdef linux // does the dollar sign need escaping when passed as string parameter? -# define ESCAPE_DOLLAR_COMMANDLINE -#endif - -#include -#include - -#include -#include - -#include "bool.h" -#include "color.h" -#include "description.h" -#include "enum.h" -#include "./float.h" -#include "int.h" -#include "notebook.h" -#include "parameter.h" -#include "radiobutton.h" -#include "./string.h" - -#include "extension/extension.h" - -#include "object/sp-defs.h" - -#include "ui/widget/color-notebook.h" - -#include "xml/node.h" - - -namespace Inkscape { -namespace Extension { - -Parameter *Parameter::make(Inkscape::XML::Node *in_repr, Inkscape::Extension::Extension *in_ext) -{ - const char *name = in_repr->attribute("name"); - const char *type = in_repr->attribute("type"); - - // we can't create a parameter without type - if (!type) { - return nullptr; - } - // also require name unless it's a pure UI element that does not store its value - if (!name) { - static std::vector ui_elements = {"description"}; - if (std::find(ui_elements.begin(), ui_elements.end(), type) == ui_elements.end()) { - return nullptr; - } - } - - const char *text = in_repr->attribute("gui-text"); - if (text == nullptr) { - text = in_repr->attribute("_gui-text"); - if (text == nullptr) { - // text = ""; // probably better to require devs to explicitly set an empty gui-text if this is what they want - } else { - const char *context = in_repr->attribute("msgctxt"); - if (context != nullptr) { - text = g_dpgettext2(nullptr, context, text); - } else { - text = _(text); - } - } - } - const char *description = in_repr->attribute("gui-description"); - if (description == nullptr) { - description = in_repr->attribute("_gui-description"); - if (description != nullptr) { - const char *context = in_repr->attribute("msgctxt"); - if (context != nullptr) { - description = g_dpgettext2(nullptr, context, description); - } else { - description = _(description); - } - } - } - bool hidden = false; - { - const char *gui_hide = in_repr->attribute("gui-hidden"); - if (gui_hide != nullptr) { - if (strcmp(gui_hide, "1") == 0 || - strcmp(gui_hide, "true") == 0) { - hidden = true; - } - /* else stays false */ - } - } - int indent = 0; - { - const char *indent_attr = in_repr->attribute("indent"); - if (indent_attr != nullptr) { - if (strcmp(indent_attr, "true") == 0) { - indent = 1; - } else { - indent = atoi(indent_attr); - } - } - } - const gchar* appearance = in_repr->attribute("appearance"); - - Parameter * param = nullptr; - if (!strcmp(type, "boolean")) { - param = new ParamBool(name, text, description, hidden, indent, in_ext, in_repr); - } else if (!strcmp(type, "int")) { - if (appearance && !strcmp(appearance, "full")) { - param = new ParamInt(name, text, description, hidden, indent, in_ext, in_repr, ParamInt::FULL); - } else { - param = new ParamInt(name, text, description, hidden, indent, in_ext, in_repr, ParamInt::MINIMAL); - } - } else if (!strcmp(type, "float")) { - if (appearance && !strcmp(appearance, "full")) { - param = new ParamFloat(name, text, description, hidden, indent, in_ext, in_repr, ParamFloat::FULL); - } else { - param = new ParamFloat(name, text, description, hidden, indent, in_ext, in_repr, ParamFloat::MINIMAL); - } - } else if (!strcmp(type, "string")) { - param = new ParamString(name, text, description, hidden, indent, in_ext, in_repr); - gchar const * max_length = in_repr->attribute("max_length"); - if (max_length != nullptr) { - ParamString * ps = dynamic_cast(param); - ps->setMaxLength(atoi(max_length)); - } - } else if (!strcmp(type, "description")) { - ParamDescription::AppearanceMode appearance_mode = ParamDescription::DESCRIPTION; - if (appearance) { - if (!strcmp(appearance, "header")) { - appearance_mode = ParamDescription::HEADER; - } else if (!strcmp(appearance, "url")) { - appearance_mode = ParamDescription::URL; - } - } - param = new ParamDescription(name, text, description, hidden, indent, in_ext, in_repr, appearance_mode); - } else if (!strcmp(type, "enum")) { - param = new ParamComboBox(name, text, description, hidden, indent, in_ext, in_repr); - } else if (!strcmp(type, "notebook")) { - param = new ParamNotebook(name, text, description, hidden, indent, in_ext, in_repr); - } else if (!strcmp(type, "optiongroup")) { - if (appearance && !strcmp(appearance, "minimal")) { - param = new ParamRadioButton(name, text, description, hidden, indent, in_ext, in_repr, ParamRadioButton::MINIMAL); - } else { - param = new ParamRadioButton(name, text, description, hidden, indent, in_ext, in_repr, ParamRadioButton::FULL); - } - } else if (!strcmp(type, "color")) { - param = new ParamColor(name, text, description, hidden, indent, in_ext, in_repr); - } - - // Note: param could equal NULL - return param; -} - -bool Parameter::get_bool(SPDocument const *doc, Inkscape::XML::Node const *node) const -{ - ParamBool const *boolpntr = dynamic_cast(this); - if (!boolpntr) { - throw Extension::param_not_bool_param(); - } - return boolpntr->get(doc, node); -} - -int Parameter::get_int(SPDocument const *doc, Inkscape::XML::Node const *node) const -{ - ParamInt const *intpntr = dynamic_cast(this); - if (!intpntr) { - throw Extension::param_not_int_param(); - } - return intpntr->get(doc, node); -} - -float Parameter::get_float(SPDocument const *doc, Inkscape::XML::Node const *node) const -{ - ParamFloat const *floatpntr = dynamic_cast(this); - if (!floatpntr) { - throw Extension::param_not_float_param(); - } - return floatpntr->get(doc, node); -} - -gchar const *Parameter::get_string(SPDocument const *doc, Inkscape::XML::Node const *node) const -{ - ParamString const *stringpntr = dynamic_cast(this); - if (!stringpntr) { - throw Extension::param_not_string_param(); - } - return stringpntr->get(doc, node); -} - -gchar const *Parameter::get_enum(SPDocument const *doc, Inkscape::XML::Node const *node) const -{ - ParamComboBox const *param = dynamic_cast(this); - if (!param) { - throw Extension::param_not_enum_param(); - } - return param->get(doc, node); -} - -bool Parameter::get_enum_contains(gchar const * value, SPDocument const *doc, Inkscape::XML::Node const *node) const -{ - ParamComboBox const *param = dynamic_cast(this); - if (!param) { - throw Extension::param_not_enum_param(); - } - return param->contains(value, doc, node); -} - -gchar const *Parameter::get_optiongroup(SPDocument const *doc, Inkscape::XML::Node const * node) const -{ - ParamRadioButton const *param = dynamic_cast(this); - if (!param) { - throw Extension::param_not_optiongroup_param(); - } - return param->get(doc, node); -} - -guint32 Parameter::get_color(const SPDocument* doc, Inkscape::XML::Node const *node) const -{ - ParamColor const *param = dynamic_cast(this); - if (!param) { - throw Extension::param_not_color_param(); - } - return param->get(doc, node); -} - -bool Parameter::set_bool(bool in, SPDocument * doc, Inkscape::XML::Node * node) -{ - ParamBool * boolpntr = dynamic_cast(this); - if (boolpntr == nullptr) - throw Extension::param_not_bool_param(); - return boolpntr->set(in, doc, node); -} - -int Parameter::set_int(int in, SPDocument * doc, Inkscape::XML::Node * node) -{ - ParamInt * intpntr = dynamic_cast(this); - if (intpntr == nullptr) - throw Extension::param_not_int_param(); - return intpntr->set(in, doc, node); -} - -/** 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(this); - if (floatpntr == nullptr) - throw Extension::param_not_float_param(); - return floatpntr->set(in, doc, node); -} - -/** Wrapper to cast to the object and use it's function. */ -gchar const * -Parameter::set_string (gchar const * in, SPDocument * doc, Inkscape::XML::Node * node) -{ - ParamString * stringpntr = dynamic_cast(this); - if (stringpntr == nullptr) - throw Extension::param_not_string_param(); - return stringpntr->set(in, doc, node); -} - -gchar const * Parameter::set_optiongroup( gchar const * in, SPDocument * doc, Inkscape::XML::Node * node ) -{ - ParamRadioButton *param = dynamic_cast(this); - if (!param) { - throw Extension::param_not_optiongroup_param(); - } - return param->set(in, doc, node); -} - -gchar const *Parameter::set_enum( gchar const * in, SPDocument * doc, Inkscape::XML::Node * node ) -{ - ParamComboBox *param = dynamic_cast(this); - if (!param) { - throw Extension::param_not_enum_param(); - } - return param->set(in, doc, node); -} - - -/** 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(this); - if (param == nullptr) - throw Extension::param_not_color_param(); - return param->set(in, doc, node); -} - - -/** Oop, now that we need a parameter, we need it's name. */ -Parameter::Parameter(gchar const * name, gchar const * text, gchar const * description, bool hidden, int indent, Inkscape::Extension::Extension * ext) : - _description(nullptr), - _text(nullptr), - _hidden(hidden), - _indent(indent), - _extension(ext), - _name(nullptr) -{ - if (name != nullptr) { - _name = g_strdup(name); - } - - if (description != nullptr) { - _description = g_strdup(description); - } - - if (text != nullptr) { - _text = g_strdup(text); - } else { - _text = g_strdup(name); - } - - return; -} - -/** Oop, now that we need a parameter, we need it's name. */ -Parameter::Parameter (gchar const * name, gchar const * text, Inkscape::Extension::Extension * ext) : - _description(nullptr), - _text(nullptr), - _hidden(false), - _indent(0), - _extension(ext), - _name(nullptr) -{ - if (name != nullptr) { - _name = g_strdup(name); - } - if (text != nullptr) { - _text = g_strdup(text); - } else { - _text = g_strdup(name); - } - - return; -} - -Parameter::~Parameter() -{ - g_free(_name); - _name = nullptr; - - g_free(_text); - _text = nullptr; - - g_free(_description); - _description = nullptr; -} - -gchar *Parameter::pref_name() const -{ - 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 = doc->getReprDoc(); - Inkscape::XML::Node * defs = doc->getDefs()->getRepr(); - Inkscape::XML::Node * params = nullptr; - - GQuark const name_quark = g_quark_from_string("inkscape:extension-params"); - - for (Inkscape::XML::Node * child = defs->firstChild(); - child != nullptr; - child = child->next()) { - if ((GQuark)child->code() == name_quark && - !strcmp(child->attribute("extension"), _extension->get_id())) { - params = child; - break; - } - } - - if (params == nullptr) { - params = xml_doc->createElement("inkscape:extension-param"); - params->setAttribute("extension", _extension->get_id()); - defs->appendChild(params); - Inkscape::GC::release(params); - } - - return params; -} - -/** Basically, if there is no widget pass a NULL. */ -Gtk::Widget * -Parameter::get_widget (SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/, sigc::signal * /*changeSignal*/) -{ - return nullptr; -} - -/** If I'm not sure which it is, just don't return a value. */ -void Parameter::string(std::string &/*string*/) const -{ - // TODO investigate clearing the target string. -} - -void Parameter::string(std::list &list) const -{ - std::string value; - string(value); - if (!value.empty()) { - std::string final; - final += "--"; - final += name(); - final += "="; - final += value; - - list.insert(list.end(), final); - } -} - -Parameter *Parameter::get_param(gchar const * /*name*/) -{ - return nullptr; -} - -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:fileencoding=utf-8:textwidth=99 : diff --git a/src/extension/param/parameter.h b/src/extension/param/parameter.h deleted file mode 100644 index c37d1539a..000000000 --- a/src/extension/param/parameter.h +++ /dev/null @@ -1,219 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/** @file - * Parameters for extensions. - */ -/* Authors: - * Ted Gould - * Jon A. Cruz - * - * Copyright (C) 2005-2006 Authors - * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#ifndef SEEN_INK_EXTENSION_PARAM_H__ -#define SEEN_INK_EXTENSION_PARAM_H__ - -#include - -#include - -class SPDocument; - -namespace Gtk { -class Widget; -} - -namespace Inkscape { -namespace XML { -class Node; -} - -namespace Extension { - -class Extension; - - -/** - * The root directory in the preferences database for extension-related parameters. - * - * The directory path has both a leading and a trailing slash, so that extension_pref_root + pref_name works - * without having to append a separator. - */ -extern Glib::ustring const extension_pref_root; - -/** - * A class to represent the parameter of an extension. - * - * This is really a super class that allows them to abstract all - * the different types of parameters into some that can be passed - * around. There is also a few functions that are used by all the - * different parameters. - */ -class Parameter { - -public: - Parameter(gchar const *name, - gchar const *text, - gchar const *description, - bool hidden, - int indent, - Inkscape::Extension::Extension * ext); - - Parameter(gchar const *name, - gchar const *text, - Inkscape::Extension::Extension * ext); - - virtual ~Parameter(); - - /** Wrapper to cast to the object and use its function. */ - bool get_bool(SPDocument const *doc, Inkscape::XML::Node const *node) const; - - /** Wrapper to cast to the object and use it's function. */ - int get_int(SPDocument const *doc, Inkscape::XML::Node const *node) const; - - /** Wrapper to cast to the object and use it's function. */ - float get_float(SPDocument const *doc, Inkscape::XML::Node const *node) const; - - /** Wrapper to cast to the object and use it's function. */ - gchar const *get_string(SPDocument const *doc, Inkscape::XML::Node const *node) const; - - guint32 get_color(SPDocument const *doc, Inkscape::XML::Node const *node) const; - - /** Wrapper to cast to the object and use it's function. */ - gchar const *get_enum(SPDocument const *doc, Inkscape::XML::Node const *node) const; - - /** Wrapper to cast to the object and use it's function. */ - bool get_enum_contains(gchar const * value, SPDocument const *doc, Inkscape::XML::Node const *node) const; - - /** Wrapper to cast to the object and use it's function. */ - gchar const *get_optiongroup(SPDocument const * doc, Inkscape::XML::Node const *node) const; - - /** Wrapper to cast to the object and use it's function. */ - bool set_bool(bool in, SPDocument * doc, Inkscape::XML::Node * node); - - /** Wrapper to cast to the object and use it's function. */ - int set_int(int in, SPDocument * doc, Inkscape::XML::Node * node); - - float set_float(float in, SPDocument * doc, Inkscape::XML::Node * node); - - gchar const *set_optiongroup(gchar const *in, SPDocument * doc, Inkscape::XML::Node *node); - - gchar const *set_enum(gchar const * in, SPDocument * doc, Inkscape::XML::Node *node); - - gchar const *set_string(gchar const * in, SPDocument * doc, Inkscape::XML::Node * node); - - guint32 set_color(guint32 in, SPDocument * doc, Inkscape::XML::Node * node); - - gchar const * name() const {return _name;} - - /** - * This function creates a parameter that can be used later. This - * is typically done in the creation of the extension and defined - * in the XML file describing the extension (it's private so people - * have to use the system) :) - * - * 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 or a type in the XML, then no parameter 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. - * - * @param in_repr The XML describing the parameter. - * @return a pointer to a new Parameter if applicable, null otherwise.. - */ - static Parameter *make(Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext); - - virtual Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal); - - gchar const * get_tooltip() const { return _description; } - - /** Indicates if the GUI for this parameter is hidden or not */ - bool get_hidden() const { return _hidden; } - - /** Indentation level of the parameter */ - int get_indent() const { return _indent; } - - virtual void string(std::list &list) const; - - /** - * Gets the current value of the parameter in a string form. - * @return A string with the 'value'. - */ - virtual void string(std::string &string) const; - - /** All the code in Notebook::get_param to get the notebook content. */ - virtual Parameter *get_param(gchar const *name); - - - /** Recommended margin of boxes containing multiple Parameters (in px) */ - const static int GUI_BOX_MARGIN = 10; - /** Recommended spacing between multiple Parameters packed into a box (in px) */ - const static int GUI_BOX_SPACING = 4; - /** Recommended spacing between the widgets making up a single Parameter (e.g. label and input) (in px) */ - const static int GUI_PARAM_WIDGETS_SPACING = 4; - /** Recommended indentation width of parameters (in px) */ - const static int GUI_INDENTATION = 12; - /** Recommended maximum line length for wrapping textual parameters (in chars) */ - const static int GUI_MAX_LINE_LENGTH = 60; - - -protected: - /** Parameter text to show as the GUI label. */ - gchar * _text; - - /** Extended description of the parameter (crrently shown as tooltip on hover). */ - gchar * _description; - - /** Whether the parameter is visible. */ - bool _hidden; - - /** Indentation level of the parameter. */ - int _indent; - - - /* **** funcs **** */ - - /** - * Build the name to write the parameter from the extension's ID and the name of this parameter. - */ - gchar *pref_name() const; - - Inkscape::XML::Node * find_child (Inkscape::XML::Node * adult); - - Inkscape::XML::Node * document_param_node (SPDocument * doc); - - Inkscape::XML::Node * new_child (Inkscape::XML::Node * parent); - -private: - /** Which extension is this parameter attached to. */ - Inkscape::Extension::Extension *_extension; - - /** The name of this parameter. */ - gchar *_name; -}; - -} // namespace Extension -} // namespace Inkscape - -#endif // SEEN_INK_EXTENSION_PARAM_H__ - -/* - 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/extension/param/radiobutton.cpp b/src/extension/param/radiobutton.cpp deleted file mode 100644 index 8c1d6a5f7..000000000 --- a/src/extension/param/radiobutton.cpp +++ /dev/null @@ -1,349 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/** \file - * extension parameter for radiobuttons. - * - * It uses a Gtk:ComboBoxText widget in the extension UI. - */ - -/* - * Author: - * Johan Engelen - * - * Copyright (C) 2006-2007 Johan Engelen - * Copyright (C) 2008 Jon A. Cruz - * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include -#include -#include -#include - -#include "xml/node.h" -#include "extension/extension.h" -#include "preferences.h" - -#include "radiobutton.h" - -/** - * The root directory in the preferences database for extension - * related parameters. - */ -#define PREF_DIR "extensions" - -namespace Inkscape { -namespace Extension { - -/* For internal use only. - Note that value and text MUST be non-NULL. This is ensured by newing only at one location in the code where non-NULL checks are made. */ - -ParamRadioButton::ParamRadioButton(const gchar * name, - const gchar * text, - const gchar * description, - bool hidden, - int indent, - Inkscape::Extension::Extension * ext, - Inkscape::XML::Node * xml, - AppearanceMode mode) - : Parameter(name, text, description, hidden, indent, ext) - , _value(nullptr) - , _mode(mode) -{ - // Read XML tree to add enumeration items: - // printf("Extension Constructor: "); - if (xml != nullptr) { - Inkscape::XML::Node *child_repr = xml->firstChild(); - while (child_repr != nullptr) { - char const * chname = child_repr->name(); - if (!strcmp(chname, INKSCAPE_EXTENSION_NS "option") || !strcmp(chname, INKSCAPE_EXTENSION_NS "_option")) { - Glib::ustring * newtext = nullptr; - Glib::ustring * newvalue = nullptr; - const char * contents = child_repr->firstChild()->content(); - - if (contents != nullptr) { - // don't translate when 'item' but do translate when '_option' - if (!strcmp(chname, INKSCAPE_EXTENSION_NS "_option")) { - if (child_repr->attribute("msgctxt") != nullptr) { - newtext = new Glib::ustring(g_dpgettext2(nullptr, child_repr->attribute("msgctxt"), contents)); - } else { - newtext = new Glib::ustring(_(contents)); - } - } else { - newtext = new Glib::ustring(contents); - } - } else { - continue; - } - - - const char * val = child_repr->attribute("value"); - if (val != nullptr) { - newvalue = new Glib::ustring(val); - } else { - newvalue = new Glib::ustring(contents); - } - - if ( (newtext) && (newvalue) ) { // logical error if this is not true here - choices.push_back(new optionentry(newvalue, newtext)); - } - } - child_repr = child_repr->next(); - } - } - - // Initialize _value with the default value from xml - // for simplicity : default to the contents of the first xml-child - const char * defaultval = nullptr; - if (!choices.empty()) { - defaultval = (static_cast (choices[0]))->value->c_str(); - } - - gchar * pref_name = this->pref_name(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Glib::ustring paramval = prefs->getString(extension_pref_root + pref_name); - g_free(pref_name); - - if (!paramval.empty()) { - defaultval = paramval.data(); - } - if (defaultval != nullptr) { - _value = g_strdup(defaultval); // allocate space for _value - } -} - -ParamRadioButton::~ParamRadioButton () -{ - //destroy choice strings - for(auto i:choices) { - delete i; - } - g_free(_value); -} - - -/** - * A function to set the \c _value. - * - * This function sets ONLY 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(). - * - * @param in The value to set. - * @param doc A document that should be used to set the value. - * @param node The node where the value may be placed. - */ -const gchar *ParamRadioButton::set(const gchar * in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/) -{ - if (in == nullptr) { - return nullptr; /* Can't have NULL string */ - } - - Glib::ustring * settext = nullptr; - for (auto entr:choices) { - if ( !entr->value->compare(in) ) { - settext = entr->value; - break; // break out of for loop - } - } - if (settext) { - if (_value != nullptr) { - g_free(_value); - } - _value = g_strdup(settext->c_str()); - gchar * prefname = this->pref_name(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setString(extension_pref_root + prefname, _value); - g_free(prefname); - } else { - g_warning("Couldn't set ParamRadioButton %s", in); - } - - return _value; -} - -void ParamRadioButton::string(std::string &string) const -{ - string += _value; -} - -/** A special radiobutton class to use in ParamRadioButton. */ -class ParamRadioButtonWdg : public Gtk::RadioButton { -private: - ParamRadioButton * _pref; - SPDocument * _doc; - Inkscape::XML::Node * _node; - sigc::signal * _changeSignal; -public: - /** - * Build a string preference for the given parameter. - * @param pref Where to put the radiobutton's string when it is selected. - */ - ParamRadioButtonWdg ( Gtk::RadioButtonGroup& group, const Glib::ustring& label, - ParamRadioButton * pref, SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal ) : - Gtk::RadioButton(group, label), _pref(pref), _doc(doc), _node(node), _changeSignal(changeSignal) { - add_changesignal(); - }; - ParamRadioButtonWdg ( const Glib::ustring& label, - ParamRadioButton * pref, SPDocument * doc, Inkscape::XML::Node * node , sigc::signal * changeSignal) : - Gtk::RadioButton(label), _pref(pref), _doc(doc), _node(node), _changeSignal(changeSignal) { - add_changesignal(); - }; - void add_changesignal() { - this->signal_toggled().connect(sigc::mem_fun(this, &ParamRadioButtonWdg::changed)); - }; - void changed (); -}; - -/** - * Respond to the selected radiobutton changing. - * - * This function responds to the radiobutton selection changing by grabbing the value - * from the text box and putting it in the parameter. - */ -void ParamRadioButtonWdg::changed() -{ - if (this->get_active()) { - Glib::ustring value = _pref->value_from_label(this->get_label()); - _pref->set(value.c_str(), _doc, _node); - } - if (_changeSignal != nullptr) { - _changeSignal->emit(); - } -} - - -class ComboWdg : public Gtk::ComboBoxText { -private: - ParamRadioButton* _base; - SPDocument* _doc; - Inkscape::XML::Node* _node; - sigc::signal * _changeSignal; - -public: - ComboWdg(ParamRadioButton* base, SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) : - _base(base), - _doc(doc), - _node(node), - _changeSignal(changeSignal) - { - this->signal_changed().connect(sigc::mem_fun(this, &ComboWdg::changed)); - } - ~ComboWdg() override = default; - void changed (); -}; - -void ComboWdg::changed() -{ - if ( _base ) { - Glib::ustring value = _base->value_from_label(get_active_text()); - _base->set(value.c_str(), _doc, _node); - } - if (_changeSignal != nullptr) { - _changeSignal->emit(); - } -} - -/** - * Returns the value for the options label parameter - */ -Glib::ustring ParamRadioButton::value_from_label(const Glib::ustring label) -{ - Glib::ustring value = ""; - - for ( auto entr:choices) { - if ( !entr->text->compare(label) ) { - value = *(entr->value); - break; - } - } - - return value; - -} - -/** - * Creates a combobox widget for an enumeration parameter. - */ -Gtk::Widget * ParamRadioButton::get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) -{ - if (_hidden) { - return nullptr; - } - - auto hbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, Parameter::GUI_PARAM_WIDGETS_SPACING)); - hbox->set_homogeneous(false); - auto vbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0)); - vbox->set_homogeneous(false); - - Gtk::Label * label = Gtk::manage(new Gtk::Label(_text, Gtk::ALIGN_START, Gtk::ALIGN_START)); - label->show(); - hbox->pack_start(*label, false, false); - - Gtk::ComboBoxText* cbt = nullptr; - bool comboSet = false; - if (_mode == MINIMAL) { - cbt = Gtk::manage(new ComboWdg(this, doc, node, changeSignal)); - cbt->show(); - vbox->pack_start(*cbt, false, false); - } - - // add choice strings as radiobuttons - // and select last selected option (_value) - Gtk::RadioButtonGroup group; - for (auto entr:choices) { - Glib::ustring * text = entr->text; - switch ( _mode ) { - case MINIMAL: - { - cbt->append(*text); - if (!entr->value->compare(_value)) { - cbt->set_active_text(*text); - comboSet = true; - } - } - break; - case COMPACT: - case FULL: - { - ParamRadioButtonWdg * radio = Gtk::manage(new ParamRadioButtonWdg(group, *text, this, doc, node, changeSignal)); - radio->show(); - vbox->pack_start(*radio, true, true); - if (!entr->value->compare(_value)) { - radio->set_active(); - } - } - break; - } - } - - if ( (_mode == MINIMAL) && !comboSet) { - cbt->set_active(0); - } - - vbox->show(); - hbox->pack_end(*vbox, false, false); - hbox->show(); - - - return dynamic_cast(hbox); -} - - -} /* 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 : diff --git a/src/extension/param/radiobutton.h b/src/extension/param/radiobutton.h deleted file mode 100644 index 48d470a01..000000000 --- a/src/extension/param/radiobutton.h +++ /dev/null @@ -1,107 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -#ifndef INK_EXTENSION_PARAMRADIOBUTTON_H_SEEN -#define INK_EXTENSION_PARAMRADIOBUTTON_H_SEEN - -/** \file - * Radiobutton parameter for extensions. - */ - -/* - * Authors: - * Johan Engelen - * Jon A. Cruz - * - * Copyright (C) 2006-2007 Johan Engelen - * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include "parameter.h" - -namespace Gtk { -class Widget; -} - -namespace Inkscape { -namespace Extension { - -class Extension; - - - -// \brief A class to represent a radiobutton parameter of an extension -class ParamRadioButton : public Parameter { -public: - enum AppearanceMode { - FULL, COMPACT, MINIMAL - }; - - ParamRadioButton(const gchar * name, - const gchar * text, - const gchar * description, - bool hidden, - int indent, - Inkscape::Extension::Extension * ext, - Inkscape::XML::Node * xml, - AppearanceMode mode); - ~ParamRadioButton() override; - - Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) override; - - // Explicitly call superclass version to avoid method being hidden. - void string(std::list &list) const override { return Parameter::string(list); } - - void string(std::string &string) const override; - - Glib::ustring value_from_label(const Glib::ustring label); - - const gchar *get(const SPDocument * /*doc*/, const Inkscape::XML::Node * /*node*/) const { return _value; } - - const gchar *set(const gchar *in, SPDocument *doc, Inkscape::XML::Node *node); - -private: - /** \brief Internal value. This should point to a string that has - been allocated in memory. And should be free'd. - It is the value of the current selected string */ - gchar * _value; - AppearanceMode _mode; - - /* For internal use only. - Note that value and text MUST be non-NULL. This is ensured by newing only at one location in the code where non-NULL checks are made. */ - class optionentry { - public: - optionentry (Glib::ustring * val, Glib::ustring * txt) { - value = val; - text = txt; - } - ~optionentry() { - delete value; - delete text; - } - Glib::ustring * value; - Glib::ustring * text; - }; - - std::vector choices; /**< A table to store the choice strings */ - -}; /* class ParamRadioButton */ - - - - - -} /* namespace Extension */ -} /* namespace Inkscape */ - -#endif /* INK_EXTENSION_PARAMRADIOBUTTON_H_SEEN */ - -/* - 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/extension/param/string.cpp b/src/extension/param/string.cpp deleted file mode 100644 index c1986cf92..000000000 --- a/src/extension/param/string.cpp +++ /dev/null @@ -1,181 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Copyright (C) 2005-2007 Authors: - * Ted Gould - * Johan Engelen * - * Jon A. Cruz - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include -#include -#include - -#include - -#include "xml/node.h" -#include "extension/extension.h" -#include "./string.h" -#include "preferences.h" -#include - -namespace Inkscape { -namespace Extension { - - -/** Free the allocated data. */ -ParamString::~ParamString() -{ - g_free(_value); - _value = nullptr; -} - -/** - * A function to set the \c _value. - * - * 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(). - * - * @param in The value to set to. - * @param doc A document that should be used to set the value. - * @param node The node where the value may be placed. - */ -const gchar * ParamString::set(const gchar * in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/) -{ - if (in == nullptr) { - return nullptr; /* Can't have NULL string */ - } - - if (_value != nullptr) { - g_free(_value); - } - - _value = g_strdup(in); - - gchar * prefname = this->pref_name(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - prefs->setString(extension_pref_root + prefname, _value); - g_free(prefname); - - return _value; -} - -void ParamString::string(std::string &string) const -{ - if (_value) { - string += _value; - } -} - -/** Initialize the object, to do that, copy the data. */ -ParamString::ParamString(const gchar * name, - const gchar * text, - const gchar * description, - bool hidden, - int indent, - Inkscape::Extension::Extension * ext, - Inkscape::XML::Node * xml) - : Parameter(name, text, description, hidden, indent, ext) - , _value(nullptr) -{ - const char * defaultval = nullptr; - if (xml->firstChild() != nullptr) { - defaultval = xml->firstChild()->content(); - } - - gchar * pref_name = this->pref_name(); - Inkscape::Preferences *prefs = Inkscape::Preferences::get(); - Glib::ustring paramval = prefs->getString(extension_pref_root + pref_name); - g_free(pref_name); - - if (!paramval.empty()) { - defaultval = paramval.data(); - } - if (defaultval != nullptr) { - char const * chname = xml->name(); - if (!strcmp(chname, INKSCAPE_EXTENSION_NS "_param")) { - if (xml->attribute("msgctxt") != nullptr) { - _value = g_strdup(g_dpgettext2(nullptr, xml->attribute("msgctxt"), defaultval)); - } else { - _value = g_strdup(_(defaultval)); - } - } else { - _value = g_strdup(defaultval); - } - } - - _max_length = 0; -} - -/** A special type of Gtk::Entry to handle string parameteres. */ -class ParamStringEntry : public Gtk::Entry { -private: - ParamString * _pref; - SPDocument * _doc; - Inkscape::XML::Node * _node; - sigc::signal * _changeSignal; -public: - /** - * Build a string preference for the given parameter. - * @param pref Where to get the string from, and where to put it - * when it changes. - */ - ParamStringEntry (ParamString * pref, SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) : - Gtk::Entry(), _pref(pref), _doc(doc), _node(node), _changeSignal(changeSignal) { - if (_pref->get(nullptr, nullptr) != nullptr) { - this->set_text(Glib::ustring(_pref->get(nullptr, nullptr))); - } - this->set_max_length(_pref->getMaxLength()); //Set the max length - default zero means no maximum - this->signal_changed().connect(sigc::mem_fun(this, &ParamStringEntry::changed_text)); - }; - void changed_text (); -}; - - -/** - * Respond to the text box changing. - * - * This function responds to the box changing by grabbing the value - * from the text box and putting it in the parameter. - */ -void ParamStringEntry::changed_text() -{ - Glib::ustring data = this->get_text(); - _pref->set(data.c_str(), _doc, _node); - if (_changeSignal != nullptr) { - _changeSignal->emit(); - } -} - -/** - * Creates a text box for the string parameter. - * - * Builds a hbox with a label and a text box in it. - */ -Gtk::Widget * ParamString::get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) -{ - if (_hidden) { - return nullptr; - } - - Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, Parameter::GUI_PARAM_WIDGETS_SPACING)); - Gtk::Label * label = Gtk::manage(new Gtk::Label(_text, Gtk::ALIGN_START)); - label->show(); - hbox->pack_start(*label, false, false); - - ParamStringEntry * textbox = new ParamStringEntry(this, doc, node, changeSignal); - textbox->show(); - hbox->pack_start(*textbox, true, true); - - hbox->show(); - - return dynamic_cast(hbox); -} - -} /* namespace Extension */ -} /* namespace Inkscape */ diff --git a/src/extension/param/string.h b/src/extension/param/string.h deleted file mode 100644 index 7c094d394..000000000 --- a/src/extension/param/string.h +++ /dev/null @@ -1,67 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -#ifndef INK_EXTENSION_PARAMSTRING_H_SEEN -#define INK_EXTENSION_PARAMSTRING_H_SEEN - -/* - * Copyright (C) 2005-2007 Authors: - * Ted Gould - * Johan Engelen * - * Jon A. Cruz - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include "parameter.h" - -namespace Inkscape { -namespace Extension { - -class ParamString : public Parameter { -private: - /** \brief Internal value. This should point to a string that has - been allocated in memory. And should be free'd. */ - gchar * _value; - /** \brief Internal value. This indicates the maximum length of the string. Zero meaning unlimited. - */ - gint _max_length; -public: - ParamString(const gchar * name, - const gchar * text, - const gchar * description, - bool hidden, - int indent, - Inkscape::Extension::Extension * ext, - Inkscape::XML::Node * xml); - ~ParamString() override; - - /** \brief Returns \c _value, with a \i const to protect it. */ - const gchar *get(SPDocument const * /*doc*/, Inkscape::XML::Node const * /*node*/) const { return _value; } - - const gchar * set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node); - - Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) override; - - // Explicitly call superclass version to avoid method being hidden. - void string(std::list &list) const override { return Parameter::string(list); } - - void string(std::string &string) const override; - - void setMaxLength(int maxLength) { _max_length = maxLength; } - int getMaxLength() { return _max_length; } -}; - - -} // namespace Extension -} // namespace Inkscape - -#endif /* INK_EXTENSION_PARAMSTRING_H_SEEN */ - -/* - 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 : diff --git a/src/extension/prefdialog.cpp b/src/extension/prefdialog.cpp deleted file mode 100644 index de58545fb..000000000 --- a/src/extension/prefdialog.cpp +++ /dev/null @@ -1,276 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Authors: - * Ted Gould - * - * Copyright (C) 2005-2008 Authors - * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#include "prefdialog.h" -#include -#include -#include - -#include "ui/dialog-events.h" -#include "xml/repr.h" - -// Used to get SP_ACTIVE_DESKTOP -#include "inkscape.h" -#include "desktop.h" -#include "document.h" -#include "document-undo.h" - -#include "effect.h" -#include "implementation/implementation.h" - -#include "execution-env.h" -#include "param/parameter.h" - - -namespace Inkscape { -namespace Extension { - - -/** \brief Creates a new preference dialog for extension preferences - \param name Name of the Extension whose dialog this is - \param help The help string for the extension (NULL if none) - \param controls The extension specific widgets in the dialog - - This function initializes the dialog with the name of the extension - in the title. It adds a few buttons and sets up handlers for - them. It also places the passed-in widgets into the dialog. -*/ -PrefDialog::PrefDialog (Glib::ustring name, gchar const * help, Gtk::Widget * controls, Effect * effect) : - Gtk::Dialog(_(name.c_str()), true), - _help(help), - _name(name), - _button_ok(nullptr), - _button_cancel(nullptr), - _button_preview(nullptr), - _param_preview(nullptr), - _effect(effect), - _exEnv(nullptr) -{ - this->set_default_size(0,0); // we want the window to be as small as possible instead of clobbering up space - - Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox()); - if (controls == nullptr) { - if (_effect == nullptr) { - std::cout << "AH!!! No controls and no effect!!!" << std::endl; - return; - } - controls = _effect->get_imp()->prefs_effect(_effect, SP_ACTIVE_DESKTOP, &_signal_param_change, nullptr); - _signal_param_change.connect(sigc::mem_fun(this, &PrefDialog::param_change)); - } - - hbox->pack_start(*controls, true, true, 0); - hbox->show(); - - this->get_content_area()->pack_start(*hbox, true, true, 0); - - /* - Gtk::Button * help_button = add_button(Gtk::Stock::HELP, Gtk::RESPONSE_HELP); - if (_help == NULL) - help_button->set_sensitive(false); - */ - _button_cancel = add_button(_effect == nullptr ? _("_Cancel") : _("_Close"), Gtk::RESPONSE_CANCEL); - _button_ok = add_button(_effect == nullptr ? _("_OK") : _("_Apply"), Gtk::RESPONSE_OK); - set_default_response(Gtk::RESPONSE_OK); - _button_ok->grab_focus(); - - if (_effect != nullptr && !_effect->no_live_preview) { - if (_param_preview == nullptr) { - XML::Document * doc = sp_repr_read_mem(live_param_xml, strlen(live_param_xml), nullptr); - if (doc == nullptr) { - std::cout << "Error encountered loading live parameter XML !!!" << std::endl; - return; - } - _param_preview = Parameter::make(doc->root(), _effect); - } - - auto sep = Gtk::manage(new Gtk::Separator()); - sep->show(); - - this->get_content_area()->pack_start(*sep, false, false, Parameter::GUI_BOX_SPACING); - - hbox = Gtk::manage(new Gtk::HBox()); - hbox->set_border_width(Parameter::GUI_BOX_MARGIN); - _button_preview = _param_preview->get_widget(nullptr, nullptr, &_signal_preview); - _button_preview->show(); - hbox->pack_start(*_button_preview, true, true, 0); - hbox->show(); - - this->get_content_area()->pack_start(*hbox, false, false, 0); - - Gtk::Box * hbox = dynamic_cast(_button_preview); - if (hbox != nullptr) { - _checkbox_preview = dynamic_cast(hbox->get_children().front()); - } - - preview_toggle(); - _signal_preview.connect(sigc::mem_fun(this, &PrefDialog::preview_toggle)); - } - - // Set window modality for effects that don't use live preview - if (_effect != nullptr && _effect->no_live_preview) { - set_modal(false); - } - - GtkWidget *dlg = GTK_WIDGET(gobj()); - sp_transientize(dlg); - - return; -} - -PrefDialog::~PrefDialog ( ) -{ - if (_param_preview != nullptr) { - delete _param_preview; - _param_preview = nullptr; - } - - if (_exEnv != nullptr) { - _exEnv->cancel(); - delete _exEnv; - _exEnv = nullptr; - _effect->set_execution_env(_exEnv); - } - - if (_effect != nullptr) { - _effect->set_pref_dialog(nullptr); - } - - return; -} - -#if 0 -/** \brief Runs the dialog - \return The response to the dialog - - This function overrides the run function in the GTKmm dialog - class, but basically it only calls it. This function only - handles the \c Gtk::RESPONSE_HELP return, and in that case it - brings up the help window. All other return values are returned - to the calling function. -*/ -int -PrefDialog::run (void) { - int resp = Gtk::RESPONSE_HELP; - while (resp == Gtk::RESPONSE_HELP) { - resp = Gtk::Dialog::run(); - if (resp == Gtk::RESPONSE_HELP) { - /* - if (_helpDialog == NULL) { - _helpDialog = new HelpDialog(_help); - } - */ - } - } - return resp; -} -#endif - -void -PrefDialog::preview_toggle () { - SPDesktop *desktop = SP_ACTIVE_DESKTOP; - SPDocument *document = SP_ACTIVE_DOCUMENT; - bool modified = document->isModifiedSinceSave(); - if(_param_preview->get_bool(nullptr, nullptr)) { - if (_exEnv == nullptr) { - set_modal(true); - _exEnv = new ExecutionEnv(_effect, SP_ACTIVE_DESKTOP, nullptr, false, false); - _effect->set_execution_env(_exEnv); - _exEnv->run(); - } - } else { - set_modal(false); - if (_exEnv != nullptr) { - _exEnv->cancel(); - _exEnv->undo(); - _exEnv->reselect(); - delete _exEnv; - _exEnv = nullptr; - _effect->set_execution_env(_exEnv); - } - } - document->setModifiedSinceSave(modified); -} - -void -PrefDialog::param_change () { - if (_exEnv != nullptr) { - if (!_effect->loaded()) { - _effect->set_state(Extension::STATE_LOADED); - } - _timersig.disconnect(); - _timersig = Glib::signal_timeout().connect(sigc::mem_fun(this, &PrefDialog::param_timer_expire), - 250, /* ms */ - Glib::PRIORITY_DEFAULT_IDLE); - } - - return; -} - -bool -PrefDialog::param_timer_expire () { - if (_exEnv != nullptr) { - _exEnv->cancel(); - _exEnv->undo(); - _exEnv->reselect(); - _exEnv->run(); - } - - return false; -} - -void -PrefDialog::on_response (int signal) { - if (signal == Gtk::RESPONSE_OK) { - if (_exEnv == nullptr) { - if (_effect != nullptr) { - _effect->effect(SP_ACTIVE_DESKTOP); - } else { - // Shutdown run() - return; - } - } else { - if (_exEnv->wait()) { - _exEnv->commit(); - } else { - _exEnv->undo(); - _exEnv->reselect(); - } - delete _exEnv; - _exEnv = nullptr; - _effect->set_execution_env(_exEnv); - } - } - - if (_param_preview != nullptr) { - _checkbox_preview->set_active(false); - } - - if ((signal == Gtk::RESPONSE_CANCEL || signal == Gtk::RESPONSE_DELETE_EVENT) && _effect != nullptr) { - delete this; - } - return; -} - -#include "internal/clear-n_.h" - -const char * PrefDialog::live_param_xml = "false"; - -}; }; /* namespace Inkscape, Extension */ - -/* - 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 : diff --git a/src/extension/prefdialog.h b/src/extension/prefdialog.h deleted file mode 100644 index 087900fbe..000000000 --- a/src/extension/prefdialog.h +++ /dev/null @@ -1,94 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * Authors: - * Ted Gould - * - * Copyright (C) 2005,2007-2008 Authors - * - * Released under GNU GPL v2+, read the file 'COPYING' for more information. - */ - -#ifndef INKSCAPE_EXTENSION_DIALOG_H__ -#define INKSCAPE_EXTENSION_DIALOG_H__ - -#include -#include -#include - -namespace Gtk { -class CheckButton; -} - -namespace Inkscape { -namespace Extension { -class Effect; -class ExecutionEnv; -class Parameter; - -/** \brief A class to represent the preferences for an extension */ -class PrefDialog : public Gtk::Dialog { - /** \brief Help string if it exists */ - gchar const * _help; - /** \brief Name of the extension */ - Glib::ustring _name; - - /** \brief A pointer to the OK button */ - Gtk::Button * _button_ok; - /** \brief A pointer to the CANCEL button */ - Gtk::Button * _button_cancel; - - /** \brief Button to control live preview */ - Gtk::Widget * _button_preview; - /** \brief Checkbox for the preview */ - Gtk::CheckButton * _checkbox_preview; - - /** \brief Parameter to control live preview */ - Parameter * _param_preview; - - /** \brief XML to define the live effects parameter on the dialog */ - static const char * live_param_xml; - - /** \brief Signal that the user is changing the live effect state */ - sigc::signal _signal_preview; - /** \brief Signal that one of the parameters change */ - sigc::signal _signal_param_change; - - /** \brief If this is the preferences for an effect, the effect - that we're working with. */ - Effect * _effect; - /** \brief If we're executing in preview mode here is the execution - environment for the effect. */ - ExecutionEnv * _exEnv; - - /** \brief The timer used to make it so that parameters don't respond - directly and allows for changes. */ - sigc::connection _timersig; - - void preview_toggle(); - void param_change(); - bool param_timer_expire(); - void on_response (int signal) override; - -public: - PrefDialog (Glib::ustring name, - gchar const * help, - Gtk::Widget * controls = nullptr, - Effect * effect = nullptr); - ~PrefDialog () override; -}; - - -};}; /* namespace Inkscape, Extension */ - -#endif /* INKSCAPE_EXTENSION_DIALOG_H__ */ - -/* - 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 : diff --git a/src/extension/prefdialog/param/bool.cpp b/src/extension/prefdialog/param/bool.cpp new file mode 100644 index 000000000..f304f9aef --- /dev/null +++ b/src/extension/prefdialog/param/bool.cpp @@ -0,0 +1,154 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2005-2007 Authors: + * Ted Gould + * Johan Engelen * + * Jon A. Cruz + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include +#include +#include +#include + +#include "xml/node.h" +#include "extension/extension.h" +#include "bool.h" +#include "preferences.h" + +namespace Inkscape { +namespace Extension { + +ParamBool::ParamBool(const gchar * name, + const gchar * text, + const gchar * description, + bool hidden, + int indent, + Inkscape::Extension::Extension * ext, + Inkscape::XML::Node * xml) + : Parameter(name, text, description, hidden, indent, ext) + , _value(false) +{ + const char * defaultval = nullptr; + if (xml->firstChild() != nullptr) { + defaultval = xml->firstChild()->content(); + } + + if (defaultval != nullptr && (!strcmp(defaultval, "true") || !strcmp(defaultval, "1"))) { + _value = true; + } else { + _value = false; + } + + gchar * pref_name = this->pref_name(); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + _value = prefs->getBool(extension_pref_root + pref_name, _value); + g_free(pref_name); + + return; +} + +bool ParamBool::set( bool in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/ ) +{ + _value = in; + + gchar * prefname = this->pref_name(); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setBool(extension_pref_root + prefname, _value); + g_free(prefname); + + return _value; +} + +bool ParamBool::get(const SPDocument * /*doc*/, const Inkscape::XML::Node * /*node*/) const +{ + return _value; +} + +/** + * A check button which is Param aware. It works with the + * parameter to change it's value as the check button changes + * value. + */ +class ParamBoolCheckButton : public Gtk::CheckButton { +public: + /** + * Initialize the check button. + * This function sets the value of the checkbox to be that of the + * parameter, and then sets up a callback to \c on_toggle. + * + * @param param Which parameter to adjust on changing the check button + */ + ParamBoolCheckButton (ParamBool * param, gchar * label, SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) : + Gtk::CheckButton(label), _pref(param), _doc(doc), _node(node), _changeSignal(changeSignal) { + this->set_active(_pref->get(nullptr, nullptr) /**\todo fix */); + this->signal_toggled().connect(sigc::mem_fun(this, &ParamBoolCheckButton::on_toggle)); + return; + } + + /** + * A function to respond to the check box changing. + * Adjusts the value of the preference to match that in the check box. + */ + void on_toggle (); + +private: + /** Param to change. */ + ParamBool * _pref; + SPDocument * _doc; + Inkscape::XML::Node * _node; + sigc::signal * _changeSignal; +}; + +void ParamBoolCheckButton::on_toggle() +{ + _pref->set(this->get_active(), nullptr /**\todo fix this */, nullptr); + if (_changeSignal != nullptr) { + _changeSignal->emit(); + } + return; +} + +void ParamBool::string(std::string &string) const +{ + if (_value) { + string += "true"; + } else { + string += "false"; + } + + return; +} + +Gtk::Widget *ParamBool::get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) +{ + if (_hidden) { + return nullptr; + } + + auto hbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, Parameter::GUI_PARAM_WIDGETS_SPACING)); + hbox->set_homogeneous(false); + + ParamBoolCheckButton * checkbox = Gtk::manage(new ParamBoolCheckButton(this, _text, doc, node, changeSignal)); + checkbox->show(); + hbox->pack_start(*checkbox, false, false); + + hbox->show(); + + return dynamic_cast(hbox); +} + +} /* 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/extension/prefdialog/param/bool.h b/src/extension/prefdialog/param/bool.h new file mode 100644 index 000000000..9864cac38 --- /dev/null +++ b/src/extension/prefdialog/param/bool.h @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#ifndef SEEN_INK_EXTENSION_PARAMBOOL_H +#define SEEN_INK_EXTENSION_PARAMBOOL_H +/* + * Copyright (C) 2005-2007 Authors: + * Ted Gould + * Johan Engelen * + * Jon A. Cruz + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include "parameter.h" + +class SPDocument; + +namespace Gtk { +class Widget; +} + +namespace Inkscape { +namespace XML { +class Node; +} + +namespace Extension { + +/** + * A boolean parameter. + */ +class ParamBool : public Parameter { +public: + + /** + * Use the superclass' allocator and set the \c _value. + */ + ParamBool(const gchar * name, + const gchar * text, + const gchar * description, + bool hidden, + int indent, + Inkscape::Extension::Extension * ext, + Inkscape::XML::Node * xml); + + /** + * Returns the current state/value. + */ + bool get(const SPDocument *doc, const Inkscape::XML::Node *node) const; + + /** + * A function to set the state/value. + * 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. + * + * @param in The value to set to + * @param doc A document that should be used to set the value. + * @param node The node where the value may be placed + */ + bool set(bool in, SPDocument * doc, Inkscape::XML::Node * node); + + /** + * Creates a bool check button for a bool parameter. + * Builds a hbox with a label and a check button in it. + */ + Gtk::Widget *get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) override; + + // Explicitly call superclass version to avoid method being hidden. + void string(std::list &list) const override { return Parameter::string(list); } + + /** + * Appends 'true' or 'false'. + * @todo investigate. Returning a value that can then be appended would probably work better/safer. + */ + void string(std::string &string) const override; + +private: + /** Internal value. */ + bool _value; +}; + +} // namespace Extension +} // namespace Inkscape + +#endif // SEEN_INK_EXTENSION_PARAMBOOL_H + +/* + 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 : diff --git a/src/extension/prefdialog/param/color.cpp b/src/extension/prefdialog/param/color.cpp new file mode 100644 index 000000000..ed9940154 --- /dev/null +++ b/src/extension/prefdialog/param/color.cpp @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2005-2007 Authors: + * Ted Gould + * Johan Engelen + * Christopher Brown + * Jon A. Cruz + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include +#include + +#include +#include +#include + +#include + +#include "extension/extension.h" +#include "color.h" + +#include +#include "ui/widget/color-notebook.h" +#include "preferences.h" + +namespace Inkscape { +namespace Extension { + +ParamColor::~ParamColor() +{ + _color_changed.disconnect(); +} + +guint32 ParamColor::set( guint32 in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/ ) +{ + _color_changed.block(true); + _color.setValue(in); + _color_changed.block(false); + + gchar * prefname = this->pref_name(); + std::string value; + string(value); + + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setString(extension_pref_root + prefname, value); + g_free(prefname); + + return in; +} + +ParamColor::ParamColor(const gchar * name, + const gchar * text, + const gchar * description, + bool hidden, + int indent, + Inkscape::Extension::Extension * ext, + Inkscape::XML::Node * xml) + : Parameter(name, text, description, hidden, indent, ext) + , _changeSignal(nullptr) +{ + const char * defaulthex = nullptr; + if (xml->firstChild() != nullptr) + defaulthex = xml->firstChild()->content(); + + gchar * pref_name = this->pref_name(); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Glib::ustring paramval = prefs->getString(extension_pref_root + pref_name); + g_free(pref_name); + + if (!paramval.empty()) + defaulthex = paramval.data(); + + if (defaulthex) { + _color.setValue(atoi(defaulthex)); + } + _color_changed = _color.signal_changed.connect(sigc::mem_fun(this, &ParamColor::_onColorChanged)); + +} + +void ParamColor::string(std::string &string) const +{ + char str[16]; + snprintf(str, 16, "%i", _color.value()); + string += str; +} + +Gtk::Widget *ParamColor::get_widget( SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/, sigc::signal * changeSignal ) +{ + using Inkscape::UI::Widget::ColorNotebook; + + if (_hidden) return nullptr; + + if (changeSignal) { + _changeSignal = new sigc::signal(*changeSignal); + } + + if (_color.value() < 1) { + _color_changed.block(true); + _color.setValue(0xFF000000); + _color_changed.block(false); + } + + Gtk::HBox *hbox = Gtk::manage(new Gtk::HBox(false, Parameter::GUI_PARAM_WIDGETS_SPACING)); + Gtk::Widget *selector = Gtk::manage(new ColorNotebook(_color)); + hbox->pack_start(*selector, true, true, 0); + selector->show(); + hbox->show(); + return hbox; +} + +void ParamColor::_onColorChanged() +{ + if (_changeSignal) + _changeSignal->emit(); +} + +}; /* namespace Extension */ +}; /* namespace Inkscape */ diff --git a/src/extension/prefdialog/param/color.h b/src/extension/prefdialog/param/color.h new file mode 100644 index 000000000..c2d3c2ccb --- /dev/null +++ b/src/extension/prefdialog/param/color.h @@ -0,0 +1,74 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#ifndef SEEN_INK_EXTENSION_PARAMCOLOR_H__ +#define SEEN_INK_EXTENSION_PARAMCOLOR_H__ +/* + * Copyright (C) 2005-2007 Authors: + * Ted Gould + * Johan Engelen * + * Jon A. Cruz + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include "parameter.h" +#include "ui/selected-color.h" + +class SPDocument; + +namespace Gtk { +class Widget; +} + +namespace Inkscape { +namespace XML { +class Node; +} + +namespace Extension { + +class ParamColor : public Parameter { +private: + void _onColorChanged(); + + Inkscape::UI::SelectedColor _color; + sigc::connection _color_changed; +public: + ParamColor(const gchar * name, + const gchar * text, + const gchar * description, + bool hidden, + int indent, + Inkscape::Extension::Extension * ext, + Inkscape::XML::Node * xml); + ~ParamColor() override; + + /** Returns \c _value, with a \i const to protect it. */ + guint32 get( SPDocument const * /*doc*/, Inkscape::XML::Node const * /*node*/ ) const { return _color.value(); } + + guint32 set (guint32 in, SPDocument * doc, Inkscape::XML::Node * node); + + Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) override; + + // Explicitly call superclass version to avoid method being hidden. + void string(std::list &list) const override { return Parameter::string(list); } + + void string (std::string &string) const override; + + sigc::signal * _changeSignal; + +}; // class ParamColor + +} // namespace Extension +} // namespace Inkscape + +#endif // SEEN_INK_EXTENSION_PARAMCOLOR_H__ + +/* + 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 : diff --git a/src/extension/prefdialog/param/description.cpp b/src/extension/prefdialog/param/description.cpp new file mode 100644 index 000000000..60e2d02c8 --- /dev/null +++ b/src/extension/prefdialog/param/description.cpp @@ -0,0 +1,134 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2005-2007 Authors: + * Ted Gould + * Johan Engelen * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#ifdef linux // does the dollar sign need escaping when passed as string parameter? +# define ESCAPE_DOLLAR_COMMANDLINE +#endif + +#include +#include +#include +#include +#include + +#include "xml/node.h" +#include "extension/extension.h" +#include "description.h" + +namespace Inkscape { +namespace Extension { + + +/** \brief Initialize the object, to do that, copy the data. */ +ParamDescription::ParamDescription(const gchar * name, + const gchar * text, + const gchar * description, + bool hidden, + int indent, + Inkscape::Extension::Extension * ext, + Inkscape::XML::Node * xml, + AppearanceMode mode) + : Parameter(name, text, description, hidden, indent, ext) + , _value(nullptr) + , _mode(mode) +{ + // construct the text content by concatenating all (non-empty) text nodes, + // removing all other nodes (e.g. comment nodes) and replacing elements with "
" + Glib::ustring value; + Inkscape::XML::Node * cur_child = xml->firstChild(); + while (cur_child != nullptr) { + if (cur_child->type() == XML::TEXT_NODE && cur_child->content() != nullptr) { + value += cur_child->content(); + } else if (cur_child->type() == XML::ELEMENT_NODE && !g_strcmp0(cur_child->name(), "extension:br")) { + value += "
"; + } + cur_child = cur_child->next(); + } + + // if there is no text content we can return immediately (the description will be invisible) + if (value == Glib::ustring("")) { + return; + } + + // do replacements in the source string to account for the attribute xml:space="preserve" + // (those should match replacements potentially performed by xgettext to allow for proper translation) + if (g_strcmp0(xml->attribute("xml:space"), "preserve") == 0) { + // xgettext copies the source string verbatim in this case, so no changes needed + } else { + // remove all whitespace from start/end of string and replace intermediate whitespace with a single space + value = Glib::Regex::create("^\\s+|\\s+$")->replace_literal(value, 0, "", (Glib::RegexMatchFlags)0); + value = Glib::Regex::create("\\s+")->replace_literal(value, 0, " ", (Glib::RegexMatchFlags)0); + } + + // translate if underscored version (_param) was used + if (g_str_has_prefix(xml->name(), "extension:_")) { + const gchar * context = xml->attribute("msgctxt"); + if (context != nullptr) { + value = g_dpgettext2(nullptr, context, value.c_str()); + } else { + value = _(value.c_str()); + } + } + + // finally replace all remaining
with a real newline character + value = Glib::Regex::create("
")->replace_literal(value, 0, "\n", (Glib::RegexMatchFlags)0); + + _value = g_strdup(value.c_str()); + + return; +} + +/** \brief Create a label for the description */ +Gtk::Widget * +ParamDescription::get_widget (SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/, sigc::signal * /*changeSignal*/) +{ + if (_hidden) { + return nullptr; + } + if (_value == nullptr) { + return nullptr; + } + + Glib::ustring newtext = _value; + + Gtk::Label * label = Gtk::manage(new Gtk::Label()); + if (_mode == HEADER) { + label->set_markup(Glib::ustring("") + Glib::Markup::escape_text(newtext) + Glib::ustring("")); + label->set_margin_top(5); + label->set_margin_bottom(5); + } else if (_mode == URL) { + Glib::ustring escaped_url = Glib::Markup::escape_text(newtext); + label->set_markup(Glib::ustring::compose("%1", escaped_url)); + } else { + label->set_text(newtext); + } + label->set_line_wrap(); + label->set_xalign(0); + + // TODO: Ugly "fix" for gtk3 width/height calculation of labels. + // - If not applying any limits long labels will make the window grow horizontally until it uses up + // most of the available space (i.e. most of the screen area) which is ridicously wide + // - By using "set_default_size(0,0)" in prefidalog.cpp we tell the window to shrink as much as possible, + // however this can result in a much to narrow dialog instead and much unnecessary wrapping + // - Here we set a lower limit of GUI_MAX_LINE_LENGTH characters per line that long texts will always use + // This means texts can not shrink anymore (they can still grow, though) and it's also necessary + // to prevent https://bugzilla.gnome.org/show_bug.cgi?id=773572 + int len = newtext.length(); + label->set_width_chars(len > Parameter::GUI_MAX_LINE_LENGTH ? Parameter::GUI_MAX_LINE_LENGTH : len); + + label->show(); + + Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox()); + hbox->pack_start(*label, true, true); + hbox->show(); + + return hbox; +} + +} /* namespace Extension */ +} /* namespace Inkscape */ diff --git a/src/extension/prefdialog/param/description.h b/src/extension/prefdialog/param/description.h new file mode 100644 index 000000000..822370b82 --- /dev/null +++ b/src/extension/prefdialog/param/description.h @@ -0,0 +1,63 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#ifndef __INK_EXTENSION_PARAMDESCRIPTION_H__ +#define __INK_EXTENSION_PARAMDESCRIPTION_H__ + +/* + * Copyright (C) 2005-2007 Authors: + * Ted Gould + * Johan Engelen * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include "parameter.h" + +class SPDocument; + +namespace Gtk { + class Widget; +} + +namespace Inkscape { +namespace Xml { + class Node; +} + +namespace Extension { + +/** \brief A description parameter */ +class ParamDescription : public Parameter { +public: + enum AppearanceMode { + DESCRIPTION, HEADER, URL + }; + ParamDescription(const gchar * name, + const gchar * text, + const gchar * description, + bool hidden, + int indent, + Inkscape::Extension::Extension * ext, + Inkscape::XML::Node * xml, + AppearanceMode mode); + + Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) override; +private: + /** \brief Internal value. */ + gchar * _value; + AppearanceMode _mode; +}; + +} /* namespace Extension */ +} /* namespace Inkscape */ + +#endif /* __INK_EXTENSION_PARAMDESCRIPTION_H__ */ + +/* + 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 : diff --git a/src/extension/prefdialog/param/enum.cpp b/src/extension/prefdialog/param/enum.cpp new file mode 100644 index 000000000..5ba3e5772 --- /dev/null +++ b/src/extension/prefdialog/param/enum.cpp @@ -0,0 +1,268 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** \file + * extension parameter for enumerations. + * + * It uses a Gtk:ComboBoxText widget in the extension UI. + */ + +/* + * Author: + * Johan Engelen + * Jon A. Cruz + * + * Copyright (C) 2006-2007 Johan Engelen + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include +#include +#include + +#include "xml/node.h" +#include "extension/extension.h" +#include "enum.h" +#include "preferences.h" + +namespace Inkscape { +namespace Extension { + +ParamComboBox::ParamComboBox(const gchar * name, + const gchar * text, + const gchar * description, + bool hidden, + int indent, + Inkscape::Extension::Extension * ext, + Inkscape::XML::Node * xml) + : Parameter(name, text, description, hidden, indent, ext) + , _value(nullptr) +{ + const char *xmlval = nullptr; // the value stored in XML + + if (xml != nullptr) { + // Read XML tree to add enumeration items: + for (Inkscape::XML::Node *node = xml->firstChild(); node; node = node->next()) { + char const * chname = node->name(); + if (!strcmp(chname, INKSCAPE_EXTENSION_NS "item") || !strcmp(chname, INKSCAPE_EXTENSION_NS "_item")) { + Glib::ustring newtext, newvalue; + const char * contents = nullptr; + if (node->firstChild()) { + contents = node->firstChild()->content(); + } + if (contents != nullptr) { + // don't translate when 'item' but do translate when '_item' + // NOTE: internal extensions use build_from_mem and don't need _item but + // still need to include if are to be localized + if (!strcmp(chname, INKSCAPE_EXTENSION_NS "_item")) { + if (node->attribute("msgctxt") != nullptr) { + newtext = g_dpgettext2(nullptr, node->attribute("msgctxt"), contents); + } else { + newtext = _(contents); + } + } else { + newtext = contents; + } + } else + continue; + + const char * val = node->attribute("value"); + if (val != nullptr) { + newvalue = val; + } else { + newvalue = contents; + } + + if ( (!newtext.empty()) && (!newvalue.empty()) ) { // logical error if this is not true here + choices.push_back(new enumentry(newvalue, newtext) ); + } + } + } + + // Initialize _value with the default value from xml + // for simplicity : default to the contents of the first xml-child + if (xml->firstChild() && xml->firstChild()->firstChild()) { + xmlval = xml->firstChild()->attribute("value"); + } + } + + gchar * pref_name = this->pref_name(); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Glib::ustring paramval = prefs ? prefs->getString(extension_pref_root + pref_name) : ""; + g_free(pref_name); + + if (!paramval.empty()) { + _value = g_strdup(paramval.data()); + } else if (xmlval) { + _value = g_strdup(xmlval); + } +} + +ParamComboBox::~ParamComboBox () +{ + //destroy choice strings + for (auto i:choices) { + delete i; + } + g_free(_value); +} + + +/** + * A function to set the \c _value. + * + * This function sets ONLY 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(). + * + * @param in The value to set. + * @param doc A document that should be used to set the value. + * @param node The node where the value may be placed. + */ +const gchar *ParamComboBox::set(const gchar * in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/) +{ + if (in == nullptr) { + return nullptr; /* Can't have NULL string */ + } + + Glib::ustring settext; + for (auto entr:choices) { + if ( !entr->text.compare(in) ) { + settext = entr->value; + break; // break out of for loop + } + } + if (!settext.empty()) { + if (_value != nullptr) { + g_free(_value); + } + _value = g_strdup(settext.data()); + gchar * prefname = this->pref_name(); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setString(extension_pref_root + prefname, _value); + g_free(prefname); + } + + return _value; +} + +/** + * function to test if \c text is selectable + */ +bool ParamComboBox::contains(const gchar * text, SPDocument const * /*doc*/, Inkscape::XML::Node const * /*node*/) const +{ + if (text == nullptr) { + return false; /* Can't have NULL string */ + } + + for (auto entr:choices) { + if ( !entr->text.compare(text) ) + return true; + } + // if we did not find the text in this ParamComboBox: + return false; +} + +void +ParamComboBox::changed () { + +} + +void ParamComboBox::string(std::string &string) const +{ + string += _value; +} + + + + +/** A special category of Gtk::Entry to handle string parameteres. */ +class ParamComboBoxEntry : public Gtk::ComboBoxText { +private: + ParamComboBox * _pref; + SPDocument * _doc; + Inkscape::XML::Node * _node; + sigc::signal * _changeSignal; +public: + /** + * Build a string preference for the given parameter. + * @param pref Where to get the string from, and where to put it + * when it changes. + */ + ParamComboBoxEntry (ParamComboBox * pref, SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) : + Gtk::ComboBoxText(), _pref(pref), _doc(doc), _node(node), _changeSignal(changeSignal) { + this->signal_changed().connect(sigc::mem_fun(this, &ParamComboBoxEntry::changed)); + }; + void changed (); +}; + +/** + * Respond to the text box changing. + * + * This function responds to the box changing by grabbing the value + * from the text box and putting it in the parameter. + */ +void +ParamComboBoxEntry::changed () +{ + Glib::ustring data = this->get_active_text(); + _pref->set(data.c_str(), _doc, _node); + if (_changeSignal != nullptr) { + _changeSignal->emit(); + } +} + +/** + * Creates a combobox widget for an enumeration parameter. + */ +Gtk::Widget *ParamComboBox::get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) +{ + if (_hidden) { + return nullptr; + } + + Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, Parameter::GUI_PARAM_WIDGETS_SPACING)); + Gtk::Label * label = Gtk::manage(new Gtk::Label(_text, Gtk::ALIGN_START)); + label->show(); + hbox->pack_start(*label, false, false); + + ParamComboBoxEntry * combo = Gtk::manage(new ParamComboBoxEntry(this, doc, node, changeSignal)); + // add choice strings: + Glib::ustring settext; + for (auto entr:choices) { + Glib::ustring text = entr->text; + combo->append(text); + + if ( _value && !entr->value.compare(_value) ) { + settext = entr->text; + } + } + if (!settext.empty()) { + combo->set_active_text(settext); + } + + combo->show(); + hbox->pack_start(*combo, true, true); + + hbox->show(); + + return dynamic_cast(hbox); +} + + +} // 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 : diff --git a/src/extension/prefdialog/param/enum.h b/src/extension/prefdialog/param/enum.h new file mode 100644 index 000000000..329bb26f9 --- /dev/null +++ b/src/extension/prefdialog/param/enum.h @@ -0,0 +1,106 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#ifndef INK_EXTENSION_PARAMENUM_H_SEEN +#define INK_EXTENSION_PARAMENUM_H_SEEN + +/** \file + * Enumeration parameter for extensions. + */ + +/* + * Authors: + * Johan Engelen + * Jon A. Cruz + * + * Copyright (C) 2006-2007 Johan Engelen + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include + +#include "parameter.h" +#include "document.h" + +namespace Gtk { +class Widget; +} + +namespace Inkscape { +namespace Extension { + +class Extension; + + +// \brief A class to represent a notebookparameter of an extension +class ParamComboBox : public Parameter { +private: + /** \brief Internal value. This should point to a string that has + been allocated in memory. And should be free'd. + It is the value of the current selected string */ + gchar * _value; + + /* For internal use only. + * Note that value and text MUST be non-NULL. + * This is ensured by newing only at one location in the code where non-NULL checks are made. + */ + class enumentry { + public: + enumentry (Glib::ustring &val, Glib::ustring &text) : + value(val), + text(text) + {} + + Glib::ustring value; + Glib::ustring text; + }; + + std::vector choices; /**< A table to store the choice strings */ + +public: + ParamComboBox(const gchar * name, + const gchar * text, + const gchar * description, + bool hidden, + int indent, + Inkscape::Extension::Extension * ext, + Inkscape::XML::Node * xml); + ~ParamComboBox() override; + + Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) override; + + // Explicitly call superclass version to avoid method being hidden. + void string(std::list &list) const override { return Parameter::string(list); } + + void string(std::string &string) const override; + + gchar const *get(SPDocument const * /*doc*/, Inkscape::XML::Node const * /*node*/) const { return _value; } + + const gchar * set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node); + + /** + * @returns true if text is part of this enum + */ + bool contains(const gchar * text, SPDocument const * /*doc*/, Inkscape::XML::Node const * /*node*/) const; + + void changed (); +}; /* class ParamComboBox */ + + + + + +} /* namespace Extension */ +} /* namespace Inkscape */ + +#endif /* INK_EXTENSION_PARAMENUM_H_SEEN */ + +/* + 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 : diff --git a/src/extension/prefdialog/param/float.cpp b/src/extension/prefdialog/param/float.cpp new file mode 100644 index 000000000..661c533ca --- /dev/null +++ b/src/extension/prefdialog/param/float.cpp @@ -0,0 +1,205 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2005-2007 Authors: + * Ted Gould + * Johan Engelen * + * Jon A. Cruz + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include +#include +#include +#include "ui/widget/spinbutton.h" +#include "ui/widget/spin-scale.h" + +#include "xml/node.h" +#include "extension/extension.h" +#include "preferences.h" +#include "./float.h" + +namespace Inkscape { +namespace Extension { + + +/** Use the superclass' allocator and set the \c _value. */ +ParamFloat::ParamFloat(const gchar * name, + const gchar * text, + const gchar * description, + bool hidden, + int indent, + Inkscape::Extension::Extension * ext, + Inkscape::XML::Node * xml, + AppearanceMode mode) + : Parameter(name, text, description, hidden, indent, ext) + , _value(0.0) + , _mode(mode) + , _min(0.0) + , _max(10.0) +{ + const gchar * defaultval = nullptr; + if (xml->firstChild() != nullptr) { + defaultval = xml->firstChild()->content(); + } + if (defaultval != nullptr) { + _value = g_ascii_strtod (defaultval,nullptr); + } + + const char * maxval = xml->attribute("max"); + if (maxval != nullptr) { + _max = g_ascii_strtod (maxval,nullptr); + } + + const char * minval = xml->attribute("min"); + if (minval != nullptr) { + _min = g_ascii_strtod (minval,nullptr); + } + + _precision = 1; + const char * precision = xml->attribute("precision"); + if (precision != nullptr) { + _precision = atoi(precision); + } + + /* We're handling this by just killing both values */ + if (_max < _min) { + _max = 10.0; + _min = 0.0; + } + + gchar * pref_name = this->pref_name(); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + _value = prefs->getDouble(extension_pref_root + pref_name, _value); + g_free(pref_name); + + // std::cout << "New Float:: value: " << _value << " max: " << _max << " min: " << _min << std::endl; + + if (_value > _max) { + _value = _max; + } + if (_value < _min) { + _value = _min; + } + + return; +} + +/** + * A function to set the \c _value. + * + * 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. + * + * @param in The value to set to. + * @param doc A document that should be used to set the value. + * @param node The node where the value may be placed. + */ +float ParamFloat::set(float in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/) +{ + _value = in; + if (_value > _max) { + _value = _max; + } + if (_value < _min) { + _value = _min; + } + + gchar * prefname = this->pref_name(); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setDouble(extension_pref_root + prefname, _value); + g_free(prefname); + + return _value; +} + +void ParamFloat::string(std::string &string) const +{ + char startstring[G_ASCII_DTOSTR_BUF_SIZE]; + g_ascii_dtostr(startstring, G_ASCII_DTOSTR_BUF_SIZE, _value); + string += startstring; + return; +} + +/** A class to make an adjustment that uses Extension params. */ +class ParamFloatAdjustment : public Gtk::Adjustment { + /** The parameter to adjust. */ + ParamFloat * _pref; + SPDocument * _doc; + Inkscape::XML::Node * _node; + sigc::signal * _changeSignal; +public: + /** Make the adjustment using an extension and the string + describing the parameter. */ + ParamFloatAdjustment (ParamFloat * param, SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) : + Gtk::Adjustment(0.0, param->min(), param->max(), 0.1, 1.0, 0), _pref(param), _doc(doc), _node(node), _changeSignal(changeSignal) { + this->set_value(_pref->get(nullptr, nullptr) /* \todo fix */); + this->signal_value_changed().connect(sigc::mem_fun(this, &ParamFloatAdjustment::val_changed)); + return; + }; + + void val_changed (); +}; /* class ParamFloatAdjustment */ + +/** + * A function to respond to the value_changed signal from the adjustment. + * + * This function just grabs the value from the adjustment and writes + * it to the parameter. Very simple, but yet beautiful. + */ +void ParamFloatAdjustment::val_changed() +{ + //std::cout << "Value Changed to: " << this->get_value() << std::endl; + _pref->set(this->get_value(), _doc, _node); + if (_changeSignal != nullptr) { + _changeSignal->emit(); + } + return; +} + +/** + * Creates a Float Adjustment for a float parameter. + * + * Builds a hbox with a label and a float adjustment in it. + */ +Gtk::Widget * ParamFloat::get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) +{ + if (_hidden) { + return nullptr; + } + + Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, Parameter::GUI_PARAM_WIDGETS_SPACING)); + + auto pfa = new ParamFloatAdjustment(this, doc, node, changeSignal); + Glib::RefPtr fadjust(pfa); + + if (_mode == FULL) { + + Glib::ustring text; + if (_text != nullptr) + text = _text; + UI::Widget::SpinScale *scale = new UI::Widget::SpinScale(text, fadjust, _precision); + scale->set_size_request(400, -1); + scale->show(); + hbox->pack_start(*scale, true, true); + + } + else if (_mode == MINIMAL) { + + Gtk::Label * label = Gtk::manage(new Gtk::Label(_text, Gtk::ALIGN_START)); + label->show(); + hbox->pack_start(*label, true, true); + + auto spin = Gtk::manage(new Inkscape::UI::Widget::SpinButton(fadjust, 0.1, _precision)); + spin->show(); + hbox->pack_start(*spin, false, false); + } + + hbox->show(); + + return dynamic_cast(hbox); +} + + +} /* namespace Extension */ +} /* namespace Inkscape */ diff --git a/src/extension/prefdialog/param/float.h b/src/extension/prefdialog/param/float.h new file mode 100644 index 000000000..c1d0f0f79 --- /dev/null +++ b/src/extension/prefdialog/param/float.h @@ -0,0 +1,83 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#ifndef INK_EXTENSION_PARAMFLOAT_H_SEEN +#define INK_EXTENSION_PARAMFLOAT_H_SEEN + +/* + * Copyright (C) 2005-2007 Authors: + * Ted Gould + * Johan Engelen * + * Jon A. Cruz + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include "parameter.h" + +class SPDocument; + +namespace Gtk { +class Widget; +} + +namespace Inkscape { +namespace XML { +class Node; +} + +namespace Extension { + +class ParamFloat : public Parameter { +public: + enum AppearanceMode { + FULL, MINIMAL + }; + ParamFloat(const gchar * name, + const gchar * text, + const gchar * description, + bool hidden, + int indent, + Inkscape::Extension::Extension * ext, + Inkscape::XML::Node * xml, + AppearanceMode mode); + + /** Returns \c _value. */ + float get(const SPDocument * /*doc*/, const Inkscape::XML::Node * /*node*/) const { return _value; } + + float set (float in, SPDocument * doc, Inkscape::XML::Node * node); + + float max () { return _max; } + + float min () { return _min; } + + float precision () { return _precision; } + + Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) override; + + // Explicitly call superclass version to avoid method being hidden. + void string(std::list &list) const override { return Parameter::string(list); } + + void string(std::string &string) const override; + +private: + /** Internal value. */ + float _value; + AppearanceMode _mode; + float _min; + float _max; + int _precision; +}; + +} /* namespace Extension */ +} /* namespace Inkscape */ + +#endif /* INK_EXTENSION_PARAMFLOAT_H_SEEN */ + +/* + 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 : diff --git a/src/extension/prefdialog/param/int.cpp b/src/extension/prefdialog/param/int.cpp new file mode 100644 index 000000000..1c41c0834 --- /dev/null +++ b/src/extension/prefdialog/param/int.cpp @@ -0,0 +1,201 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2005-2007 Authors: + * Ted Gould + * Johan Engelen * + * Jon A. Cruz + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include +#include +#include +#include "ui/widget/spinbutton.h" +#include "ui/widget/spin-scale.h" + +#include "xml/node.h" +#include "extension/extension.h" +#include "preferences.h" +#include "int.h" + +namespace Inkscape { +namespace Extension { + + +/** Use the superclass' allocator and set the \c _value. */ +ParamInt::ParamInt(const gchar * name, + const gchar * text, + const gchar * description, + bool hidden, + int indent, + Inkscape::Extension::Extension * ext, + Inkscape::XML::Node * xml, + AppearanceMode mode) + : Parameter(name, text, description, hidden, indent, ext) + , _value(0) + , _mode(mode) + , _min(0) + , _max(10) +{ + const char * defaultval = nullptr; + if (xml->firstChild() != nullptr) { + defaultval = xml->firstChild()->content(); + } + if (defaultval != nullptr) { + _value = atoi(defaultval); + } + + const char * maxval = xml->attribute("max"); + if (maxval != nullptr) { + _max = atoi(maxval); + } + + const char * minval = xml->attribute("min"); + if (minval != nullptr) { + _min = atoi(minval); + } + /* We're handling this by just killing both values */ + if (_max < _min) { + _max = 10; + _min = 0; + } + + gchar *pref_name = this->pref_name(); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + _value = prefs->getInt(extension_pref_root + pref_name, _value); + g_free(pref_name); + + // std::cout << "New Int:: value: " << _value << " max: " << _max << " min: " << _min << std::endl; + + if (_value > _max) { + _value = _max; + } + if (_value < _min) { + _value = _min; + } +} + +/** + * A function to set the \c _value. + * 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. + * + * @param in The value to set to. + * @param doc A document that should be used to set the value. + * @param node The node where the value may be placed. + */ +int ParamInt::set(int in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/) +{ + _value = in; + if (_value > _max) { + _value = _max; + } + if (_value < _min) { + _value = _min; + } + + gchar * prefname = this->pref_name(); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setInt(extension_pref_root + prefname, _value); + g_free(prefname); + + return _value; +} + +/** A class to make an adjustment that uses Extension params. */ +class ParamIntAdjustment : public Gtk::Adjustment { + /** The parameter to adjust. */ + ParamInt * _pref; + SPDocument * _doc; + Inkscape::XML::Node * _node; + sigc::signal * _changeSignal; +public: + /** Make the adjustment using an extension and the string + describing the parameter. */ + ParamIntAdjustment (ParamInt * param, SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) : + Gtk::Adjustment(0.0, param->min(), param->max(), 1.0, 10.0, 0), _pref(param), _doc(doc), _node(node), _changeSignal(changeSignal) { + this->set_value(_pref->get(nullptr, nullptr) /* \todo fix */); + this->signal_value_changed().connect(sigc::mem_fun(this, &ParamIntAdjustment::val_changed)); + }; + + void val_changed (); +}; /* class ParamIntAdjustment */ + +/** + * A function to respond to the value_changed signal from the adjustment. + * + * This function just grabs the value from the adjustment and writes + * it to the parameter. Very simple, but yet beautiful. + */ +void ParamIntAdjustment::val_changed() +{ + //std::cout << "Value Changed to: " << this->get_value() << std::endl; + _pref->set((int)this->get_value(), _doc, _node); + if (_changeSignal != nullptr) { + _changeSignal->emit(); + } +} + +/** + * Creates a Int Adjustment for a int parameter. + * + * Builds a hbox with a label and a int adjustment in it. + */ +Gtk::Widget * +ParamInt::get_widget (SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) +{ + if (_hidden) { + return nullptr; + } + + Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, Parameter::GUI_PARAM_WIDGETS_SPACING)); + + auto pia = new ParamIntAdjustment(this, doc, node, changeSignal); + Glib::RefPtr fadjust(pia); + + if (_mode == FULL) { + + Glib::ustring text; + if (_text != nullptr) + text = _text; + UI::Widget::SpinScale *scale = new UI::Widget::SpinScale(text, fadjust, 0); + scale->set_size_request(400, -1); + scale->show(); + hbox->pack_start(*scale, true, true); + } + else if (_mode == MINIMAL) { + Gtk::Label * label = Gtk::manage(new Gtk::Label(_text, Gtk::ALIGN_START)); + label->show(); + hbox->pack_start(*label, true, true); + + auto spin = Gtk::manage(new Inkscape::UI::Widget::SpinButton(fadjust, 1.0, 0)); + spin->show(); + hbox->pack_start(*spin, false, false); + } + + hbox->show(); + + return dynamic_cast(hbox); +} + +void ParamInt::string(std::string &string) const +{ + char startstring[32]; + sprintf(startstring, "%d", _value); + string += startstring; +} + +} // 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/extension/prefdialog/param/int.h b/src/extension/prefdialog/param/int.h new file mode 100644 index 000000000..fac481267 --- /dev/null +++ b/src/extension/prefdialog/param/int.h @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#ifndef INK_EXTENSION_PARAMINT_H_SEEN +#define INK_EXTENSION_PARAMINT_H_SEEN + +/* + * Copyright (C) 2005-2007 Authors: + * Ted Gould + * Johan Engelen * + * Jon A. Cruz + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include "parameter.h" + +class SPDocument; + +namespace Gtk { +class Widget; +} + +namespace Inkscape { +namespace XML { +class Node; +} + +namespace Extension { + +class ParamInt : public Parameter { +public: + enum AppearanceMode { + FULL, MINIMAL + }; + ParamInt(const gchar * name, + const gchar * text, + const gchar * description, + bool hidden, + int indent, + Inkscape::Extension::Extension * ext, + Inkscape::XML::Node * xml, + AppearanceMode mode); + + /** Returns \c _value. */ + int get(const SPDocument * /*doc*/, const Inkscape::XML::Node * /*node*/) const { return _value; } + + int set (int in, SPDocument * doc, Inkscape::XML::Node * node); + + int max () { return _max; } + + int min () { return _min; } + + Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) override; + + // Explicitly call superclass version to avoid method being hidden. + void string(std::list &list) const override { return Parameter::string(list); } + + void string(std::string &string) const override; + +private: + /** Internal value. */ + int _value; + AppearanceMode _mode; + int _min; + int _max; +}; + +} /* namespace Extension */ +} /* namespace Inkscape */ + +#endif /* INK_EXTENSION_PARAMINT_H_SEEN */ + +/* + 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 : diff --git a/src/extension/prefdialog/param/notebook.cpp b/src/extension/prefdialog/param/notebook.cpp new file mode 100644 index 000000000..838c09d5b --- /dev/null +++ b/src/extension/prefdialog/param/notebook.cpp @@ -0,0 +1,413 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** \file + * Notebook and NotebookPage parameters for extensions. + */ + +/* + * Authors: + * Johan Engelen + * Jon A. Cruz + * + * Copyright (C) 2006 Author + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include +#include +#include +#include + +#include + +#include + +#include +#include "preferences.h" + +#include "notebook.h" + +/** + * The root directory in the preferences database for extension + * related parameters. + */ +#define PREF_DIR "extensions" + +namespace Inkscape { +namespace Extension { + + +ParamNotebook::ParamNotebookPage::ParamNotebookPage(const gchar * name, + const gchar * text, + const gchar * description, + bool hidden, + Inkscape::Extension::Extension * ext, + Inkscape::XML::Node * xml) + : Parameter(name, text, description, hidden, /*indent*/ 0, ext) +{ + + // Read XML to build page + if (xml != nullptr) { + Inkscape::XML::Node *child_repr = xml->firstChild(); + while (child_repr != nullptr) { + char const * chname = child_repr->name(); + if (!strncmp(chname, INKSCAPE_EXTENSION_NS_NC, strlen(INKSCAPE_EXTENSION_NS_NC))) { + chname += strlen(INKSCAPE_EXTENSION_NS); + } + 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 != nullptr) parameters.push_back(param); + } + child_repr = child_repr->next(); + } + } +} + +ParamNotebook::ParamNotebookPage::~ParamNotebookPage () +{ + //destroy parameters + for (auto param:parameters) { + delete param; + } +} + +/** Return the value as a string. */ +void ParamNotebook::ParamNotebookPage::paramString(std::list &list) +{ + for (auto param:parameters) { + param->string(list); + } +} + + +/** + \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 + \todo the 'gui-hidden' attribute is read but not used! + + 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. +*/ +ParamNotebook::ParamNotebookPage * +ParamNotebook::ParamNotebookPage::makepage (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext) +{ + const char * name; + const char * text; + const char * description; + bool hidden = false; + const char * hide; + + name = in_repr->attribute("name"); + text = in_repr->attribute("gui-text"); + if (text == nullptr) + text = in_repr->attribute("_gui-text"); + description = in_repr->attribute("gui-description"); + if (description == nullptr) + description = in_repr->attribute("_gui-description"); + hide = in_repr->attribute("gui-hidden"); + if (hide != nullptr) { + if (strcmp(hide, "1") == 0 || + strcmp(hide, "true") == 0) { + hidden = true; + } + /* else stays false */ + } + + /* In this case we just don't have enough information */ + if (name == nullptr) { + return nullptr; + } + + ParamNotebookPage * page = new ParamNotebookPage(name, text, description, hidden, in_ext, in_repr); + + /* Note: page could equal NULL */ + return page; +} + + + +/** + * Creates a notebookpage widget for a notebook. + * + * Builds a notebook page (a vbox) and puts parameters on it. + */ +Gtk::Widget * ParamNotebook::ParamNotebookPage::get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) +{ + if (_hidden) { + return nullptr; + } + + Gtk::VBox * vbox = Gtk::manage(new Gtk::VBox); + vbox->set_border_width(Parameter::GUI_BOX_MARGIN); + vbox->set_spacing(Parameter::GUI_BOX_SPACING); + + // add parameters onto page (if any) + for (auto param:parameters) { + Gtk::Widget * widg = param->get_widget(doc, node, changeSignal); + if (widg) { + int indent = param->get_indent(); + widg->set_margin_start(indent * Parameter::GUI_INDENTATION); + vbox->pack_start(*widg, false, false, 0); + + gchar const * tip = param->get_tooltip(); + if (tip) { + widg->set_tooltip_text(tip); + } else { + widg->set_tooltip_text(""); + widg->set_has_tooltip(false); + } + } + } + + vbox->show(); + + return dynamic_cast(vbox); +} + +/** Search the parameter's name in the page content. */ +Parameter *ParamNotebook::ParamNotebookPage::get_param(const gchar * name) +{ + if (name == nullptr) { + throw Extension::param_not_exist(); + } + if (this->parameters.empty()) { + // the list of parameters is empty + throw Extension::param_not_exist(); + } + + for (auto param:parameters) { + if (!strcmp(param->name(), name)) { + return param; + } + } + + return nullptr; +} + +/** End ParamNotebookPage **/ +/** ParamNotebook **/ + +ParamNotebook::ParamNotebook(const gchar * name, + const gchar * text, + const gchar * description, + bool hidden, + int indent, + Inkscape::Extension::Extension * ext, + Inkscape::XML::Node * xml) + : Parameter(name, text, description, hidden, indent, ext) +{ + // Read XML tree to add pages: + if (xml != nullptr) { + Inkscape::XML::Node *child_repr = xml->firstChild(); + while (child_repr != nullptr) { + char const * chname = child_repr->name(); + if (!strncmp(chname, INKSCAPE_EXTENSION_NS_NC, strlen(INKSCAPE_EXTENSION_NS_NC))) { + chname += strlen(INKSCAPE_EXTENSION_NS); + } + if (chname[0] == '_') // Allow _ for translation of tags + chname++; + if (!strcmp(chname, "page")) { + ParamNotebookPage * page; + page = ParamNotebookPage::makepage(child_repr, ext); + if (page != nullptr) pages.push_back(page); + } + child_repr = child_repr->next(); + } + } + + // Initialize _value with the current page + const char * defaultval = nullptr; + // set first page as default + if (!pages.empty()) { + defaultval = pages[0]->name(); + } + + gchar * pref_name = this->pref_name(); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Glib::ustring paramval = prefs->getString(extension_pref_root + pref_name); + g_free(pref_name); + + if (!paramval.empty()) + defaultval = paramval.data(); + if (defaultval != nullptr) + _value = g_strdup(defaultval); // allocate space for _value +} + +ParamNotebook::~ParamNotebook () +{ + //destroy pages + for (auto page:pages) { + delete page; + } + g_free(_value); +} + + +/** + * A function to set the \c _value. + * + * 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(). + * + * @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. + */ +const gchar *ParamNotebook::set(const int in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/) +{ + int i = in < pages.size() ? in : pages.size()-1; + ParamNotebookPage * page = pages[i]; + + if (page == nullptr) return _value; + + if (_value != nullptr) g_free(_value); + _value = g_strdup(page->name()); + + gchar * prefname = this->pref_name(); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setString(extension_pref_root + prefname, _value); + g_free(prefname); + + return _value; +} + +void ParamNotebook::string(std::list &list) const +{ + std::string param_string; + param_string += "--"; + param_string += name(); + param_string += "="; + + param_string += "\""; + param_string += _value; // the name of the current page + param_string += "\""; + list.insert(list.end(), param_string); + + for (auto page:pages) { + page->paramString(list); + } +} + +/** 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: + /** + * 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)); + }; + void changed_page(Gtk::Widget *page, guint pagenum); + bool activated; +}; + +/** + * 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(Gtk::Widget * /*page*/, guint pagenum) +{ + if (get_visible()) { + _pref->set((int)pagenum, _doc, _node); + } +} + +/** Search the parameter's name in the notebook content. */ +Parameter *ParamNotebook::get_param(const gchar * name) +{ + if (name == nullptr) { + throw Extension::param_not_exist(); + } + for (auto page:pages) { + Parameter * subparam = page->get_param(name); + if (subparam) { + return subparam; + } + } + + return nullptr; +} + + +/** + * 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, sigc::signal * changeSignal) +{ + if (_hidden) { + return nullptr; + } + + ParamNotebookWdg * nb = Gtk::manage(new ParamNotebookWdg(this, doc, node)); + + // add pages (if any) + int i = -1; + int pagenr = i; + for (auto page:pages) { + i++; + Gtk::Widget * widg = page->get_widget(doc, node, changeSignal); + nb->append_page(*widg, _(page->get_text())); + 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(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:fileencoding=utf-8:textwidth=99 : diff --git a/src/extension/prefdialog/param/notebook.h b/src/extension/prefdialog/param/notebook.h new file mode 100644 index 000000000..dd7154f06 --- /dev/null +++ b/src/extension/prefdialog/param/notebook.h @@ -0,0 +1,117 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#ifndef INK_EXTENSION_PARAMNOTEBOOK_H_SEEN +#define INK_EXTENSION_PARAMNOTEBOOK_H_SEEN + +/** \file + * Notebook parameter for extensions. + */ + +/* + * Author: + * Johan Engelen + * Jon A. Cruz + * + * Copyright (C) 2006 Author + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include "parameter.h" + +namespace Gtk { +class Widget; +} + +namespace Inkscape { +namespace Extension { + +class Extension; + + +/** A class to represent a notebookparameter of an extension. */ +class ParamNotebook : public Parameter { +private: + /** + * Internal value. This should point to a string that has + * been allocated in memory. And should be free'd. + * It is the name of the current page. + */ + gchar * _value; + + /** + * A class to represent the pages of a notebookparameter of an extension. + */ + class ParamNotebookPage : public Parameter { + private: + std::vector parameters; /**< A table to store the parameters for this page. + This only gets created if there are parameters on this + page */ + + public: + static ParamNotebookPage * makepage (Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext); + + ParamNotebookPage(const gchar * name, + const gchar * text, + const gchar * description, + bool hidden, + Inkscape::Extension::Extension * ext, + Inkscape::XML::Node * xml); + ~ParamNotebookPage() override; + + Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) override; + void paramString (std::list &list); + gchar * get_text () {return _text;}; + Parameter * get_param (const gchar * name) override; + }; /* class ParamNotebookPage */ + + + std::vector pages; /**< A table to store the pages with parameters for this notebook. + This only gets created if there are pages in this + notebook */ +public: + ParamNotebook(const gchar * name, + const gchar * text, + const gchar * description, + bool hidden, + int indent, + Inkscape::Extension::Extension * ext, + Inkscape::XML::Node * xml); + ~ParamNotebook() override; + + Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) override; + + /** + * 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. + */ + void string (std::list &list) const override; + + // Explicitly call superclass version to avoid method being hidden. + void string(std::string &string) const override {return Parameter::string(string);} + + + Parameter * get_param (const gchar * name) override; + + const gchar * get (const SPDocument * /*doc*/, const Inkscape::XML::Node * /*node*/) { return _value; } + const gchar * set (const int in, SPDocument * doc, Inkscape::XML::Node * node); +}; /* class ParamNotebook */ + + + + + +} // namespace Extension +} // namespace Inkscape + +#endif /* INK_EXTENSION_PARAMNOTEBOOK_H_SEEN */ + +/* + 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 : diff --git a/src/extension/prefdialog/param/parameter.cpp b/src/extension/prefdialog/param/parameter.cpp new file mode 100644 index 000000000..1a60ef32e --- /dev/null +++ b/src/extension/prefdialog/param/parameter.cpp @@ -0,0 +1,461 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** @file + * Parameters for extensions. + */ +/* Author: + * Ted Gould + * Johan Engelen + * Jon A. Cruz + * + * Copyright (C) 2005-2007 Authors + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#ifdef linux // does the dollar sign need escaping when passed as string parameter? +# define ESCAPE_DOLLAR_COMMANDLINE +#endif + +#include +#include + +#include +#include + +#include "bool.h" +#include "color.h" +#include "description.h" +#include "enum.h" +#include "./float.h" +#include "int.h" +#include "notebook.h" +#include "parameter.h" +#include "radiobutton.h" +#include "./string.h" + +#include "extension/extension.h" + +#include "object/sp-defs.h" + +#include "ui/widget/color-notebook.h" + +#include "xml/node.h" + + +namespace Inkscape { +namespace Extension { + +Parameter *Parameter::make(Inkscape::XML::Node *in_repr, Inkscape::Extension::Extension *in_ext) +{ + const char *name = in_repr->attribute("name"); + const char *type = in_repr->attribute("type"); + + // we can't create a parameter without type + if (!type) { + return nullptr; + } + // also require name unless it's a pure UI element that does not store its value + if (!name) { + static std::vector ui_elements = {"description"}; + if (std::find(ui_elements.begin(), ui_elements.end(), type) == ui_elements.end()) { + return nullptr; + } + } + + const char *text = in_repr->attribute("gui-text"); + if (text == nullptr) { + text = in_repr->attribute("_gui-text"); + if (text == nullptr) { + // text = ""; // probably better to require devs to explicitly set an empty gui-text if this is what they want + } else { + const char *context = in_repr->attribute("msgctxt"); + if (context != nullptr) { + text = g_dpgettext2(nullptr, context, text); + } else { + text = _(text); + } + } + } + const char *description = in_repr->attribute("gui-description"); + if (description == nullptr) { + description = in_repr->attribute("_gui-description"); + if (description != nullptr) { + const char *context = in_repr->attribute("msgctxt"); + if (context != nullptr) { + description = g_dpgettext2(nullptr, context, description); + } else { + description = _(description); + } + } + } + bool hidden = false; + { + const char *gui_hide = in_repr->attribute("gui-hidden"); + if (gui_hide != nullptr) { + if (strcmp(gui_hide, "1") == 0 || + strcmp(gui_hide, "true") == 0) { + hidden = true; + } + /* else stays false */ + } + } + int indent = 0; + { + const char *indent_attr = in_repr->attribute("indent"); + if (indent_attr != nullptr) { + if (strcmp(indent_attr, "true") == 0) { + indent = 1; + } else { + indent = atoi(indent_attr); + } + } + } + const gchar* appearance = in_repr->attribute("appearance"); + + Parameter * param = nullptr; + if (!strcmp(type, "boolean")) { + param = new ParamBool(name, text, description, hidden, indent, in_ext, in_repr); + } else if (!strcmp(type, "int")) { + if (appearance && !strcmp(appearance, "full")) { + param = new ParamInt(name, text, description, hidden, indent, in_ext, in_repr, ParamInt::FULL); + } else { + param = new ParamInt(name, text, description, hidden, indent, in_ext, in_repr, ParamInt::MINIMAL); + } + } else if (!strcmp(type, "float")) { + if (appearance && !strcmp(appearance, "full")) { + param = new ParamFloat(name, text, description, hidden, indent, in_ext, in_repr, ParamFloat::FULL); + } else { + param = new ParamFloat(name, text, description, hidden, indent, in_ext, in_repr, ParamFloat::MINIMAL); + } + } else if (!strcmp(type, "string")) { + param = new ParamString(name, text, description, hidden, indent, in_ext, in_repr); + gchar const * max_length = in_repr->attribute("max_length"); + if (max_length != nullptr) { + ParamString * ps = dynamic_cast(param); + ps->setMaxLength(atoi(max_length)); + } + } else if (!strcmp(type, "description")) { + ParamDescription::AppearanceMode appearance_mode = ParamDescription::DESCRIPTION; + if (appearance) { + if (!strcmp(appearance, "header")) { + appearance_mode = ParamDescription::HEADER; + } else if (!strcmp(appearance, "url")) { + appearance_mode = ParamDescription::URL; + } + } + param = new ParamDescription(name, text, description, hidden, indent, in_ext, in_repr, appearance_mode); + } else if (!strcmp(type, "enum")) { + param = new ParamComboBox(name, text, description, hidden, indent, in_ext, in_repr); + } else if (!strcmp(type, "notebook")) { + param = new ParamNotebook(name, text, description, hidden, indent, in_ext, in_repr); + } else if (!strcmp(type, "optiongroup")) { + if (appearance && !strcmp(appearance, "minimal")) { + param = new ParamRadioButton(name, text, description, hidden, indent, in_ext, in_repr, ParamRadioButton::MINIMAL); + } else { + param = new ParamRadioButton(name, text, description, hidden, indent, in_ext, in_repr, ParamRadioButton::FULL); + } + } else if (!strcmp(type, "color")) { + param = new ParamColor(name, text, description, hidden, indent, in_ext, in_repr); + } + + // Note: param could equal NULL + return param; +} + +bool Parameter::get_bool(SPDocument const *doc, Inkscape::XML::Node const *node) const +{ + ParamBool const *boolpntr = dynamic_cast(this); + if (!boolpntr) { + throw Extension::param_not_bool_param(); + } + return boolpntr->get(doc, node); +} + +int Parameter::get_int(SPDocument const *doc, Inkscape::XML::Node const *node) const +{ + ParamInt const *intpntr = dynamic_cast(this); + if (!intpntr) { + throw Extension::param_not_int_param(); + } + return intpntr->get(doc, node); +} + +float Parameter::get_float(SPDocument const *doc, Inkscape::XML::Node const *node) const +{ + ParamFloat const *floatpntr = dynamic_cast(this); + if (!floatpntr) { + throw Extension::param_not_float_param(); + } + return floatpntr->get(doc, node); +} + +gchar const *Parameter::get_string(SPDocument const *doc, Inkscape::XML::Node const *node) const +{ + ParamString const *stringpntr = dynamic_cast(this); + if (!stringpntr) { + throw Extension::param_not_string_param(); + } + return stringpntr->get(doc, node); +} + +gchar const *Parameter::get_enum(SPDocument const *doc, Inkscape::XML::Node const *node) const +{ + ParamComboBox const *param = dynamic_cast(this); + if (!param) { + throw Extension::param_not_enum_param(); + } + return param->get(doc, node); +} + +bool Parameter::get_enum_contains(gchar const * value, SPDocument const *doc, Inkscape::XML::Node const *node) const +{ + ParamComboBox const *param = dynamic_cast(this); + if (!param) { + throw Extension::param_not_enum_param(); + } + return param->contains(value, doc, node); +} + +gchar const *Parameter::get_optiongroup(SPDocument const *doc, Inkscape::XML::Node const * node) const +{ + ParamRadioButton const *param = dynamic_cast(this); + if (!param) { + throw Extension::param_not_optiongroup_param(); + } + return param->get(doc, node); +} + +guint32 Parameter::get_color(const SPDocument* doc, Inkscape::XML::Node const *node) const +{ + ParamColor const *param = dynamic_cast(this); + if (!param) { + throw Extension::param_not_color_param(); + } + return param->get(doc, node); +} + +bool Parameter::set_bool(bool in, SPDocument * doc, Inkscape::XML::Node * node) +{ + ParamBool * boolpntr = dynamic_cast(this); + if (boolpntr == nullptr) + throw Extension::param_not_bool_param(); + return boolpntr->set(in, doc, node); +} + +int Parameter::set_int(int in, SPDocument * doc, Inkscape::XML::Node * node) +{ + ParamInt * intpntr = dynamic_cast(this); + if (intpntr == nullptr) + throw Extension::param_not_int_param(); + return intpntr->set(in, doc, node); +} + +/** 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(this); + if (floatpntr == nullptr) + throw Extension::param_not_float_param(); + return floatpntr->set(in, doc, node); +} + +/** Wrapper to cast to the object and use it's function. */ +gchar const * +Parameter::set_string (gchar const * in, SPDocument * doc, Inkscape::XML::Node * node) +{ + ParamString * stringpntr = dynamic_cast(this); + if (stringpntr == nullptr) + throw Extension::param_not_string_param(); + return stringpntr->set(in, doc, node); +} + +gchar const * Parameter::set_optiongroup( gchar const * in, SPDocument * doc, Inkscape::XML::Node * node ) +{ + ParamRadioButton *param = dynamic_cast(this); + if (!param) { + throw Extension::param_not_optiongroup_param(); + } + return param->set(in, doc, node); +} + +gchar const *Parameter::set_enum( gchar const * in, SPDocument * doc, Inkscape::XML::Node * node ) +{ + ParamComboBox *param = dynamic_cast(this); + if (!param) { + throw Extension::param_not_enum_param(); + } + return param->set(in, doc, node); +} + + +/** 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(this); + if (param == nullptr) + throw Extension::param_not_color_param(); + return param->set(in, doc, node); +} + + +/** Oop, now that we need a parameter, we need it's name. */ +Parameter::Parameter(gchar const * name, gchar const * text, gchar const * description, bool hidden, int indent, Inkscape::Extension::Extension * ext) : + _description(nullptr), + _text(nullptr), + _hidden(hidden), + _indent(indent), + _extension(ext), + _name(nullptr) +{ + if (name != nullptr) { + _name = g_strdup(name); + } + + if (description != nullptr) { + _description = g_strdup(description); + } + + if (text != nullptr) { + _text = g_strdup(text); + } else { + _text = g_strdup(name); + } + + return; +} + +/** Oop, now that we need a parameter, we need it's name. */ +Parameter::Parameter (gchar const * name, gchar const * text, Inkscape::Extension::Extension * ext) : + _description(nullptr), + _text(nullptr), + _hidden(false), + _indent(0), + _extension(ext), + _name(nullptr) +{ + if (name != nullptr) { + _name = g_strdup(name); + } + if (text != nullptr) { + _text = g_strdup(text); + } else { + _text = g_strdup(name); + } + + return; +} + +Parameter::~Parameter() +{ + g_free(_name); + _name = nullptr; + + g_free(_text); + _text = nullptr; + + g_free(_description); + _description = nullptr; +} + +gchar *Parameter::pref_name() const +{ + 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 = doc->getReprDoc(); + Inkscape::XML::Node * defs = doc->getDefs()->getRepr(); + Inkscape::XML::Node * params = nullptr; + + GQuark const name_quark = g_quark_from_string("inkscape:extension-params"); + + for (Inkscape::XML::Node * child = defs->firstChild(); + child != nullptr; + child = child->next()) { + if ((GQuark)child->code() == name_quark && + !strcmp(child->attribute("extension"), _extension->get_id())) { + params = child; + break; + } + } + + if (params == nullptr) { + params = xml_doc->createElement("inkscape:extension-param"); + params->setAttribute("extension", _extension->get_id()); + defs->appendChild(params); + Inkscape::GC::release(params); + } + + return params; +} + +/** Basically, if there is no widget pass a NULL. */ +Gtk::Widget * +Parameter::get_widget (SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/, sigc::signal * /*changeSignal*/) +{ + return nullptr; +} + +/** If I'm not sure which it is, just don't return a value. */ +void Parameter::string(std::string &/*string*/) const +{ + // TODO investigate clearing the target string. +} + +void Parameter::string(std::list &list) const +{ + std::string value; + string(value); + if (!value.empty()) { + std::string final; + final += "--"; + final += name(); + final += "="; + final += value; + + list.insert(list.end(), final); + } +} + +Parameter *Parameter::get_param(gchar const * /*name*/) +{ + return nullptr; +} + +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:fileencoding=utf-8:textwidth=99 : diff --git a/src/extension/prefdialog/param/parameter.h b/src/extension/prefdialog/param/parameter.h new file mode 100644 index 000000000..c37d1539a --- /dev/null +++ b/src/extension/prefdialog/param/parameter.h @@ -0,0 +1,219 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** @file + * Parameters for extensions. + */ +/* Authors: + * Ted Gould + * Jon A. Cruz + * + * Copyright (C) 2005-2006 Authors + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#ifndef SEEN_INK_EXTENSION_PARAM_H__ +#define SEEN_INK_EXTENSION_PARAM_H__ + +#include + +#include + +class SPDocument; + +namespace Gtk { +class Widget; +} + +namespace Inkscape { +namespace XML { +class Node; +} + +namespace Extension { + +class Extension; + + +/** + * The root directory in the preferences database for extension-related parameters. + * + * The directory path has both a leading and a trailing slash, so that extension_pref_root + pref_name works + * without having to append a separator. + */ +extern Glib::ustring const extension_pref_root; + +/** + * A class to represent the parameter of an extension. + * + * This is really a super class that allows them to abstract all + * the different types of parameters into some that can be passed + * around. There is also a few functions that are used by all the + * different parameters. + */ +class Parameter { + +public: + Parameter(gchar const *name, + gchar const *text, + gchar const *description, + bool hidden, + int indent, + Inkscape::Extension::Extension * ext); + + Parameter(gchar const *name, + gchar const *text, + Inkscape::Extension::Extension * ext); + + virtual ~Parameter(); + + /** Wrapper to cast to the object and use its function. */ + bool get_bool(SPDocument const *doc, Inkscape::XML::Node const *node) const; + + /** Wrapper to cast to the object and use it's function. */ + int get_int(SPDocument const *doc, Inkscape::XML::Node const *node) const; + + /** Wrapper to cast to the object and use it's function. */ + float get_float(SPDocument const *doc, Inkscape::XML::Node const *node) const; + + /** Wrapper to cast to the object and use it's function. */ + gchar const *get_string(SPDocument const *doc, Inkscape::XML::Node const *node) const; + + guint32 get_color(SPDocument const *doc, Inkscape::XML::Node const *node) const; + + /** Wrapper to cast to the object and use it's function. */ + gchar const *get_enum(SPDocument const *doc, Inkscape::XML::Node const *node) const; + + /** Wrapper to cast to the object and use it's function. */ + bool get_enum_contains(gchar const * value, SPDocument const *doc, Inkscape::XML::Node const *node) const; + + /** Wrapper to cast to the object and use it's function. */ + gchar const *get_optiongroup(SPDocument const * doc, Inkscape::XML::Node const *node) const; + + /** Wrapper to cast to the object and use it's function. */ + bool set_bool(bool in, SPDocument * doc, Inkscape::XML::Node * node); + + /** Wrapper to cast to the object and use it's function. */ + int set_int(int in, SPDocument * doc, Inkscape::XML::Node * node); + + float set_float(float in, SPDocument * doc, Inkscape::XML::Node * node); + + gchar const *set_optiongroup(gchar const *in, SPDocument * doc, Inkscape::XML::Node *node); + + gchar const *set_enum(gchar const * in, SPDocument * doc, Inkscape::XML::Node *node); + + gchar const *set_string(gchar const * in, SPDocument * doc, Inkscape::XML::Node * node); + + guint32 set_color(guint32 in, SPDocument * doc, Inkscape::XML::Node * node); + + gchar const * name() const {return _name;} + + /** + * This function creates a parameter that can be used later. This + * is typically done in the creation of the extension and defined + * in the XML file describing the extension (it's private so people + * have to use the system) :) + * + * 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 or a type in the XML, then no parameter 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. + * + * @param in_repr The XML describing the parameter. + * @return a pointer to a new Parameter if applicable, null otherwise.. + */ + static Parameter *make(Inkscape::XML::Node * in_repr, Inkscape::Extension::Extension * in_ext); + + virtual Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal); + + gchar const * get_tooltip() const { return _description; } + + /** Indicates if the GUI for this parameter is hidden or not */ + bool get_hidden() const { return _hidden; } + + /** Indentation level of the parameter */ + int get_indent() const { return _indent; } + + virtual void string(std::list &list) const; + + /** + * Gets the current value of the parameter in a string form. + * @return A string with the 'value'. + */ + virtual void string(std::string &string) const; + + /** All the code in Notebook::get_param to get the notebook content. */ + virtual Parameter *get_param(gchar const *name); + + + /** Recommended margin of boxes containing multiple Parameters (in px) */ + const static int GUI_BOX_MARGIN = 10; + /** Recommended spacing between multiple Parameters packed into a box (in px) */ + const static int GUI_BOX_SPACING = 4; + /** Recommended spacing between the widgets making up a single Parameter (e.g. label and input) (in px) */ + const static int GUI_PARAM_WIDGETS_SPACING = 4; + /** Recommended indentation width of parameters (in px) */ + const static int GUI_INDENTATION = 12; + /** Recommended maximum line length for wrapping textual parameters (in chars) */ + const static int GUI_MAX_LINE_LENGTH = 60; + + +protected: + /** Parameter text to show as the GUI label. */ + gchar * _text; + + /** Extended description of the parameter (crrently shown as tooltip on hover). */ + gchar * _description; + + /** Whether the parameter is visible. */ + bool _hidden; + + /** Indentation level of the parameter. */ + int _indent; + + + /* **** funcs **** */ + + /** + * Build the name to write the parameter from the extension's ID and the name of this parameter. + */ + gchar *pref_name() const; + + Inkscape::XML::Node * find_child (Inkscape::XML::Node * adult); + + Inkscape::XML::Node * document_param_node (SPDocument * doc); + + Inkscape::XML::Node * new_child (Inkscape::XML::Node * parent); + +private: + /** Which extension is this parameter attached to. */ + Inkscape::Extension::Extension *_extension; + + /** The name of this parameter. */ + gchar *_name; +}; + +} // namespace Extension +} // namespace Inkscape + +#endif // SEEN_INK_EXTENSION_PARAM_H__ + +/* + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/extension/prefdialog/param/radiobutton.cpp b/src/extension/prefdialog/param/radiobutton.cpp new file mode 100644 index 000000000..8c1d6a5f7 --- /dev/null +++ b/src/extension/prefdialog/param/radiobutton.cpp @@ -0,0 +1,349 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** \file + * extension parameter for radiobuttons. + * + * It uses a Gtk:ComboBoxText widget in the extension UI. + */ + +/* + * Author: + * Johan Engelen + * + * Copyright (C) 2006-2007 Johan Engelen + * Copyright (C) 2008 Jon A. Cruz + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include +#include +#include +#include + +#include "xml/node.h" +#include "extension/extension.h" +#include "preferences.h" + +#include "radiobutton.h" + +/** + * The root directory in the preferences database for extension + * related parameters. + */ +#define PREF_DIR "extensions" + +namespace Inkscape { +namespace Extension { + +/* For internal use only. + Note that value and text MUST be non-NULL. This is ensured by newing only at one location in the code where non-NULL checks are made. */ + +ParamRadioButton::ParamRadioButton(const gchar * name, + const gchar * text, + const gchar * description, + bool hidden, + int indent, + Inkscape::Extension::Extension * ext, + Inkscape::XML::Node * xml, + AppearanceMode mode) + : Parameter(name, text, description, hidden, indent, ext) + , _value(nullptr) + , _mode(mode) +{ + // Read XML tree to add enumeration items: + // printf("Extension Constructor: "); + if (xml != nullptr) { + Inkscape::XML::Node *child_repr = xml->firstChild(); + while (child_repr != nullptr) { + char const * chname = child_repr->name(); + if (!strcmp(chname, INKSCAPE_EXTENSION_NS "option") || !strcmp(chname, INKSCAPE_EXTENSION_NS "_option")) { + Glib::ustring * newtext = nullptr; + Glib::ustring * newvalue = nullptr; + const char * contents = child_repr->firstChild()->content(); + + if (contents != nullptr) { + // don't translate when 'item' but do translate when '_option' + if (!strcmp(chname, INKSCAPE_EXTENSION_NS "_option")) { + if (child_repr->attribute("msgctxt") != nullptr) { + newtext = new Glib::ustring(g_dpgettext2(nullptr, child_repr->attribute("msgctxt"), contents)); + } else { + newtext = new Glib::ustring(_(contents)); + } + } else { + newtext = new Glib::ustring(contents); + } + } else { + continue; + } + + + const char * val = child_repr->attribute("value"); + if (val != nullptr) { + newvalue = new Glib::ustring(val); + } else { + newvalue = new Glib::ustring(contents); + } + + if ( (newtext) && (newvalue) ) { // logical error if this is not true here + choices.push_back(new optionentry(newvalue, newtext)); + } + } + child_repr = child_repr->next(); + } + } + + // Initialize _value with the default value from xml + // for simplicity : default to the contents of the first xml-child + const char * defaultval = nullptr; + if (!choices.empty()) { + defaultval = (static_cast (choices[0]))->value->c_str(); + } + + gchar * pref_name = this->pref_name(); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Glib::ustring paramval = prefs->getString(extension_pref_root + pref_name); + g_free(pref_name); + + if (!paramval.empty()) { + defaultval = paramval.data(); + } + if (defaultval != nullptr) { + _value = g_strdup(defaultval); // allocate space for _value + } +} + +ParamRadioButton::~ParamRadioButton () +{ + //destroy choice strings + for(auto i:choices) { + delete i; + } + g_free(_value); +} + + +/** + * A function to set the \c _value. + * + * This function sets ONLY 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(). + * + * @param in The value to set. + * @param doc A document that should be used to set the value. + * @param node The node where the value may be placed. + */ +const gchar *ParamRadioButton::set(const gchar * in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/) +{ + if (in == nullptr) { + return nullptr; /* Can't have NULL string */ + } + + Glib::ustring * settext = nullptr; + for (auto entr:choices) { + if ( !entr->value->compare(in) ) { + settext = entr->value; + break; // break out of for loop + } + } + if (settext) { + if (_value != nullptr) { + g_free(_value); + } + _value = g_strdup(settext->c_str()); + gchar * prefname = this->pref_name(); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setString(extension_pref_root + prefname, _value); + g_free(prefname); + } else { + g_warning("Couldn't set ParamRadioButton %s", in); + } + + return _value; +} + +void ParamRadioButton::string(std::string &string) const +{ + string += _value; +} + +/** A special radiobutton class to use in ParamRadioButton. */ +class ParamRadioButtonWdg : public Gtk::RadioButton { +private: + ParamRadioButton * _pref; + SPDocument * _doc; + Inkscape::XML::Node * _node; + sigc::signal * _changeSignal; +public: + /** + * Build a string preference for the given parameter. + * @param pref Where to put the radiobutton's string when it is selected. + */ + ParamRadioButtonWdg ( Gtk::RadioButtonGroup& group, const Glib::ustring& label, + ParamRadioButton * pref, SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal ) : + Gtk::RadioButton(group, label), _pref(pref), _doc(doc), _node(node), _changeSignal(changeSignal) { + add_changesignal(); + }; + ParamRadioButtonWdg ( const Glib::ustring& label, + ParamRadioButton * pref, SPDocument * doc, Inkscape::XML::Node * node , sigc::signal * changeSignal) : + Gtk::RadioButton(label), _pref(pref), _doc(doc), _node(node), _changeSignal(changeSignal) { + add_changesignal(); + }; + void add_changesignal() { + this->signal_toggled().connect(sigc::mem_fun(this, &ParamRadioButtonWdg::changed)); + }; + void changed (); +}; + +/** + * Respond to the selected radiobutton changing. + * + * This function responds to the radiobutton selection changing by grabbing the value + * from the text box and putting it in the parameter. + */ +void ParamRadioButtonWdg::changed() +{ + if (this->get_active()) { + Glib::ustring value = _pref->value_from_label(this->get_label()); + _pref->set(value.c_str(), _doc, _node); + } + if (_changeSignal != nullptr) { + _changeSignal->emit(); + } +} + + +class ComboWdg : public Gtk::ComboBoxText { +private: + ParamRadioButton* _base; + SPDocument* _doc; + Inkscape::XML::Node* _node; + sigc::signal * _changeSignal; + +public: + ComboWdg(ParamRadioButton* base, SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) : + _base(base), + _doc(doc), + _node(node), + _changeSignal(changeSignal) + { + this->signal_changed().connect(sigc::mem_fun(this, &ComboWdg::changed)); + } + ~ComboWdg() override = default; + void changed (); +}; + +void ComboWdg::changed() +{ + if ( _base ) { + Glib::ustring value = _base->value_from_label(get_active_text()); + _base->set(value.c_str(), _doc, _node); + } + if (_changeSignal != nullptr) { + _changeSignal->emit(); + } +} + +/** + * Returns the value for the options label parameter + */ +Glib::ustring ParamRadioButton::value_from_label(const Glib::ustring label) +{ + Glib::ustring value = ""; + + for ( auto entr:choices) { + if ( !entr->text->compare(label) ) { + value = *(entr->value); + break; + } + } + + return value; + +} + +/** + * Creates a combobox widget for an enumeration parameter. + */ +Gtk::Widget * ParamRadioButton::get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) +{ + if (_hidden) { + return nullptr; + } + + auto hbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, Parameter::GUI_PARAM_WIDGETS_SPACING)); + hbox->set_homogeneous(false); + auto vbox = Gtk::manage(new Gtk::Box(Gtk::ORIENTATION_VERTICAL, 0)); + vbox->set_homogeneous(false); + + Gtk::Label * label = Gtk::manage(new Gtk::Label(_text, Gtk::ALIGN_START, Gtk::ALIGN_START)); + label->show(); + hbox->pack_start(*label, false, false); + + Gtk::ComboBoxText* cbt = nullptr; + bool comboSet = false; + if (_mode == MINIMAL) { + cbt = Gtk::manage(new ComboWdg(this, doc, node, changeSignal)); + cbt->show(); + vbox->pack_start(*cbt, false, false); + } + + // add choice strings as radiobuttons + // and select last selected option (_value) + Gtk::RadioButtonGroup group; + for (auto entr:choices) { + Glib::ustring * text = entr->text; + switch ( _mode ) { + case MINIMAL: + { + cbt->append(*text); + if (!entr->value->compare(_value)) { + cbt->set_active_text(*text); + comboSet = true; + } + } + break; + case COMPACT: + case FULL: + { + ParamRadioButtonWdg * radio = Gtk::manage(new ParamRadioButtonWdg(group, *text, this, doc, node, changeSignal)); + radio->show(); + vbox->pack_start(*radio, true, true); + if (!entr->value->compare(_value)) { + radio->set_active(); + } + } + break; + } + } + + if ( (_mode == MINIMAL) && !comboSet) { + cbt->set_active(0); + } + + vbox->show(); + hbox->pack_end(*vbox, false, false); + hbox->show(); + + + return dynamic_cast(hbox); +} + + +} /* 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 : diff --git a/src/extension/prefdialog/param/radiobutton.h b/src/extension/prefdialog/param/radiobutton.h new file mode 100644 index 000000000..48d470a01 --- /dev/null +++ b/src/extension/prefdialog/param/radiobutton.h @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#ifndef INK_EXTENSION_PARAMRADIOBUTTON_H_SEEN +#define INK_EXTENSION_PARAMRADIOBUTTON_H_SEEN + +/** \file + * Radiobutton parameter for extensions. + */ + +/* + * Authors: + * Johan Engelen + * Jon A. Cruz + * + * Copyright (C) 2006-2007 Johan Engelen + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include "parameter.h" + +namespace Gtk { +class Widget; +} + +namespace Inkscape { +namespace Extension { + +class Extension; + + + +// \brief A class to represent a radiobutton parameter of an extension +class ParamRadioButton : public Parameter { +public: + enum AppearanceMode { + FULL, COMPACT, MINIMAL + }; + + ParamRadioButton(const gchar * name, + const gchar * text, + const gchar * description, + bool hidden, + int indent, + Inkscape::Extension::Extension * ext, + Inkscape::XML::Node * xml, + AppearanceMode mode); + ~ParamRadioButton() override; + + Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) override; + + // Explicitly call superclass version to avoid method being hidden. + void string(std::list &list) const override { return Parameter::string(list); } + + void string(std::string &string) const override; + + Glib::ustring value_from_label(const Glib::ustring label); + + const gchar *get(const SPDocument * /*doc*/, const Inkscape::XML::Node * /*node*/) const { return _value; } + + const gchar *set(const gchar *in, SPDocument *doc, Inkscape::XML::Node *node); + +private: + /** \brief Internal value. This should point to a string that has + been allocated in memory. And should be free'd. + It is the value of the current selected string */ + gchar * _value; + AppearanceMode _mode; + + /* For internal use only. + Note that value and text MUST be non-NULL. This is ensured by newing only at one location in the code where non-NULL checks are made. */ + class optionentry { + public: + optionentry (Glib::ustring * val, Glib::ustring * txt) { + value = val; + text = txt; + } + ~optionentry() { + delete value; + delete text; + } + Glib::ustring * value; + Glib::ustring * text; + }; + + std::vector choices; /**< A table to store the choice strings */ + +}; /* class ParamRadioButton */ + + + + + +} /* namespace Extension */ +} /* namespace Inkscape */ + +#endif /* INK_EXTENSION_PARAMRADIOBUTTON_H_SEEN */ + +/* + 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:fileencoding=utf-8:textwidth=99 : diff --git a/src/extension/prefdialog/param/string.cpp b/src/extension/prefdialog/param/string.cpp new file mode 100644 index 000000000..c1986cf92 --- /dev/null +++ b/src/extension/prefdialog/param/string.cpp @@ -0,0 +1,181 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Copyright (C) 2005-2007 Authors: + * Ted Gould + * Johan Engelen * + * Jon A. Cruz + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include +#include +#include + +#include + +#include "xml/node.h" +#include "extension/extension.h" +#include "./string.h" +#include "preferences.h" +#include + +namespace Inkscape { +namespace Extension { + + +/** Free the allocated data. */ +ParamString::~ParamString() +{ + g_free(_value); + _value = nullptr; +} + +/** + * A function to set the \c _value. + * + * 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(). + * + * @param in The value to set to. + * @param doc A document that should be used to set the value. + * @param node The node where the value may be placed. + */ +const gchar * ParamString::set(const gchar * in, SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/) +{ + if (in == nullptr) { + return nullptr; /* Can't have NULL string */ + } + + if (_value != nullptr) { + g_free(_value); + } + + _value = g_strdup(in); + + gchar * prefname = this->pref_name(); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + prefs->setString(extension_pref_root + prefname, _value); + g_free(prefname); + + return _value; +} + +void ParamString::string(std::string &string) const +{ + if (_value) { + string += _value; + } +} + +/** Initialize the object, to do that, copy the data. */ +ParamString::ParamString(const gchar * name, + const gchar * text, + const gchar * description, + bool hidden, + int indent, + Inkscape::Extension::Extension * ext, + Inkscape::XML::Node * xml) + : Parameter(name, text, description, hidden, indent, ext) + , _value(nullptr) +{ + const char * defaultval = nullptr; + if (xml->firstChild() != nullptr) { + defaultval = xml->firstChild()->content(); + } + + gchar * pref_name = this->pref_name(); + Inkscape::Preferences *prefs = Inkscape::Preferences::get(); + Glib::ustring paramval = prefs->getString(extension_pref_root + pref_name); + g_free(pref_name); + + if (!paramval.empty()) { + defaultval = paramval.data(); + } + if (defaultval != nullptr) { + char const * chname = xml->name(); + if (!strcmp(chname, INKSCAPE_EXTENSION_NS "_param")) { + if (xml->attribute("msgctxt") != nullptr) { + _value = g_strdup(g_dpgettext2(nullptr, xml->attribute("msgctxt"), defaultval)); + } else { + _value = g_strdup(_(defaultval)); + } + } else { + _value = g_strdup(defaultval); + } + } + + _max_length = 0; +} + +/** A special type of Gtk::Entry to handle string parameteres. */ +class ParamStringEntry : public Gtk::Entry { +private: + ParamString * _pref; + SPDocument * _doc; + Inkscape::XML::Node * _node; + sigc::signal * _changeSignal; +public: + /** + * Build a string preference for the given parameter. + * @param pref Where to get the string from, and where to put it + * when it changes. + */ + ParamStringEntry (ParamString * pref, SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) : + Gtk::Entry(), _pref(pref), _doc(doc), _node(node), _changeSignal(changeSignal) { + if (_pref->get(nullptr, nullptr) != nullptr) { + this->set_text(Glib::ustring(_pref->get(nullptr, nullptr))); + } + this->set_max_length(_pref->getMaxLength()); //Set the max length - default zero means no maximum + this->signal_changed().connect(sigc::mem_fun(this, &ParamStringEntry::changed_text)); + }; + void changed_text (); +}; + + +/** + * Respond to the text box changing. + * + * This function responds to the box changing by grabbing the value + * from the text box and putting it in the parameter. + */ +void ParamStringEntry::changed_text() +{ + Glib::ustring data = this->get_text(); + _pref->set(data.c_str(), _doc, _node); + if (_changeSignal != nullptr) { + _changeSignal->emit(); + } +} + +/** + * Creates a text box for the string parameter. + * + * Builds a hbox with a label and a text box in it. + */ +Gtk::Widget * ParamString::get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) +{ + if (_hidden) { + return nullptr; + } + + Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox(false, Parameter::GUI_PARAM_WIDGETS_SPACING)); + Gtk::Label * label = Gtk::manage(new Gtk::Label(_text, Gtk::ALIGN_START)); + label->show(); + hbox->pack_start(*label, false, false); + + ParamStringEntry * textbox = new ParamStringEntry(this, doc, node, changeSignal); + textbox->show(); + hbox->pack_start(*textbox, true, true); + + hbox->show(); + + return dynamic_cast(hbox); +} + +} /* namespace Extension */ +} /* namespace Inkscape */ diff --git a/src/extension/prefdialog/param/string.h b/src/extension/prefdialog/param/string.h new file mode 100644 index 000000000..7c094d394 --- /dev/null +++ b/src/extension/prefdialog/param/string.h @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +#ifndef INK_EXTENSION_PARAMSTRING_H_SEEN +#define INK_EXTENSION_PARAMSTRING_H_SEEN + +/* + * Copyright (C) 2005-2007 Authors: + * Ted Gould + * Johan Engelen * + * Jon A. Cruz + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include "parameter.h" + +namespace Inkscape { +namespace Extension { + +class ParamString : public Parameter { +private: + /** \brief Internal value. This should point to a string that has + been allocated in memory. And should be free'd. */ + gchar * _value; + /** \brief Internal value. This indicates the maximum length of the string. Zero meaning unlimited. + */ + gint _max_length; +public: + ParamString(const gchar * name, + const gchar * text, + const gchar * description, + bool hidden, + int indent, + Inkscape::Extension::Extension * ext, + Inkscape::XML::Node * xml); + ~ParamString() override; + + /** \brief Returns \c _value, with a \i const to protect it. */ + const gchar *get(SPDocument const * /*doc*/, Inkscape::XML::Node const * /*node*/) const { return _value; } + + const gchar * set (const gchar * in, SPDocument * doc, Inkscape::XML::Node * node); + + Gtk::Widget * get_widget(SPDocument * doc, Inkscape::XML::Node * node, sigc::signal * changeSignal) override; + + // Explicitly call superclass version to avoid method being hidden. + void string(std::list &list) const override { return Parameter::string(list); } + + void string(std::string &string) const override; + + void setMaxLength(int maxLength) { _max_length = maxLength; } + int getMaxLength() { return _max_length; } +}; + + +} // namespace Extension +} // namespace Inkscape + +#endif /* INK_EXTENSION_PARAMSTRING_H_SEEN */ + +/* + 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 : diff --git a/src/extension/prefdialog/prefdialog.cpp b/src/extension/prefdialog/prefdialog.cpp new file mode 100644 index 000000000..6fbffb262 --- /dev/null +++ b/src/extension/prefdialog/prefdialog.cpp @@ -0,0 +1,277 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Authors: + * Ted Gould + * + * Copyright (C) 2005-2008 Authors + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include "prefdialog.h" + +#include +#include +#include + +#include "ui/dialog-events.h" +#include "xml/repr.h" + +// Used to get SP_ACTIVE_DESKTOP +#include "inkscape.h" +#include "desktop.h" +#include "document.h" +#include "document-undo.h" + +#include "extension/effect.h" +#include "extension/execution-env.h" +#include "extension/implementation/implementation.h" + +#include "param/parameter.h" + + +namespace Inkscape { +namespace Extension { + + +/** \brief Creates a new preference dialog for extension preferences + \param name Name of the Extension whose dialog this is + \param help The help string for the extension (NULL if none) + \param controls The extension specific widgets in the dialog + + This function initializes the dialog with the name of the extension + in the title. It adds a few buttons and sets up handlers for + them. It also places the passed-in widgets into the dialog. +*/ +PrefDialog::PrefDialog (Glib::ustring name, gchar const * help, Gtk::Widget * controls, Effect * effect) : + Gtk::Dialog(_(name.c_str()), true), + _help(help), + _name(name), + _button_ok(nullptr), + _button_cancel(nullptr), + _button_preview(nullptr), + _param_preview(nullptr), + _effect(effect), + _exEnv(nullptr) +{ + this->set_default_size(0,0); // we want the window to be as small as possible instead of clobbering up space + + Gtk::HBox * hbox = Gtk::manage(new Gtk::HBox()); + if (controls == nullptr) { + if (_effect == nullptr) { + std::cout << "AH!!! No controls and no effect!!!" << std::endl; + return; + } + controls = _effect->get_imp()->prefs_effect(_effect, SP_ACTIVE_DESKTOP, &_signal_param_change, nullptr); + _signal_param_change.connect(sigc::mem_fun(this, &PrefDialog::param_change)); + } + + hbox->pack_start(*controls, true, true, 0); + hbox->show(); + + this->get_content_area()->pack_start(*hbox, true, true, 0); + + /* + Gtk::Button * help_button = add_button(Gtk::Stock::HELP, Gtk::RESPONSE_HELP); + if (_help == NULL) + help_button->set_sensitive(false); + */ + _button_cancel = add_button(_effect == nullptr ? _("_Cancel") : _("_Close"), Gtk::RESPONSE_CANCEL); + _button_ok = add_button(_effect == nullptr ? _("_OK") : _("_Apply"), Gtk::RESPONSE_OK); + set_default_response(Gtk::RESPONSE_OK); + _button_ok->grab_focus(); + + if (_effect != nullptr && !_effect->no_live_preview) { + if (_param_preview == nullptr) { + XML::Document * doc = sp_repr_read_mem(live_param_xml, strlen(live_param_xml), nullptr); + if (doc == nullptr) { + std::cout << "Error encountered loading live parameter XML !!!" << std::endl; + return; + } + _param_preview = Parameter::make(doc->root(), _effect); + } + + auto sep = Gtk::manage(new Gtk::Separator()); + sep->show(); + + this->get_content_area()->pack_start(*sep, false, false, Parameter::GUI_BOX_SPACING); + + hbox = Gtk::manage(new Gtk::HBox()); + hbox->set_border_width(Parameter::GUI_BOX_MARGIN); + _button_preview = _param_preview->get_widget(nullptr, nullptr, &_signal_preview); + _button_preview->show(); + hbox->pack_start(*_button_preview, true, true, 0); + hbox->show(); + + this->get_content_area()->pack_start(*hbox, false, false, 0); + + Gtk::Box * hbox = dynamic_cast(_button_preview); + if (hbox != nullptr) { + _checkbox_preview = dynamic_cast(hbox->get_children().front()); + } + + preview_toggle(); + _signal_preview.connect(sigc::mem_fun(this, &PrefDialog::preview_toggle)); + } + + // Set window modality for effects that don't use live preview + if (_effect != nullptr && _effect->no_live_preview) { + set_modal(false); + } + + GtkWidget *dlg = GTK_WIDGET(gobj()); + sp_transientize(dlg); + + return; +} + +PrefDialog::~PrefDialog ( ) +{ + if (_param_preview != nullptr) { + delete _param_preview; + _param_preview = nullptr; + } + + if (_exEnv != nullptr) { + _exEnv->cancel(); + delete _exEnv; + _exEnv = nullptr; + _effect->set_execution_env(_exEnv); + } + + if (_effect != nullptr) { + _effect->set_pref_dialog(nullptr); + } + + return; +} + +#if 0 +/** \brief Runs the dialog + \return The response to the dialog + + This function overrides the run function in the GTKmm dialog + class, but basically it only calls it. This function only + handles the \c Gtk::RESPONSE_HELP return, and in that case it + brings up the help window. All other return values are returned + to the calling function. +*/ +int +PrefDialog::run (void) { + int resp = Gtk::RESPONSE_HELP; + while (resp == Gtk::RESPONSE_HELP) { + resp = Gtk::Dialog::run(); + if (resp == Gtk::RESPONSE_HELP) { + /* + if (_helpDialog == NULL) { + _helpDialog = new HelpDialog(_help); + } + */ + } + } + return resp; +} +#endif + +void +PrefDialog::preview_toggle () { + SPDesktop *desktop = SP_ACTIVE_DESKTOP; + SPDocument *document = SP_ACTIVE_DOCUMENT; + bool modified = document->isModifiedSinceSave(); + if(_param_preview->get_bool(nullptr, nullptr)) { + if (_exEnv == nullptr) { + set_modal(true); + _exEnv = new ExecutionEnv(_effect, SP_ACTIVE_DESKTOP, nullptr, false, false); + _effect->set_execution_env(_exEnv); + _exEnv->run(); + } + } else { + set_modal(false); + if (_exEnv != nullptr) { + _exEnv->cancel(); + _exEnv->undo(); + _exEnv->reselect(); + delete _exEnv; + _exEnv = nullptr; + _effect->set_execution_env(_exEnv); + } + } + document->setModifiedSinceSave(modified); +} + +void +PrefDialog::param_change () { + if (_exEnv != nullptr) { + if (!_effect->loaded()) { + _effect->set_state(Extension::STATE_LOADED); + } + _timersig.disconnect(); + _timersig = Glib::signal_timeout().connect(sigc::mem_fun(this, &PrefDialog::param_timer_expire), + 250, /* ms */ + Glib::PRIORITY_DEFAULT_IDLE); + } + + return; +} + +bool +PrefDialog::param_timer_expire () { + if (_exEnv != nullptr) { + _exEnv->cancel(); + _exEnv->undo(); + _exEnv->reselect(); + _exEnv->run(); + } + + return false; +} + +void +PrefDialog::on_response (int signal) { + if (signal == Gtk::RESPONSE_OK) { + if (_exEnv == nullptr) { + if (_effect != nullptr) { + _effect->effect(SP_ACTIVE_DESKTOP); + } else { + // Shutdown run() + return; + } + } else { + if (_exEnv->wait()) { + _exEnv->commit(); + } else { + _exEnv->undo(); + _exEnv->reselect(); + } + delete _exEnv; + _exEnv = nullptr; + _effect->set_execution_env(_exEnv); + } + } + + if (_param_preview != nullptr) { + _checkbox_preview->set_active(false); + } + + if ((signal == Gtk::RESPONSE_CANCEL || signal == Gtk::RESPONSE_DELETE_EVENT) && _effect != nullptr) { + delete this; + } + return; +} + +#include "extension/internal/clear-n_.h" + +const char * PrefDialog::live_param_xml = "false"; + +}; }; /* namespace Inkscape, Extension */ + +/* + 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 : diff --git a/src/extension/prefdialog/prefdialog.h b/src/extension/prefdialog/prefdialog.h new file mode 100644 index 000000000..087900fbe --- /dev/null +++ b/src/extension/prefdialog/prefdialog.h @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * Authors: + * Ted Gould + * + * Copyright (C) 2005,2007-2008 Authors + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#ifndef INKSCAPE_EXTENSION_DIALOG_H__ +#define INKSCAPE_EXTENSION_DIALOG_H__ + +#include +#include +#include + +namespace Gtk { +class CheckButton; +} + +namespace Inkscape { +namespace Extension { +class Effect; +class ExecutionEnv; +class Parameter; + +/** \brief A class to represent the preferences for an extension */ +class PrefDialog : public Gtk::Dialog { + /** \brief Help string if it exists */ + gchar const * _help; + /** \brief Name of the extension */ + Glib::ustring _name; + + /** \brief A pointer to the OK button */ + Gtk::Button * _button_ok; + /** \brief A pointer to the CANCEL button */ + Gtk::Button * _button_cancel; + + /** \brief Button to control live preview */ + Gtk::Widget * _button_preview; + /** \brief Checkbox for the preview */ + Gtk::CheckButton * _checkbox_preview; + + /** \brief Parameter to control live preview */ + Parameter * _param_preview; + + /** \brief XML to define the live effects parameter on the dialog */ + static const char * live_param_xml; + + /** \brief Signal that the user is changing the live effect state */ + sigc::signal _signal_preview; + /** \brief Signal that one of the parameters change */ + sigc::signal _signal_param_change; + + /** \brief If this is the preferences for an effect, the effect + that we're working with. */ + Effect * _effect; + /** \brief If we're executing in preview mode here is the execution + environment for the effect. */ + ExecutionEnv * _exEnv; + + /** \brief The timer used to make it so that parameters don't respond + directly and allows for changes. */ + sigc::connection _timersig; + + void preview_toggle(); + void param_change(); + bool param_timer_expire(); + void on_response (int signal) override; + +public: + PrefDialog (Glib::ustring name, + gchar const * help, + Gtk::Widget * controls = nullptr, + Effect * effect = nullptr); + ~PrefDialog () override; +}; + + +};}; /* namespace Inkscape, Extension */ + +#endif /* INKSCAPE_EXTENSION_DIALOG_H__ */ + +/* + 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 : -- cgit v1.2.3