Inkscape
Vector Graphics Editor
parameter-string.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (C) 2005-2007 Authors:
4 * Ted Gould <ted@gould.cx>
5 * Johan Engelen <johan@shouraizou.nl> *
6 * Jon A. Cruz <jon@joncruz.org>
7 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
8 */
9
10#include "parameter-string.h"
11
12#include <utility>
13#include <glibmm/regex.h>
14#include <gtkmm/box.h>
15#include <gtkmm/entry.h>
16#include <gtkmm/label.h>
17#include <gtkmm/scrolledwindow.h>
18#include <gtkmm/textview.h>
19
20#include "extension/extension.h"
21#include "preferences.h"
22#include "ui/pack.h"
23#include "xml/node.h"
24
25namespace Inkscape::Extension {
26
28 : InxParameter(xml, ext)
29{
30 // get value
31 const char *value = nullptr;
32 if (xml->firstChild()) {
33 value = xml->firstChild()->content();
34 }
35
37 _value = prefs->getString(pref_name());
38
39 if (_value.empty() && value) {
40 _value = value;
41 }
42
43 // translate value
44 if (!_value.empty()) {
45 if (_translatable == YES) { // translate only if explicitly marked translatable
46 _value = get_translation(_value.c_str());
47 }
48 }
49
50 // max-length
51 const char *max_length = xml->attribute("max-length");
52 if (!max_length) {
53 max_length = xml->attribute("max_length"); // backwards-compatibility with old name (underscore)
54 }
55 if (max_length) {
56 _max_length = strtoul(max_length, nullptr, 0);
57 }
58
59 // parse appearance
60 if (_appearance) {
61 if (!strcmp(_appearance, "multiline")) {
63 } else {
64 g_warning("Invalid value ('%s') for appearance of parameter '%s' in extension '%s'",
66 }
67 }
68}
69
77const Glib::ustring& ParamString::set(Glib::ustring in)
78{
79 _value = std::move(in);
81 prefs->setString(pref_name(), _value);
82 return _value;
83}
84
86{
87 return _value.raw();
88}
89
90void ParamString::string_to_value(const std::string &in)
91{
92 _value = in;
93}
94
96class ParamStringEntry : public Gtk::Entry {
97private:
98 ParamString *_pref;
99 sigc::signal<void ()> *_changeSignal;
100public:
106 ParamStringEntry(ParamString *pref, sigc::signal<void ()> *changeSignal)
107 : Gtk::Entry()
108 , _pref(pref)
109 , _changeSignal(changeSignal)
110 {
111 this->set_text(_pref->get());
112 this->set_max_length(_pref->getMaxLength()); //Set the max length - default zero means no maximum
113 this->signal_changed().connect(sigc::mem_fun(*this, &ParamStringEntry::changed_text));
114 };
115 void changed_text();
116};
117
118
125void ParamStringEntry::changed_text()
126{
127 Glib::ustring data = this->get_text();
128 _pref->set(data.c_str());
129 if (_changeSignal != nullptr) {
130 _changeSignal->emit();
131 }
132}
133
134
135
137class ParamMultilineStringEntry : public Gtk::TextView {
138private:
139 ParamString *_pref;
140 sigc::signal<void ()> *_changeSignal;
141public:
147 ParamMultilineStringEntry(ParamString *pref, sigc::signal<void ()> *changeSignal)
148 : Gtk::TextView()
149 , _pref(pref)
150 , _changeSignal(changeSignal)
151 {
152 // replace literal '\n' with actual newlines for multiline strings
153 Glib::ustring value = Glib::Regex::create("\\\\n")->replace_literal(_pref->get(), 0, "\n", (Glib::Regex::MatchFlags)0);
154
155 this->get_buffer()->set_text(value);
156 this->get_buffer()->signal_changed().connect(sigc::mem_fun(*this, &ParamMultilineStringEntry::changed_text));
157 };
158 void changed_text();
159};
160
167void ParamMultilineStringEntry::changed_text()
168{
169 Glib::ustring data = this->get_buffer()->get_text();
170
171 // always store newlines as literal '\n'
172 data = Glib::Regex::create("\n")->replace_literal(data, 0, "\\n", (Glib::Regex::MatchFlags)0);
173
174 _pref->set(data.c_str());
175 if (_changeSignal != nullptr) {
176 _changeSignal->emit();
177 }
178}
179
180
181
187Gtk::Widget *ParamString::get_widget(sigc::signal<void ()> *changeSignal)
188{
189 if (_hidden) {
190 return nullptr;
191 }
192
193 auto const box = Gtk::make_managed<Gtk::Box>(Gtk::Orientation::HORIZONTAL, GUI_PARAM_WIDGETS_SPACING);
194
195 auto const label = Gtk::make_managed<Gtk::Label>(_text, Gtk::Align::START);
196 UI::pack_start(*box, *label, false, false);
197
198 if (_mode == MULTILINE) {
199 box->set_orientation(Gtk::Orientation::VERTICAL);
200
201 auto const textarea = Gtk::make_managed<Gtk::ScrolledWindow>();
202 textarea->set_vexpand();
203 textarea->set_has_frame(true);
204
205 auto const entry = Gtk::make_managed<ParamMultilineStringEntry>(this, changeSignal);
206 textarea->set_child(*entry);
207
208 UI::pack_start(*box, *textarea, true, true);
209 } else {
210 Gtk::Widget *entry = Gtk::make_managed<ParamStringEntry>(this, changeSignal);
211 UI::pack_start(*box, *entry, true, true);
212 }
213
214 return box;
215}
216
217} // namespace Inkscape::Extension
The object that is the basis for the Extension system.
Definition: extension.h:130
char const * get_id() const
Get the ID of this extension - not a copy don't delete!
Definition: extension.cpp:316
A class to represent the parameter of an extension.
Definition: parameter.h:34
char * _name
The name of this parameter.
Definition: parameter.h:133
static constexpr int GUI_PARAM_WIDGETS_SPACING
Recommended spacing between the widgets making up a single Parameter (e.g.
Definition: parameter.h:119
Glib::ustring pref_name() const
Build preference name for the current parameter.
Definition: parameter.cpp:281
char * _text
Parameter text to show as the GUI label.
Definition: parameter.h:136
Inkscape::Extension::Extension * _extension
Which extension is this Widget attached to.
Definition: widget.h:102
bool _hidden
Whether the widget is visible.
Definition: widget.h:108
const char * get_translation(const char *msgid)
gets the gettext translation for msgid
Definition: widget.cpp:155
char * _appearance
Appearance of the widget (not used by all widgets).
Definition: widget.h:115
Translatable _translatable
Is widget translatable?
Definition: widget.h:118
std::string value_to_string() const override
Gets the current value of the parameter in a string form.
const Glib::ustring & get() const
Returns _value, with a \i const to protect it.
void string_to_value(const std::string &in) override
Sets the current value of the parameter from a string.
Glib::ustring _value
Internal value.
const Glib::ustring & set(Glib::ustring in)
A function to set the _value.
ParamString(Inkscape::XML::Node *xml, Inkscape::Extension::Extension *ext)
Gtk::Widget * get_widget(sigc::signal< void()> *changeSignal) override
Creates a text box for the string parameter.
AppearanceMode _mode
appearance mode
int _max_length
Maximum length of the string in characters (zero meaning unlimited).
Preference storage class.
Definition: preferences.h:63
Glib::ustring getString(Glib::ustring const &pref_path, Glib::ustring const &def="")
Retrieve an UTF-8 string.
Definition: preferences.h:446
static Preferences * get()
Access the singleton Preferences object.
Definition: preferences.h:599
void setString(Glib::ustring const &pref_path, Glib::ustring const &value)
Set an UTF-8 string value.
Interface for refcounted XML nodes.
Definition: node.h:80
virtual Node * firstChild()=0
Get the first child of this node.
virtual char const * attribute(char const *key) const =0
Get the string representation of a node's attribute.
virtual char const * content() const =0
Get the content of a text or comment node.
Inkscape::Extension::Extension: Frontend to certain, possibly pluggable, actions.
Definition: desktop.h:51
Extension support.
void pack_start(Gtk::Box &box, Gtk::Widget &child, bool const expand, bool const fill, unsigned const padding)
Adds child to box, packed with reference to the start of box.
Definition: pack.cpp:141
@ HORIZONTAL
The x-dimension (0).
Definition: rectangle.h:43
@ VERTICAL
The y-dimension (1).
Definition: rectangle.h:47
Helpers for using Gtk::Boxes, encapsulating large changes between GTK3 & GTK4.
unsigned char * data
Singleton class to access the preferences file in a convenient way.
std::unique_ptr< Toolbar >(* create)(SPDesktop *desktop)
Definition: toolbars.cpp:63
Interface for XML nodes.