From 9185b26e396867391d92e4ab6edf933eec77db3a Mon Sep 17 00:00:00 2001 From: Patrick Storz Date: Sun, 4 Aug 2019 22:40:14 +0200 Subject: Add WidgetLabel replacing the former ParamDescription This improves consistency, as "description" parameter were not actually parameters with a value that could be modified or saved. The old syntax is deprecated but still supported for now. --- src/extension/CMakeLists.txt | 4 +- src/extension/prefdialog/parameter-description.cpp | 115 -------------------- src/extension/prefdialog/parameter-description.h | 59 ---------- src/extension/prefdialog/parameter.cpp | 23 +++- src/extension/prefdialog/widget-label.cpp | 121 +++++++++++++++++++++ src/extension/prefdialog/widget-label.h | 65 +++++++++++ src/extension/prefdialog/widget.cpp | 13 ++- 7 files changed, 221 insertions(+), 179 deletions(-) delete mode 100644 src/extension/prefdialog/parameter-description.cpp delete mode 100644 src/extension/prefdialog/parameter-description.h create mode 100644 src/extension/prefdialog/widget-label.cpp create mode 100644 src/extension/prefdialog/widget-label.h diff --git a/src/extension/CMakeLists.txt b/src/extension/CMakeLists.txt index a747f6d45..c8d3f5fc9 100644 --- a/src/extension/CMakeLists.txt +++ b/src/extension/CMakeLists.txt @@ -56,13 +56,13 @@ set(extension_SRC prefdialog/parameter.cpp prefdialog/parameter-bool.cpp prefdialog/parameter-color.cpp - prefdialog/parameter-description.cpp prefdialog/parameter-float.cpp prefdialog/parameter-int.cpp prefdialog/parameter-notebook.cpp prefdialog/parameter-optiongroup.cpp prefdialog/parameter-string.cpp prefdialog/widget.cpp + prefdialog/widget-label.cpp # ------ # Header @@ -131,13 +131,13 @@ set(extension_SRC prefdialog/parameter.h prefdialog/parameter-bool.h prefdialog/parameter-color.h - prefdialog/parameter-description.h prefdialog/parameter-float.h prefdialog/parameter-int.h prefdialog/parameter-notebook.h prefdialog/parameter-optiongroup.h prefdialog/parameter-string.h prefdialog/widget.h + prefdialog/widget-label.h ) if(WIN32) diff --git a/src/extension/prefdialog/parameter-description.cpp b/src/extension/prefdialog/parameter-description.cpp deleted file mode 100644 index ca8825615..000000000 --- a/src/extension/prefdialog/parameter-description.cpp +++ /dev/null @@ -1,115 +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. - */ - -#include "parameter-description.h" - -#include -#include -#include -#include - -#include "xml/node.h" -#include "extension/extension.h" - -namespace Inkscape { -namespace Extension { - - -ParamDescription::ParamDescription(Inkscape::XML::Node *xml, Inkscape::Extension::Extension *ext) - : InxParameter(xml, ext) -{ - // construct the text content by concatenating all (non-empty) text nodes, - // removing all other nodes (e.g. comment nodes) and replacing elements with "
" - 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(); - } - - // 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 value - if (!_value.empty()) { - if (_translatable != NO) { // translate unless explicitly marked untranslatable - _value = get_translation(_value.c_str()); - } - } - - // finally replace all remaining
with a real newline character - _value = Glib::Regex::create("
")->replace_literal(_value, 0, "\n", (Glib::RegexMatchFlags)0); - - // parse appearance - if (_appearance) { - if (!strcmp(_appearance, "header")) { - _mode = HEADER; - } else if (!strcmp(_appearance, "url")) { - _mode = URL; - } else { - g_warning("Invalid value ('%s') for appearance of parameter '%s' in extension '%s'", - _appearance, _name, _extension->get_id()); - } - } -} - -/** \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; - } - - 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 ridiculously 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 too narrow dialog instead and a lot of 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 > GUI_MAX_LINE_LENGTH ? 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/parameter-description.h b/src/extension/prefdialog/parameter-description.h deleted file mode 100644 index 5ffec4de7..000000000 --- a/src/extension/prefdialog/parameter-description.h +++ /dev/null @@ -1,59 +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 InxParameter { -public: - enum AppearanceMode { - DEFAULT, HEADER, URL - }; - - ParamDescription(Inkscape::XML::Node *xml, Inkscape::Extension::Extension *ext); - - Gtk::Widget *get_widget(SPDocument *doc, Inkscape::XML::Node *node, sigc::signal *changeSignal) override; -private: - /** \brief Internal value. */ - Glib::ustring _value; - - /** appearance mode **/ - AppearanceMode _mode = DEFAULT; -}; - -} /* 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/parameter.cpp b/src/extension/prefdialog/parameter.cpp index 6a9c744b3..9bb87f7a2 100644 --- a/src/extension/prefdialog/parameter.cpp +++ b/src/extension/prefdialog/parameter.cpp @@ -21,13 +21,13 @@ #include "parameter.h" #include "parameter-bool.h" #include "parameter-color.h" -#include "parameter-description.h" #include "parameter-float.h" #include "parameter-int.h" #include "parameter-notebook.h" #include "parameter-optiongroup.h" #include "parameter-string.h" #include "widget.h" +#include "widget-label.h" #include "extension/extension.h" @@ -41,6 +41,24 @@ namespace Inkscape { namespace Extension { + +// Re-implement ParamDescription for backwards-compatibility, deriving from both, WidgetLabel and InxParameter. +// TODO: Should go away eventually... +class ParamDescription : public virtual WidgetLabel, public virtual InxParameter { +public: + ParamDescription(Inkscape::XML::Node *xml, Inkscape::Extension::Extension *ext) + : WidgetLabel(xml, ext) + , InxParameter(xml, ext) + {} + + Gtk::Widget *get_widget(SPDocument *doc, Inkscape::XML::Node *node, sigc::signal *changeSignal) override + { + return this->WidgetLabel::get_widget(doc, node, changeSignal); + } +}; + + + InxParameter *InxParameter::make(Inkscape::XML::Node *in_repr, Inkscape::Extension::Extension *in_ext) { InxParameter *param = nullptr; @@ -58,12 +76,13 @@ InxParameter *InxParameter::make(Inkscape::XML::Node *in_repr, Inkscape::Extensi } else if (!strcmp(type, "string")) { param = new ParamString(in_repr, in_ext); } else if (!strcmp(type, "description")) { + // support deprecated "description" for backwards-compatibility param = new ParamDescription(in_repr, in_ext); } else if (!strcmp(type, "notebook")) { param = new ParamNotebook(in_repr, in_ext); } else if (!strcmp(type, "optiongroup")) { param = new ParamOptionGroup(in_repr, in_ext); - } else if (!strcmp(type, "enum")) { // support deprecated "enum" for backwards-compatibilty + } else if (!strcmp(type, "enum")) { // support deprecated "enum" for backwards-compatibility in_repr->setAttribute("appearance", "combo"); param = new ParamOptionGroup(in_repr, in_ext); } else if (!strcmp(type, "color")) { diff --git a/src/extension/prefdialog/widget-label.cpp b/src/extension/prefdialog/widget-label.cpp new file mode 100644 index 000000000..64de11463 --- /dev/null +++ b/src/extension/prefdialog/widget-label.cpp @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** @file + * Description widget for extensions + *//* + * Authors: + * Ted Gould + * Johan Engelen * + * Patrick Storz + * + * Copyright (C) 2005-2019 Authors + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#include "widget-label.h" + +#include +#include +#include +#include + +#include "xml/node.h" +#include "extension/extension.h" + +namespace Inkscape { +namespace Extension { + + +WidgetLabel::WidgetLabel(Inkscape::XML::Node *xml, Inkscape::Extension::Extension *ext) + : InxWidget(xml, ext) +{ + // construct the text content by concatenating all (non-empty) text nodes, + // removing all other nodes (e.g. comment nodes) and replacing elements with "
" + 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(); + } + + // 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 value + if (!_value.empty()) { + if (_translatable != NO) { // translate unless explicitly marked untranslatable + _value = get_translation(_value.c_str()); + } + } + + // finally replace all remaining
with a real newline character + _value = Glib::Regex::create("
")->replace_literal(_value, 0, "\n", (Glib::RegexMatchFlags)0); + + // parse appearance + if (_appearance) { + if (!strcmp(_appearance, "header")) { + _mode = HEADER; + } else if (!strcmp(_appearance, "url")) { + _mode = URL; + } else { + g_warning("Invalid value ('%s') for appearance of label widget in extension '%s'", + _appearance, _extension->get_id()); + } + } +} + +/** \brief Create a label for the description */ +Gtk::Widget *WidgetLabel::get_widget (SPDocument * /*doc*/, Inkscape::XML::Node * /*node*/, sigc::signal * /*changeSignal*/) +{ + if (_hidden) { + 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 ridiculously 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 too narrow dialog instead and a lot of 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 > GUI_MAX_LINE_LENGTH ? 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/widget-label.h b/src/extension/prefdialog/widget-label.h new file mode 100644 index 000000000..57ffc5cb1 --- /dev/null +++ b/src/extension/prefdialog/widget-label.h @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/** @file + * Description widget for extensions + *//* + * Authors: + * Ted Gould + * Johan Engelen * + * Patrick Storz + * + * Copyright (C) 2005-2019 Authors + * + * Released under GNU GPL v2+, read the file 'COPYING' for more information. + */ + +#ifndef SEEN_INK_EXTENSION_WIDGET_LABEL_H +#define SEEN_INK_EXTENSION_WIDGET_LABEL_H + +#include "widget.h" + +class SPDocument; + +namespace Gtk { + class Widget; +} + +namespace Inkscape { +namespace Xml { + class Node; +} + +namespace Extension { + +/** \brief A description parameter */ +class WidgetLabel : public InxWidget { +public: + enum AppearanceMode { + DEFAULT, HEADER, URL + }; + + WidgetLabel(Inkscape::XML::Node *xml, Inkscape::Extension::Extension *ext); + + Gtk::Widget *get_widget(SPDocument *doc, Inkscape::XML::Node *node, sigc::signal *changeSignal) override; +private: + /** \brief Internal value. */ + Glib::ustring _value; + + /** appearance mode **/ + AppearanceMode _mode = DEFAULT; +}; + +} /* namespace Extension */ +} /* namespace Inkscape */ + +#endif /* SEEN_INK_EXTENSION_WIDGET_LABEL_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/widget.cpp b/src/extension/prefdialog/widget.cpp index ea02970ca..1297edb1c 100644 --- a/src/extension/prefdialog/widget.cpp +++ b/src/extension/prefdialog/widget.cpp @@ -11,6 +11,7 @@ */ #include "widget.h" +#include "widget-label.h" #include @@ -26,7 +27,17 @@ InxWidget *InxWidget::make(Inkscape::XML::Node *in_repr, Inkscape::Extension::Ex { InxWidget *widget = nullptr; - // Note: param could equal nullptr + const char *name = in_repr->name(); + if (!name) { + // we can't create a widget without name + g_warning("InxWidget without name in extension '%s'.", in_ext->get_id()); + } else if (!strcmp(name, "description")) { + widget = new WidgetLabel(in_repr, in_ext); + } else { + g_warning("Unknown widget name ('%s') in extension '%s'", name, in_ext->get_id()); + } + + // Note: widget could equal nullptr return widget; } -- cgit v1.2.3