Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
text-edit.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
6/* Authors:
7 * Lauris Kaplinski <lauris@ximian.com>
8 * bulia byak <buliabyak@users.sf.net>
9 * Johan Engelen <goejendaagh@zonnet.nl>
10 * Abhishek Sharma
11 * John Smith
12 * Tavmjong Bah
13 *
14 * Copyright (C) 1999-2013 Authors
15 * Copyright (C) 2000-2001 Ximian, Inc.
16 *
17 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
18 */
19
20#include <gtkmm/eventcontrollerkey.h>
21#include "preferences.h"
22#ifdef HAVE_CONFIG_H
23# include "config.h" // only include where actually required!
24#endif
25
26#include "text-edit.h"
27
28#include <algorithm>
29#include <memory>
30#include <string>
31
32#include <glibmm/i18n.h>
33#include <glibmm/markup.h>
34#include <glibmm/ustring.h>
35#include <gtkmm/box.h>
36#include <gtkmm/builder.h>
37#include <gtkmm/button.h>
38#include <gtkmm/label.h>
39#include <gtkmm/listbox.h>
40#include <gtkmm/listboxrow.h>
41#include <gtkmm/menubutton.h>
42#include <gtkmm/notebook.h>
43#include <gtkmm/searchentry2.h>
44#include <gtkmm/separator.h>
45#include <gtkmm/textbuffer.h>
46#include <gtkmm/textview.h>
47#ifdef WITH_LIBSPELLING
49#endif
50#include <sigc++/functors/mem_fun.h>
51
52#include "desktop-style.h"
53#include "desktop.h"
54#include "dialog-container.h"
55#include "document-undo.h"
56#include "inkscape.h"
59#include "object/sp-flowtext.h"
60#include "object/sp-text.h"
61#include "selection.h"
62#include "style.h"
64#include "text-editing.h"
65#include "ui/builder-utils.h"
66#include "ui/controller.h"
67#include "ui/icon-names.h"
68#include "ui/pack.h"
69#include "ui/util.h"
72#include "util/units.h"
73
74namespace Inkscape::UI::Dialog {
75namespace {
76
77Glib::ustring const &getSamplePhrase()
78{
79 /* TRANSLATORS: Test string used in text and font dialog (when no
80 * text has been entered) to get a preview of the font. Choose
81 * some representative characters that users of your locale will be
82 * interested in. */
83 static auto const samplephrase = Glib::ustring{_("AaBbCcIiPpQq12369$\342\202\254\302\242?.;/()")};
84 return samplephrase;
85}
86
87} // namespace
88
90 : DialogBase("/dialogs/textandfont", "Text")
91
92 , builder(create_builder("dialog-text-edit.glade"))
93 // Font
94 , settings_and_filters_box (get_widget<Gtk::Box> (builder, "settings_and_filters_box"))
95 , filter_menu_button (get_widget<Gtk::MenuButton> (builder, "filter_menu_button"))
96 , reset_button (get_widget<Gtk::Button> (builder, "reset_button"))
97 , search_entry (get_widget<Gtk::SearchEntry2>(builder, "search_entry"))
98 , font_count_label (get_widget<Gtk::Label> (builder, "font_count_label"))
99 , filter_popover (get_widget<Gtk::Popover> (builder, "filter_popover"))
100 , popover_box (get_widget<Gtk::Box> (builder, "popover_box"))
101 , frame (get_widget<Gtk::Frame> (builder, "frame"))
102 , frame_label (get_widget<Gtk::Label> (builder, "frame_label"))
103 , collection_editor_button (get_widget<Gtk::Button> (builder, "collection_editor_button"))
104 , collections_list (get_widget<Gtk::ListBox> (builder, "collections_list"))
105 , preview_label (get_widget<Gtk::Label> (builder, "preview_label"))
106 // Features
107 , preview_label2 (get_widget<Gtk::Label> (builder, "preview_label2"))
108 // Shared
109 , setasdefault_button (get_widget<Gtk::Button> (builder, "setasdefault_button"))
110 , apply_button (get_widget<Gtk::Button> (builder, "apply_button"))
111 , _apply_box (get_widget<Gtk::Box> (builder, "apply-box"))
112 , _undo{"doc.undo"}
113 , _redo{"doc.redo"}
114{
116 _use_browser = prefs->getInt("/options/font/browser", 0) != 0;
117
119 Inkscape::UI::Widget::FontList::create_font_list("/font-selector") :
121
122 auto font_collections = Inkscape::FontCollections::get();
123
124 auto contents = &get_widget<Gtk::Box> (builder, "contents");
125 auto notebook = &get_widget<Gtk::Notebook>(builder, "notebook");
126 auto font_box = &get_widget<Gtk::Box> (builder, "font_box");
127 auto feat_box = &get_widget<Gtk::Box> (builder, "feat_box");
128
129#ifdef WITH_LIBSPELLING
130 text_view = Gtk::manage(Glib::wrap(GTK_TEXT_VIEW(gtk_source_view_new())));
131#else
132 text_view = Gtk::make_managed<Gtk::TextView>();
133#endif
134 text_buffer = text_view->get_buffer();
135 text_view->property_height_request().set_value(64);
136 text_view->set_focusable();
137 text_view->set_wrap_mode(Gtk::WrapMode::WORD);
138 auto &text_view_container = get_widget<Gtk::ScrolledWindow>(builder, "text_view_container");
139 text_view_container.set_child(*text_view);
140
141 if (_use_browser) {
142 // hide settings and filter box
143 settings_and_filters_box.set_visible(false);
144 font_count_label.set_visible(false);
145 preview_label.set_visible(false);
146 }
147
148 font_box->insert_child_after(*font_list->box(), font_count_label);
149 UI::pack_start(*feat_box, font_features, true, true);
150 feat_box->reorder_child_after(font_features, *feat_box->get_first_child());
151
152 filter_popover.signal_show().connect([this] {
153 // update font collections checkboxes
155 }, false);
156
157#ifdef WITH_LIBSPELLING
158 // TODO: Use computed xml:lang attribute of relevant element, if present, to specify the language.
159 // onReadSelection() looks like a suitable place.
160 auto adapter = spelling_text_buffer_adapter_create(GTK_SOURCE_BUFFER(text_view->get_buffer()->gobj()), spelling_checker_get_default());
161 text_view->set_extra_menu(get_menu_model(*adapter));
162 text_view->insert_action_group("spelling", as_action_group(*adapter));
163 set_enabled(*adapter, true);
164#endif
165
166 append(*contents);
167
168 /* Signal handlers */
169 auto const key = Gtk::EventControllerKey::create();
170 key->signal_key_pressed().connect([this, &key = *key](auto&& ...args) { return captureUndo(key, args...); }, true);
171 text_view->add_controller(key);
172
173 text_buffer->signal_changed().connect([this] { onChange(); });
174
175 setasdefault_button.signal_clicked().connect([this] { onSetDefault(); });
176 apply_button.signal_clicked().connect([this] { onApply(); });
178 search_entry.signal_search_changed().connect([this] { on_search_entry_changed(); });
179 reset_button.signal_clicked().connect([this] { on_reset_button_pressed(); });
180 collection_editor_button.signal_clicked().connect([this] { on_fcm_button_clicked(); });
182 fontCollectionsUpdate = font_collections->connect_update([this] { display_font_collections(); });
183 fontCollectionsChangedSelection = font_collections->connect_selection_update([this] {
184 auto font_collections = Inkscape::FontCollections::get();
186 int selected_count = font_collections->get_selected_collections_count();
187 reset_button.set_sensitive(selected_count != 0);
188 });
189
191
193 notebook->signal_switch_page().connect(sigc::mem_fun(*this, &TextEdit::on_page_changed));
194 _font_changed = font_list->signal_changed().connect([this](){ apply_changes(true); });
195 _apply_font = font_list->signal_apply().connect([this](){ onChange(); onSetDefault(); });
196
197 on_page_changed(nullptr, 0);
198}
199
200TextEdit::~TextEdit() = default;
201
202bool TextEdit::captureUndo(Gtk::EventControllerKey const &controller,
203 unsigned keyval, unsigned keycode, Gdk::ModifierType state)
204{
205 for (auto const accel: {&_undo, &_redo}) {
206 if (accel->isTriggeredBy(controller, keyval, keycode, state)) {
207 /*
208 * TODO: Handle these events separately after switching to GTKMM4
209 * e.g. try to use the built-in undo/redo of GtkEditable, etc.
210 * Fixes: https://gitlab.com/inkscape/inkscape/-/issues/744
211 */
212 return true;
213 }
214 }
215
216 return false;
217}
218
219void TextEdit::onReadSelection ( bool dostyle, bool /*docontent*/ )
220{
221 if (blocked)
222 return;
223
224 blocked = true;
225
226 SPItem *text = getSelectedTextItem ();
227
228 auto phrase = getSamplePhrase();
229
230 if (text)
231 {
232 guint items = getSelectedTextCount ();
233 bool has_one_item = items == 1;
234 text_view->set_sensitive(has_one_item);
235 apply_button.set_sensitive(false);
236 setasdefault_button.set_sensitive(true);
237
238 Glib::ustring str = sp_te_get_string_multiline(text);
239 if (!str.empty()) {
240 if (has_one_item) {
241 text_buffer->set_text(str);
242 text_buffer->set_modified(false);
243 }
244 phrase = str;
245
246 } else {
247 text_buffer->set_text("");
248 }
249
250 text->getRepr(); // was being called but result ignored. Check this.
251 } else {
252 text_view->set_sensitive(false);
253 apply_button.set_sensitive(false);
254 setasdefault_button.set_sensitive(false);
255 }
256
257 if (dostyle && text) {
258 auto *desktop = getDesktop();
259
260 // create temporary style
261 SPStyle query(desktop->getDocument());
262
263 // Query style from desktop into it. This returns a result flag and fills query with the
264 // style of subselection, if any, or selection
265
267
268 // If querying returned nothing, read the style from the text tool prefs (default style for new texts).
269 if (result_numbers == QUERY_STYLE_NOTHING) {
270 query.readFromPrefs("/tools/text");
271 }
272
274
275 // Update family/style based on selection.
276 font_lister->selection_update();
277 Glib::ustring fontspec = font_lister->get_fontspec();
278 // Update Font Face.
279 // font_selector.update_font ();
280 font_list->set_current_font(font_lister->get_font_family(), font_lister->get_font_style());
281
282 // Update Size.
284 int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT);
285 double size = sp_style_css_size_px_to_units(query.font_size.computed, unit);
287 font_list->set_current_size(size);
288 // Update font features (variant) widget
289 //int result_features =
291 int result_features =
293 font_features.update( &query, result_features == QUERY_STYLE_MULTIPLE_DIFFERENT, fontspec );
294 Glib::ustring features = font_features.get_markup();
295
296 // Update Preview
297 setPreviewText (fontspec, features, phrase);
298 }
299
300 blocked = false;
301}
302
303
304void TextEdit::setPreviewText (Glib::ustring const &font_spec, Glib::ustring const &font_features,
305 Glib::ustring const &phrase)
306{
307 if (_use_browser) return;
308
309 if (font_spec.empty()) {
310 preview_label.set_markup("");
311 preview_label2.set_markup("");
312 return;
313 }
314
315 // Limit number of lines in preview to arbitrary amount to prevent Text and Font dialog
316 // from growing taller than a desktop
317 const int max_lines = 4;
318 // Ignore starting empty lines; they would show up as nothing
319 auto start_pos = phrase.find_first_not_of(" \n\r\t");
320 if (start_pos == Glib::ustring::npos) {
321 start_pos = 0;
322 }
323 // Now take up to max_lines
324 auto end_pos = Glib::ustring::npos;
325 auto from = start_pos;
326 for (int i = 0; i < max_lines; ++i) {
327 end_pos = phrase.find("\n", from);
328 if (end_pos == Glib::ustring::npos) { break; }
329 from = end_pos + 1;
330 }
331 Glib::ustring phrase_trimmed = phrase.substr(start_pos, end_pos != Glib::ustring::npos ? end_pos - start_pos : end_pos);
332
333 Glib::ustring font_spec_escaped = Glib::Markup::escape_text( font_spec );
334 Glib::ustring phrase_escaped = Glib::Markup::escape_text(phrase_trimmed);
335
337 int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT);
338 double pt_size =
340 sp_style_css_size_units_to_px(font_list->get_fontsize(), unit), "px", "pt");
341 pt_size = std::min(pt_size, 100.0);
342 // Pango font size is in 1024ths of a point
343 auto const size = std::to_string(static_cast<int>(pt_size * PANGO_SCALE));
344
345 auto font_features_attr = Glib::ustring{};
346 if (!font_features.empty()) {
347 font_features_attr = Glib::ustring::compose("font_features='%1'", font_features);
348 }
349
350 auto const markup = Glib::ustring::compose("<span font='%1' size='%2' %3>%4</span>",
351 font_spec_escaped, size, font_features_attr,
352 phrase_escaped);
353 preview_label.set_markup (markup);
354 preview_label2.set_markup (markup);
355}
356
358{
359 if (!getDesktop())
360 return nullptr;
361
362 auto tmp= getDesktop()->getSelection()->items();
363 for(auto i=tmp.begin();i!=tmp.end();++i)
364 {
365 if (is<SPText>(*i) || is<SPFlowtext>(*i))
366 return *i;
367 }
368
369 return nullptr;
370}
371
372
374{
375 if (!getDesktop())
376 return 0;
377
378 unsigned int items = 0;
379
380 auto tmp= getDesktop()->getSelection()->items();
381 for(auto i=tmp.begin();i!=tmp.end();++i)
382 {
383 if (is<SPText>(*i) || is<SPFlowtext>(*i))
384 ++items;
385 }
386
387 return items;
388}
389
391{
392 onReadSelection(true, true);
393}
394
396{
397 onReadSelection(true, true);
398}
399
400void TextEdit::selectionModified(Selection *selection, guint flags)
401{
402 bool style = ((flags & (SP_OBJECT_CHILD_MODIFIED_FLAG |
403 SP_OBJECT_STYLE_MODIFIED_FLAG )) != 0 );
404 bool content = ((flags & (SP_OBJECT_CHILD_MODIFIED_FLAG |
405 SP_TEXT_CONTENT_MODIFIED_FLAG )) != 0 );
406 onReadSelection (style, content);
407}
408
409
411{
412 Gtk::TextIter start, end;
413
414 // write text
415 if (text_buffer->get_modified()) {
416 text_buffer->get_bounds(start, end);
417 Glib::ustring str = text_buffer->get_text(start, end);
418 sp_te_set_repr_text_multiline (text, str.c_str());
419 text_buffer->set_modified(false);
420 }
421}
422
424{
426
427 Glib::ustring fontspec = font_list->get_fontspec();
428
429 if( !fontspec.empty() ) {
430
432 fontlister->fill_css( css, fontspec );
433
434 // TODO, possibly move this to FontLister::set_css to be shared.
437 int unit = prefs->getInt("/options/font/unitType", SP_CSS_UNIT_PT);
438 if (prefs->getBool("/options/font/textOutputPx", true)) {
439 os << sp_style_css_size_units_to_px(font_list->get_fontsize(), unit)
441 } else {
442 os << font_list->get_fontsize() << sp_style_get_css_unit_string(unit);
443 }
444 sp_repr_css_set_property (css, "font-size", os.str().c_str());
445 }
446
447 // Font features
449
450 return css;
451}
452
454{
457
458 blocked = true;
459 prefs->mergeStyle("/tools/text/style", css);
460 blocked = false;
461
463
464 setasdefault_button.set_sensitive ( false );
465}
466
468{
469 apply_changes(false);
470}
471
472void TextEdit::apply_changes(bool continuous) {
473 blocked = true;
474
476
477 unsigned items = 0;
478 auto item_list = desktop->getSelection()->items();
481 for(auto i=item_list.begin();i!=item_list.end();++i){
482 // apply style to the reprs of all text objects in the selection
483 if (is<SPText>(*i) || (is<SPFlowtext>(*i)) ) {
484 ++items;
485 }
486 }
487 if (items == 1) {
488 double factor = font_list->get_fontsize() / selected_fontsize;
489 prefs->setDouble("/options/font/scaleLineHeightFromFontSIze", factor);
490 }
492
493 if (items == 0) {
494 // no text objects; apply style to prefs for new objects
495 prefs->mergeStyle("/tools/text/style", css);
496 setasdefault_button.set_sensitive ( false );
497
498 } else if (items == 1) {
499 // exactly one text object; now set its text, too
501 if (is<SPText>(item) || is<SPFlowtext>(item)) {
503 SPStyle *item_style = item->style;
504 if (is<SPText>(item) && item_style->inline_size.value == 0) {
506 sp_repr_css_unset_property(css, "inline-size");
507 item->changeCSS(css, "style");
508 }
509 }
510 }
511
512 // Update FontLister
513 Glib::ustring fontspec = font_list->get_fontspec();
515 if( !fontspec.empty() ) {
516 fontlister->set_fontspec( fontspec, false );
517 }
518
519 auto recent_fonts = Inkscape::RecentlyUsedFonts::get();
520
521 if (continuous && recent_fonts->get_continuous_streak()) {
522 recent_fonts->pop_front();
523 }
524
525 recent_fonts->prepend_to_list(fontlister->get_font_family());
526 recent_fonts->set_continuous_streak(continuous);
527
528 // complete the transaction
529 if (continuous) {
530 DocumentUndo::maybeDone(desktop->getDocument(), "text-style", _("Set text style"), INKSCAPE_ICON("draw-text"));
531 }
532 else {
533 DocumentUndo::done(desktop->getDocument(), _("Set text style"), INKSCAPE_ICON("draw-text"));
534 apply_button.set_sensitive(false);
535 }
536
539
540 blocked = false;
541}
542
544{
546
548
549 // Insert system collections.
550 for(auto const& col: font_collections->get_collections(true)) {
551 auto const btn = Gtk::make_managed<Gtk::CheckButton>(col);
552 btn->set_margin_bottom(2);
553 btn->set_active(font_collections->is_collection_selected(col));
554 btn->signal_toggled().connect([=](){
555 // toggle font system collection
556 font_collections->update_selected_collections(col);
557 });
558 auto const row = Gtk::make_managed<Gtk::ListBoxRow>();
559 row->set_focusable(false);
560 row->set_child(*btn);
561 collections_list.append(*row);
562 }
563
564 // Insert row separator.
565 auto const sep = Gtk::make_managed<Gtk::Separator>();
566 sep->set_margin_bottom(2);
567 auto const sep_row = Gtk::make_managed<Gtk::ListBoxRow>();
568 sep_row->set_focusable(false);
569 sep_row->set_child(*sep);
570 collections_list.append(*sep_row);
571
572 // Insert user collections.
573 for (auto const& col: font_collections->get_collections()) {
574 auto const btn = Gtk::make_managed<Gtk::CheckButton>(col);
575 btn->set_margin_bottom(2);
576 btn->set_active(font_collections->is_collection_selected(col));
577 btn->signal_toggled().connect([=](){
578 // toggle font collection
579 font_collections->update_selected_collections(col);
580 });
581 auto const row = Gtk::make_managed<Gtk::ListBoxRow>();
582 row->set_focusable(false);
583 row->set_child(*btn);
584 collections_list.append(*row);
585 }
586}
587
588void TextEdit::on_page_changed(Gtk::Widget*, int pos)
589{
590 _apply_box.set_visible(pos != 0 || !_use_browser); // font browser doesn't use "Apply" button
591
592 if (pos == 1) {
593 Glib::ustring fontspec = font_list->get_fontspec();
594 if (!fontspec.empty()) {
595 auto res = FontFactory::get().FaceFromFontSpecification(fontspec.c_str());
596 if (res) {
598 }
599 }
600 }
601}
602
604{
605 auto search_txt = search_entry.get_text();
606 font_list->unset_model();
608 font_lister->show_results(search_txt);
609
612 font_list->set_model();
613}
614
616{
618 search_entry.set_text("");
619
620 // Un-select all the selected font collections.
621 font_collections->clear_selected_collections();
622
624 font_lister->init_font_families();
625 font_lister->init_default_styles();
628}
629
635
637{
638 // Inkscape::UI::Dialog::FontCollectionsManager::getInstance();
639 if(auto desktop = SP_ACTIVE_DESKTOP) {
640 if (auto container = desktop->getContainer()) {
641 container->new_floating_dialog("FontCollections");
642 }
643 }
644}
645
647{
648 if (blocked) {
649 return;
650 }
651
652 Gtk::TextIter start, end;
653 text_buffer->get_bounds(start, end);
654 Glib::ustring str = text_buffer->get_text(start, end);
655
656 Glib::ustring fontspec = font_list->get_fontspec();
657 Glib::ustring features = font_features.get_markup();
658 auto const &phrase = str.empty() ? getSamplePhrase() : str;
659 setPreviewText(fontspec, features, phrase);
660
661 SPItem *text = getSelectedTextItem();
662 if (text) {
663 apply_button.set_sensitive ( true );
664 }
665
666 setasdefault_button.set_sensitive ( true);
667}
668
669void TextEdit::onFontChange(Glib::ustring const & /*fontspec*/)
670{
671 // Is not necessary update open type features this done when user click on font features tab
672 onChange();
673}
674
675} // namespace Inkscape::UI::Dialog
676
677/*
678 Local Variables:
679 mode:c++
680 c-file-style:"stroustrup"
681 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
682 indent-tabs-mode:nil
683 fill-column:99
684 End:
685*/
686// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :
Gtk builder utilities.
std::shared_ptr< FontInstance > FaceFromFontSpecification(char const *fontSpecification)
A thin wrapper around std::ostringstream, but writing floating point numbers in the format required b...
static void done(SPDocument *document, Glib::ustring const &event_description, Glib::ustring const &undo_icon, unsigned int object_modified_tag=0)
static void maybeDone(SPDocument *document, const gchar *keyconst, Glib::ustring const &event_description, Glib::ustring const &undo_icon, unsigned int object_modified_tag=0)
static FontCollections * get()
void update_selected_collections(const Glib::ustring &collection_name)
bool is_collection_selected(const Glib::ustring &collection_name)
std::vector< Glib::ustring > get_collections(bool is_system=false) const
This class enumerates fonts using libnrtype into reusable data stores and allows for random access to...
Definition font-lister.h:84
std::pair< bool, std::string > get_font_count_label() const
void set_fontspec(Glib::ustring const &fontspec, bool check=true)
Sets current_fontspec, etc.
std::pair< Glib::ustring, Glib::ustring > selection_update()
Sets font-family and style after a selection change.
void update_font_list(SPDocument *document)
Updates font list to include fonts in document.
void fill_css(SPCSSAttr *css, Glib::ustring fontspec={})
Fill css using given fontspec (doesn't need to be member function).
void init_font_families(int group_offset=-1, int group_size=-1)
int add_document_fonts_at_top(SPDocument *document)
Glib::ustring const & get_font_style() const
void show_results(Glib::ustring const &search_text)
static Inkscape::FontLister * get_instance()
Glib::ustring get_fontspec() const
sigc::connection connectUpdate(sigc::slot< void()> slot)
Let users of FontLister know to update GUI.
Glib::ustring const & get_font_family() const
SPItemRange items()
Returns a range of selected SPItems.
Definition object-set.h:255
SPItem * singleItem()
Returns a single selected item.
Preference storage class.
Definition preferences.h:61
bool getBool(Glib::ustring const &pref_path, bool def=false)
Retrieve a Boolean value.
static Preferences * get()
Access the singleton Preferences object.
int getInt(Glib::ustring const &pref_path, int def=0)
Retrieve an integer.
void setDouble(Glib::ustring const &pref_path, double value)
Set a floating point value.
void mergeStyle(Glib::ustring const &pref_path, SPCSSAttr *style)
Merge a CSS style with the current preference value.
static RecentlyUsedFonts * get()
The set of selected SPObjects for a given document and layer model.
Definition selection.h:80
DialogBase is the base class for the dialog system.
Definition dialog-base.h:42
SPDesktop * getDesktop() const
Definition dialog-base.h:79
Gtk::SearchEntry2 & search_entry
Definition text-edit.h:171
Glib::RefPtr< Gtk::TextBuffer > text_buffer
Definition text-edit.h:185
sigc::scoped_connection fontFeaturesChangedConn
Definition text-edit.h:202
void apply_changes(bool continuous)
void onApply()
Callback for pressing the apply button.
void onFontChange(Glib::ustring const &fontspec)
Callback invoked when the user modifies the font through the dialog or the tools control bar.
void onReadSelection(bool style, bool content)
Called whenever something 'changes' on canvas.
void display_font_collections()
Function to list the font collections in the popover menu.
Inkscape::UI::Widget::FontVariants font_features
Definition text-edit.h:188
void onChange()
Callback invoked when the user modifies the text of the selected text object.
sigc::scoped_connection fontCollectionsChangedSelection
Definition text-edit.h:203
void onSetDefault()
Callback for pressing the default button.
SPItem * getSelectedTextItem()
Get the selected text off the main canvas.
bool captureUndo(Gtk::EventControllerKey const &controller, unsigned keyval, unsigned keycode, Gdk::ModifierType state)
This function would disable undo and redo if the text_view widget is in focus It is to fix the issue:...
Glib::RefPtr< Gtk::Builder > builder
Definition text-edit.h:161
void selectionModified(Selection *selection, guint flags) final
unsigned getSelectedTextCount()
Count the number of text objects in the selection on the canvas.
sigc::scoped_connection _apply_font
Definition text-edit.h:205
void selectionChanged(Selection *selection) final
void updateObjectText(SPItem *text)
Gtk::Button & collection_editor_button
Definition text-edit.h:177
Gtk::Button & setasdefault_button
Definition text-edit.h:192
sigc::scoped_connection _font_changed
Definition text-edit.h:206
void setPreviewText(Glib::ustring const &font_spec, Glib::ustring const &font_features, Glib::ustring const &phrase)
Helper function to create markup from a fontspec and display in the preview label.
sigc::scoped_connection fontCollectionsUpdate
Definition text-edit.h:204
void on_page_changed(Gtk::Widget *widgt, int pos)
Gtk::ListBox & collections_list
Definition text-edit.h:178
std::unique_ptr< FontSelectorInterface > font_list
Definition text-edit.h:181
static std::unique_ptr< FontSelectorInterface > create_font_selector()
void update(SPStyle const *query, bool different_features, Glib::ustring &font_spec)
Update GUI based on query results.
void fill_css(SPCSSAttr *css)
Fill SPCSSAttr based on settings of buttons.
Glib::ustring get_markup()
Get CSS string for markup.
void update_opentype(Glib::ustring &font_spec)
Update GUI based on OpenType features of selected font.
sigc::connection connectChanged(sigc::slot< void()> slot)
Let others know that user has changed GUI settings.
Creates a Gnome HIG style indented frame with bold label See http://developer.gnome....
Definition frame.h:24
static FontFactory & get(Args &&... args)
Definition statics.h:153
static double convert(double from_dist, Unit const *from, Unit const *to)
Convert distances.
Definition units.cpp:588
To do: update description of desktop.
Definition desktop.h:149
SPDocument * getDocument() const
Definition desktop.h:189
Inkscape::UI::Dialog::DialogContainer * getContainer()
Definition desktop.cpp:335
Inkscape::Selection * getSelection() const
Definition desktop.h:188
Typed SVG document implementation.
Definition document.h:101
Base class for visual SVG elements.
Definition sp-item.h:109
void changeCSS(SPCSSAttr *css, char const *attr)
SPStyle * style
Represents the style properties, whether from presentation attributes, the style attribute,...
Definition sp-object.h:248
Inkscape::XML::Node * getRepr()
Returns the XML representation of tree.
An SVG style object.
Definition style.h:45
T< SPAttr::INLINE_SIZE, SPILength > inline_size
Definition style.h:183
void readFromPrefs(Glib::ustring const &path)
Read style properties from preferences.
Definition style.cpp:625
T< SPAttr::FONT_SIZE, SPIFontSize > font_size
Size of the font.
Definition style.h:116
Utilities to more easily use Gtk::EventController & subclasses like Gesture.
TODO: insert short description here.
std::shared_ptr< Css const > css
void sp_desktop_set_style(SPDesktop *desktop, SPCSSAttr *css, bool change, bool write_current, bool switch_style)
Apply style on selection on desktop.
int sp_desktop_query_style(SPDesktop *desktop, SPStyle *style, int property)
Query the subselection (if any) or selection on the given desktop for the given property,...
@ QUERY_STYLE_PROPERTY_FONTNUMBERS
@ QUERY_STYLE_PROPERTY_FONTFEATURESETTINGS
@ QUERY_STYLE_PROPERTY_FONTVARIANTS
@ QUERY_STYLE_MULTIPLE_DIFFERENT
@ QUERY_STYLE_NOTHING
Editable view implementation.
A widget that manages DialogNotebook's and other widgets inside a horizontal DialogMultipaned.
TODO: insert short description here.
TODO: insert short description here.
Font selection widgets.
Macro for icon names used in Inkscape.
SPItem * item
C++ wrapping for libspelling C API.
Glib::ustring label
Definition desktop.h:50
Dialog code.
Definition desktop.h:117
void remove_all_children(Widget &widget)
For each child in get_children(widget), call widget.remove(*child). May not cause delete child!
Definition util.h:88
void set_enabled(SpellingTextBufferAdapter &adapter, bool enabled)
auto spelling_text_buffer_adapter_create(GtkSourceBuffer *buffer, SpellingChecker *checker)
auto get_menu_model(SpellingTextBufferAdapter &adapter)
W & get_widget(const Glib::RefPtr< Gtk::Builder > &builder, const char *id)
auto as_action_group(SpellingTextBufferAdapter &adapter)
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
Glib::RefPtr< Gtk::Builder > create_builder(const char *filename)
static void append(std::vector< T > &target, std::vector< T > &&source)
static cairo_user_data_key_t key
Helpers for using Gtk::Boxes, encapsulating large changes between GTK3 & GTK4.
Singleton class to access the preferences file in a convenient way.
SPCSSAttr * sp_repr_css_attr_new()
Creates an empty SPCSSAttr (a class for manipulating CSS style properties).
Definition repr-css.cpp:67
void sp_repr_css_attr_unref(SPCSSAttr *css)
Unreferences an SPCSSAttr (will be garbage collected if no references remain).
Definition repr-css.cpp:76
void sp_repr_css_unset_property(SPCSSAttr *css, gchar const *name)
Set a style property to "inkscape:unset".
Definition repr-css.cpp:201
void sp_repr_css_set_property(SPCSSAttr *css, gchar const *name, gchar const *value)
Set a style property to a new value (e.g.
Definition repr-css.cpp:190
GList * items
TODO: insert short description here.
static const unsigned SP_STYLE_FLAG_IFSET(1<< 0)
@ SP_CSS_UNIT_PT
@ SP_CSS_UNIT_PX
double sp_style_css_size_px_to_units(double size, int unit, double font_size)
Definition style.cpp:1332
double sp_style_css_size_units_to_px(double size, int unit, double font_size)
Definition style.cpp:1367
SPCSSAttr * sp_css_attr_from_style(SPStyle const *const style, guint const flags)
Definition style.cpp:1409
gchar const * sp_style_get_css_unit_string(int unit)
Definition style.cpp:1305
SPStyle - a style object for SPItem objects.
Text-edit.
Glib::ustring sp_te_get_string_multiline(SPItem const *text)
Gets a text-only representation of the given text or flowroot object, replacing line break elements w...
void sp_te_set_repr_text_multiline(SPItem *text, gchar const *str)
Glib::RefPtr< Gtk::Builder > builder