Inkscape
Vector Graphics Editor
Loading...
Searching...
No Matches
inkscape.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-or-later
6/* Authors:
7 * Lauris Kaplinski <lauris@kaplinski.com>
8 * bulia byak <buliabyak@users.sf.net>
9 * Liam P. White <inkscapebrony@gmail.com>
10 *
11 * Copyright (C) 1999-2014 authors
12 * c++ port Copyright (C) 2003 Nathan Hurst
13 * c++ification Copyright (C) 2014 Liam P. White
14 *
15 * Released under GNU GPL v2+, read the file 'COPYING' for more information.
16 */
17
18#include <unistd.h>
19
20#include <fstream>
21#include <map>
22#include <boost/stacktrace.hpp>
23#undef near
24#undef IGNORE
25#include <glibmm/regex.h>
26#include <glibmm/i18n.h>
27#include <glibmm/miscutils.h>
28#include <glibmm/convert.h>
29#include <glibmm/main.h>
30#include <gtkmm/icontheme.h>
31#include <gtkmm/label.h>
32#include <gtkmm/messagedialog.h>
33#include <gtkmm/recentmanager.h>
34#include <gtkmm/textbuffer.h>
35
36#include "desktop.h"
37#include "document.h"
38#include "inkscape.h"
41#include "inkscape-window.h"
42#include "message-stack.h"
43#include "path-prefix.h"
44#include "selection.h"
45
46#include "debug/simple-event.h"
47#include "debug/event-tracker.h"
48#include "io/resource.h"
49#include "io/sys.h"
52#include "object/sp-root.h"
53#include "io/resource.h"
54#include "ui/builder-utils.h"
55#include "ui/themes.h"
56#include "ui/dialog-events.h"
57#include "ui/dialog-run.h"
60#include "ui/themes.h"
61#include "ui/tools/tool-base.h"
62#include "ui/util.h"
64#include "util/font-discovery.h"
65#include "util/units.h"
66
67// Inkscape::Application static members
70
71#define DESKTOP_IS_ACTIVE(d) (INKSCAPE._desktops != nullptr && !INKSCAPE._desktops->empty() && ((d) == INKSCAPE._desktops->front()))
72
73static void (* segv_handler) (int) = SIG_DFL;
74static void (* abrt_handler) (int) = SIG_DFL;
75static void (* fpe_handler) (int) = SIG_DFL;
76static void (* ill_handler) (int) = SIG_DFL;
77#ifndef _WIN32
78static void (* bus_handler) (int) = SIG_DFL;
79#endif
80
81static constexpr int SP_INDENT = 8;
82
95{
96 in.refCount++;
97}
98
100{
101 in.refCount--;
102
104 if (in.refCount <= 0) {
106 }
107 } else {
108 g_error("Attempt to unref an Application (=%p) not the current instance (=%p) (maybe it's already been destroyed?)",
110 }
111}
112
113namespace Inkscape {
114
119Application*
121{
122 return const_cast<Application*>(this);
123}
127void
129{
130 if (!Application::exists()) {
131 new Application(use_gui);
132 } else {
133 // g_assert_not_reached(); Can happen with InkscapeApplication
134 }
135}
136
137
141bool
143{
144 return Application::_S_inst != nullptr;
145}
146
153{
154 if (!exists()) {
155 g_error("Inkscape::Application does not yet exist.");
156 }
157 return *Application::_S_inst;
158}
159
160/* \brief Constructor for the application.
161 * Creates a new Inkscape::Application.
162 *
163 * \pre Application::_S_inst == NULL
164 */
165
167 _use_gui(use_gui)
168{
169 using namespace Inkscape::IO::Resource;
170 /* fixme: load application defaults */
171
172 // we need a app runing to know shared path
173 auto extensiondir_shared = get_path_string(SHARED, EXTENSIONS);
174 if (!extensiondir_shared.empty()) {
175 std::string pythonpath = extensiondir_shared;
176 auto pythonpath_old = Glib::getenv("PYTHONPATH");
177 if (!pythonpath_old.empty()) {
178 pythonpath += G_SEARCHPATH_SEPARATOR + pythonpath_old;
179 }
180 Glib::setenv("PYTHONPATH", pythonpath);
181 }
182 segv_handler = signal (SIGSEGV, Application::crash_handler);
183 abrt_handler = signal (SIGABRT, Application::crash_handler);
184 fpe_handler = signal (SIGFPE, Application::crash_handler);
185 ill_handler = signal (SIGILL, Application::crash_handler);
186#ifndef _WIN32
187 bus_handler = signal (SIGBUS, Application::crash_handler);
188#endif
189
190 // \TODO: this belongs to Application::init but if it isn't here
191 // then the Filters and Extensions menus don't work.
192 _S_inst = this;
193
195 ErrorReporter* handler = new ErrorReporter(use_gui);
196 prefs->setErrorHandler(handler);
197 {
198 Glib::ustring msg;
199 Glib::ustring secondary;
200 if (prefs->getLastError( msg, secondary )) {
201 handler->handleError(msg, secondary);
202 }
203 }
204
205 if (use_gui) {
206 using namespace Inkscape::IO::Resource;
207
208 auto display = Gdk::Display::get_default();
209 auto icon_theme = Gtk::IconTheme::get_for_display(display);
210 auto search_paths = icon_theme->get_search_path();
211 // prepend search paths or else hicolor icons fallback will fail
212 for (auto type : {USER, SHARED, SYSTEM}) {
213 auto path = get_path_string(type, ICONS);
214 if (!path.empty()) {
215 search_paths.insert(search_paths.begin(), path);
216 }
217 }
218 icon_theme->set_search_path(search_paths);
219
225 // register custom widget types
227 }
228
229 /* set language for user interface according setting in preferences */
230 Glib::ustring ui_language = prefs->getString("/ui/language");
231 if(!ui_language.empty())
232 {
233 Glib::setenv("LANGUAGE", ui_language.raw(), true);
234#ifdef _WIN32
235 // locale may be set to C with some Windows Region Formats (like English(Europe)).
236 // forcing the LANGUAGE variable to be ignored
237 // see :guess_category_value:gettext-runtime/intl/dcigettext.c,
238 // and :gl_locale_name_from_win32_LANGID:gettext-runtime/gnulib-lib/localename.c
239 Glib::setenv("LANG", ui_language.raw(), true);
240#endif
241 }
242
243 if (use_gui)
244 {
246 /* Check for global remapping of Alt key */
247 mapalt(guint(prefs->getInt("/options/mapalt/value", 0)));
248 trackalt(guint(prefs->getInt("/options/trackalt/value", 0)));
249
250 /* update highlight colors when theme changes */
251 themecontext->getChangeThemeSignal().connect([this](){
253 });
254 }
255
256 /* Initialize font factory */
257 auto &factory = FontFactory::get();
258 if (prefs->getBool("/options/font/use_fontsdir_system", true)) {
259 char const *fontsdir = get_path(SYSTEM, FONTS);
260 factory.AddFontsDir(fontsdir);
261 }
262 // we keep user font dir for simplicity
263 if (prefs->getBool("/options/font/use_fontsdir_user", true)) {
264 char const *fontsdirshared = get_path(SHARED, FONTS);
265 if (fontsdirshared) {
266 factory.AddFontsDir(fontsdirshared);
267 }
268 char const *fontsdir = get_path(USER, FONTS);
269 factory.AddFontsDir(fontsdir);
270 }
271 Glib::ustring fontdirs_pref = prefs->getString("/options/font/custom_fontdirs");
272 std::vector<Glib::ustring> fontdirs = Glib::Regex::split_simple("\\|", fontdirs_pref);
273 for (auto &fontdir : fontdirs) {
274 factory.AddFontsDir(fontdir.c_str());
275 }
276}
277
279{
280 if (_desktops) {
281 g_error("FATAL: desktops still in list on application destruction!");
282 }
283
285
286 _S_inst = nullptr; // this will probably break things
287
288 refCount = 0;
289}
290
295void Application::mapalt(guint maskvalue)
296{
297 if ( maskvalue < 2 || maskvalue > 5 ) { // MOD5 is the highest defined in gdktypes.h
298 _mapalt = 0;
299 } else {
300 _mapalt = (GDK_ALT_MASK << (maskvalue-1));
301 }
302}
303
304void
306{
310
311 static bool recursion = false;
312
313 /*
314 * reset all signal handlers: any further crashes should just be allowed
315 * to crash normally.
316 * */
317 signal (SIGSEGV, segv_handler );
318 signal (SIGABRT, abrt_handler );
319 signal (SIGFPE, fpe_handler );
320 signal (SIGILL, ill_handler );
321#ifndef _WIN32
322 signal (SIGBUS, bus_handler );
323#endif
324
325 /* Stop bizarre loops */
326 if (recursion) {
327 abort ();
328 }
329 recursion = true;
330
331 _crashIsHappening = true;
332
333 EventTracker<SimpleEvent<Inkscape::Debug::Event::CORE> > tracker("crash");
334 tracker.set<SimpleEvent<> >("emergency-save");
335
336 fprintf(stderr, "\nEmergency save activated!\n");
337
338 time_t sptime = time (nullptr);
339 struct tm *sptm = localtime (&sptime);
340 gchar sptstr[256];
341 strftime(sptstr, 256, "%Y_%m_%d_%H_%M_%S", sptm);
342
343 gint count = 0;
344 gchar *curdir = g_get_current_dir(); // This one needs to be freed explicitly
345 std::vector<gchar *> savednames;
346 std::vector<gchar *> failednames;
347 for (auto doc : INKSCAPE._document_set) {
349 repr = doc->getReprRoot();
350 if (doc->isModifiedSinceSave()) {
351 const gchar *docname;
352 char n[64];
353
354 /* originally, the document name was retrieved from
355 * the sodipod:docname attribute */
356 docname = doc->getDocumentName();
357 if (docname) {
358 /* Removes an emergency save suffix if present: /(.*)\.[0-9_]*\.[0-9_]*\.[~\.]*$/\1/ */
359 const char* d0 = strrchr ((char*)docname, '.');
360 if (d0 && (d0 > docname)) {
361 const char* d = d0;
362 unsigned int dots = 0;
363 while ((isdigit (*d) || *d=='_' || *d=='.') && d>docname && dots<2) {
364 d -= 1;
365 if (*d=='.') dots++;
366 }
367 if (*d=='.' && d>docname && dots==2) {
368 size_t len = MIN (d - docname, 63);
369 memcpy (n, docname, len);
370 n[len] = '\0';
371 docname = n;
372 }
373 }
374 }
375 if (!docname || !*docname) docname = "emergency";
376
377 // Emergency filename
378 char c[1024];
379 g_snprintf (c, 1024, "%.256s.%s.%d.svg", docname, sptstr, count);
380
381 const char* document_filename = doc->getDocumentFilename();
382 char* document_base = nullptr;
383 if (document_filename) {
384 document_base = g_path_get_dirname(document_filename);
385 }
386
387 // Find a location
388 const char* locations[] = {
389 // Don't use getDocumentBase as that also can be unsaved template locations.
390 document_base,
391 g_get_home_dir(),
392 g_get_tmp_dir(),
393 curdir,
394 };
395 FILE *file = nullptr;
396 for(auto & location : locations) {
397 if (!location) continue; // It seems to be okay, but just in case
398 gchar * filename = g_build_filename(location, c, nullptr);
399 Inkscape::IO::dump_fopen_call(filename, "E");
400 file = Inkscape::IO::fopen_utf8name(filename, "w");
401 if (file) {
402 g_snprintf (c, 1024, "%s", filename); // we want the complete path to be stored in c (for reporting purposes)
403 break;
404 }
405 }
406 if (document_base) {
407 g_free(document_base);
408 }
409
410 // Save
411 if (file) {
412 sp_repr_save_stream (repr->document(), file, SP_SVG_NS_URI);
413 savednames.push_back(g_strdup (c));
414 fclose (file);
415
416 // Attempt to add the emergency save to the recent files, so users can find it on restart
417 auto recentmanager = Gtk::RecentManager::get_default();
418 if (recentmanager && Glib::path_is_absolute(c)) {
419 Glib::ustring uri = Glib::filename_to_uri(c);
420 recentmanager->add_item(uri, {
421 docname, // Name
422 "Emergency Saved Image", // Description
423 "image/svg+xml", // Mime type
424 "org.inkscape.Inkscape", // App name
425 "", // Execute
426 {"Crash"}, // Groups
427 true, // Private
428 });
429 }
430 } else {
431 failednames.push_back((doc->getDocumentName()) ? g_strdup(doc->getDocumentName()) : g_strdup (_("Untitled document")));
432 }
433 count++;
434 }
435 }
436 g_free(curdir);
437
438 if (!savednames.empty()) {
439 fprintf (stderr, "\nEmergency save document locations:\n");
440 for (auto i:savednames) {
441 fprintf (stderr, " %s\n", i);
442 }
443 }
444 if (!failednames.empty()) {
445 fprintf (stderr, "\nFailed to do emergency save for documents:\n");
446 for (auto i:failednames) {
447 fprintf (stderr, " %s\n", i);
448 }
449 }
450
451 // do not save the preferences since they can be in a corrupted state
453
454 fprintf (stderr, "Emergency save completed. Inkscape will close now.\n");
455 fprintf (stderr, "If you can reproduce this crash, please file a bug at https://inkscape.org/report\n");
456 fprintf (stderr, "with a detailed description of the steps leading to the crash, so we can fix it.\n");
457
458 /* Show nice dialog box */
459
460 char const *istr = "";
461 char const *sstr = _("Automatic backups of unsaved documents were done to the following locations:\n");
462 char const *fstr = _("Automatic backup of the following documents failed:\n");
463 gint nllen = strlen ("\n");
464 gint len = strlen (istr) + strlen (sstr) + strlen (fstr);
465 for (auto i:savednames) {
466 len = len + SP_INDENT + strlen (i) + nllen;
467 }
468 for (auto i:failednames) {
469 len = len + SP_INDENT + strlen (i) + nllen;
470 }
471 len += 1;
472 gchar *b = g_new (gchar, len);
473 gint pos = 0;
474 len = strlen (istr);
475 memcpy (b + pos, istr, len);
476 pos += len;
477 if (!savednames.empty()) {
478 len = strlen (sstr);
479 memcpy (b + pos, sstr, len);
480 pos += len;
481 for (auto i:savednames) {
482 memset (b + pos, ' ', SP_INDENT);
483 pos += SP_INDENT;
484 len = strlen(i);
485 memcpy (b + pos, i, len);
486 pos += len;
487 memcpy (b + pos, "\n", nllen);
488 pos += nllen;
489 }
490 }
491 if (!failednames.empty()) {
492 len = strlen (fstr);
493 memcpy (b + pos, fstr, len);
494 pos += len;
495 for (auto i:failednames) {
496 memset (b + pos, ' ', SP_INDENT);
497 pos += SP_INDENT;
498 len = strlen(i);
499 memcpy (b + pos, i, len);
500 pos += len;
501 memcpy (b + pos, "\n", nllen);
502 pos += nllen;
503 }
504 }
505 *(b + pos) = '\0';
506
507 if ( exists() && instance().use_gui() ) {
508 try {
509 auto mainloop = Glib::MainLoop::create();
510 auto builder = UI::create_builder("dialog-crash.glade");
511 auto &autosaves = UI::get_widget<Gtk::Label>(builder, "autosaves");
512 if (std::strlen(b) == 0) {
513 autosaves.set_visible(false);
514 } else {
515 autosaves.set_label(b);
516 }
517 UI::get_object<Gtk::TextBuffer>(builder, "stacktrace")->set_text("<pre>\n" + boost::stacktrace::to_string(boost::stacktrace::stacktrace()) + "</pre>\n<details><summary>System info</summary>\n" + debug_info() + "\n</details>");
518 auto &window = UI::get_widget<Gtk::Window>(builder, "crash_dialog");
519 auto &button_ok = UI::get_widget<Gtk::Button>(builder, "button_ok");
520 button_ok.signal_clicked().connect([&] { window.close(); });
521 button_ok.grab_focus();
522 window.signal_close_request().connect([&] { mainloop->quit(); return false; }, true);
523 sp_transientize(window);
524 window.present();
525 mainloop->run();
526 } catch (const Glib::Error &ex) {
527 g_message("Glade file loading failed for crash handler... Anyway, error was: %s", b);
528 std::cerr << boost::stacktrace::stacktrace();
529 }
530 } else {
531 g_message( "Error: %s", b );
532 std::cerr << boost::stacktrace::stacktrace();
533 }
534 g_free (b);
535
536 tracker.clear();
537 Logger::shutdown();
538
539 fflush(stderr); // make sure buffers are empty before crashing (otherwise output might be suppressed)
540
541 /* on exit, allow restored signal handler to take over and crash us */
542}
543
544
545void
547{
548 g_return_if_fail (desktop != nullptr);
549 if (_desktops == nullptr) {
550 _desktops = new std::vector<SPDesktop*>;
551 }
552
553 if (std::find(_desktops->begin(), _desktops->end(), desktop) != _desktops->end()) {
554 g_error("Attempted to add desktop already in list.");
555 }
556
557 _desktops->insert(_desktops->begin(), desktop);
558
562}
563
564
565
566void
568{
569 g_return_if_fail (desktop != nullptr);
570
571 if (std::find (_desktops->begin(), _desktops->end(), desktop) == _desktops->end() ) {
572 g_error("Attempted to remove desktop not in list.");
573 }
574
575
576 if (DESKTOP_IS_ACTIVE (desktop)) {
578 if (_desktops->size() > 1) {
579 SPDesktop * new_desktop = *(++_desktops->begin());
580 _desktops->erase(std::find(_desktops->begin(), _desktops->end(), new_desktop));
581 _desktops->insert(_desktops->begin(), new_desktop);
582
583 signal_activate_desktop.emit(new_desktop);
584 signal_selection_set.emit(new_desktop->getSelection());
585 signal_selection_changed.emit(new_desktop->getSelection());
586 } else {
587 if (desktop->getSelection())
589 }
590 }
591
592 _desktops->erase(std::find(_desktops->begin(), _desktops->end(), desktop));
593
594 // if this was the last desktop, shut down the program
595 if (_desktops->empty()) {
596 this->exit();
597 delete _desktops;
598 _desktops = nullptr;
599 }
600}
601
602
603
604void
606{
607 g_return_if_fail (desktop != nullptr);
608
609 if (DESKTOP_IS_ACTIVE (desktop)) {
610 return;
611 }
612
613 std::vector<SPDesktop*>::iterator i;
614
615 if ((i = std::find (_desktops->begin(), _desktops->end(), desktop)) == _desktops->end()) {
616 g_error("Tried to activate desktop not added to list.");
617 }
618
619 SPDesktop *current = _desktops->front();
620
622
623 _desktops->erase (i);
624 _desktops->insert (_desktops->begin(), desktop);
625
629}
630
631
635void
637{
638 g_return_if_fail (desktop != nullptr);
639
640 if (DESKTOP_IS_ACTIVE (desktop)) {
642 }
643}
644
645
646
647SPDesktop *
649{
650 for (auto & _desktop : *_desktops) {
651 if (_desktop->dkey == dkey){
652 return _desktop;
653 }
654 }
655 return nullptr;
656}
657
658
659unsigned int
661{
662 unsigned int dkey = 0;
663
664 for (auto & _desktop : *_desktops) {
665 if (_desktop->dkey > dkey){
666 dkey = _desktop->dkey;
667 }
668 }
669 return dkey;
670}
671
672
673
674SPDesktop *
676{
677 SPDesktop *d = nullptr;
678 unsigned int dkey_current = (_desktops->front())->dkey;
679
680 if (dkey_current < maximum_dkey()) {
681 // find next existing
682 for (unsigned int i = dkey_current + 1; i <= maximum_dkey(); ++i) {
683 d = find_desktop_by_dkey (i);
684 if (d) {
685 break;
686 }
687 }
688 } else {
689 // find first existing
690 for (unsigned int i = 0; i <= maximum_dkey(); ++i) {
691 d = find_desktop_by_dkey (i);
692 if (d) {
693 break;
694 }
695 }
696 }
697
698 g_assert (d);
699 return d;
700}
701
702
703
704SPDesktop *
706{
707 SPDesktop *d = nullptr;
708 unsigned int dkey_current = (_desktops->front())->dkey;
709
710 if (dkey_current > 0) {
711 // find prev existing
712 for (signed int i = dkey_current - 1; i >= 0; --i) {
713 d = find_desktop_by_dkey (i);
714 if (d) {
715 break;
716 }
717 }
718 }
719 if (!d) {
720 // find last existing
722 }
723
724 g_assert (d);
725 return d;
726}
727
728
729
730void
735
736void
741
742void
747
749{
750 _document_set.emplace(document);
751}
752
754{
755 _document_set.erase(document);
756}
757
758SPDesktop *
760{
761 if (!_desktops || _desktops->empty()) {
762 return nullptr;
763 }
764
765 return _desktops->front();
766}
767
770{
771 if (SP_ACTIVE_DESKTOP) {
772 return SP_ACTIVE_DESKTOP->getDocument();
773 } else if (!_document_set.empty()) {
774 // If called from the command line there will be no desktop
775 // So 'fall back' to take the first listed document in the Inkscape instance
776 return *_document_set.begin();
777 }
778
779 return nullptr;
780}
781
782/*#####################
783# HELPERS
784#####################*/
785
794
795void
796Application::get_all_desktops(std::list< SPDesktop* >& listbuf)
797{
798 listbuf.insert(listbuf.end(), _desktops->begin(), _desktops->end());
799}
800
801} // namespace Inkscape
802
803/*
804 Local Variables:
805 mode:c++
806 c-file-style:"stroustrup"
807 c-file-offsets:((innamespace . 0)(inline-open . 0))
808 indent-tabs-mode:nil
809 fill-column:99
810 End:
811*/
812// vim: expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :
double scale
Definition aa.cpp:228
Gtk builder utilities.
static Inkscape::Application * _S_inst
Definition inkscape.h:164
sigc::signal< void(SPDesktop *)> signal_deactivate_desktop
Definition inkscape.h:129
static bool exists()
Checks whether the current Inkscape::Application global object exists.
Definition inkscape.cpp:142
Inkscape::UI::ThemeContext * themecontext
Definition inkscape.h:84
SPDesktop * prev_desktop()
Definition inkscape.cpp:705
void activate_desktop(SPDesktop *desktop)
Definition inkscape.cpp:605
bool use_gui() const
Definition inkscape.h:75
std::set< SPDocument * > _document_set
Definition inkscape.h:172
void reactivate_desktop(SPDesktop *desktop)
Resends ACTIVATE_DESKTOP for current desktop; needed when a new desktop has got its window that dialo...
Definition inkscape.cpp:636
guint mapalt() const
Definition inkscape.h:67
Application(bool use_gui)
Definition inkscape.cpp:166
SPDesktop * next_desktop()
Definition inkscape.cpp:675
SPDocument * active_document()
Definition inkscape.cpp:769
void add_document(SPDocument *document)
Definition inkscape.cpp:748
static void create(bool use_gui)
Creates a new Inkscape::Application global object.
Definition inkscape.cpp:128
void add_desktop(SPDesktop *desktop)
Definition inkscape.cpp:546
SPDesktop * find_desktop_by_dkey(unsigned int dkey)
Definition inkscape.cpp:648
std::vector< SPDesktop * > * _desktops
Definition inkscape.h:173
sigc::signal< void(SPDesktop *)> signal_activate_desktop
Definition inkscape.h:127
sigc::signal< void(Inkscape::Selection *)> signal_selection_set
Definition inkscape.h:125
Application * operator&() const
Defined only for debugging purposes.
Definition inkscape.cpp:120
sigc::signal< void()> signal_external_change
Definition inkscape.h:136
sigc::signal< void(Inkscape::Selection *)> signal_selection_changed
Definition inkscape.h:119
static Application & instance()
Returns the current Inkscape::Application global object.
Definition inkscape.cpp:152
void get_all_desktops(std::list< SPDesktop * > &listbuf)
Definition inkscape.cpp:796
guint trackalt() const
Definition inkscape.h:72
unsigned int maximum_dkey()
Definition inkscape.cpp:660
static bool _crashIsHappening
Definition inkscape.h:179
void exit()
Handler for Inkscape's Exit verb.
Definition inkscape.cpp:790
static void crash_handler(int signum)
Definition inkscape.cpp:305
SPDesktop * active_desktop()
Definition inkscape.cpp:759
void remove_desktop(SPDesktop *desktop)
Definition inkscape.cpp:567
void remove_document(SPDocument *document)
Definition inkscape.cpp:753
void handleError(Glib::ustring const &primary, Glib::ustring const &secondary) const
void clear()
Unselects all selected objects.
Preference storage class.
Definition preferences.h:61
bool getBool(Glib::ustring const &pref_path, bool def=false)
Retrieve a Boolean value.
Glib::ustring getString(Glib::ustring const &pref_path, Glib::ustring const &def="")
Retrieve an UTF-8 string.
static Preferences * get()
Access the singleton Preferences object.
bool getLastError(Glib::ustring &primary, Glib::ustring &secondary)
Return details of the last encountered error, if any.
int getInt(Glib::ustring const &pref_path, int def=0)
Retrieve an integer.
void setErrorHandler(ErrorReporter *handler)
static void unload(bool save=true)
Unload all preferences.
double getDoubleLimited(Glib::ustring const &pref_path, double def=0.0, double min=DBL_MIN, double max=DBL_MAX, Glib::ustring const &unit="")
Retrieve a limited floating point value.
void add_gtk_css(bool only_providers, bool cached=false)
Add our CSS style sheets.
Definition themes.cpp:264
void adjustGlobalFontScale(double factor)
Set application-wide font size adjustment by a factor, where 1 is 100% (no change)
Definition themes.cpp:608
static void initialize_source_syntax_styles()
Definition themes.cpp:643
sigc::signal< void()> getChangeThemeSignal()
Definition themes.h:56
static Glib::ustring get_font_scale_pref_path()
Definition themes.h:68
static FontFactory & get(Args &&... args)
Definition statics.h:153
Interface for refcounted XML nodes.
Definition node.h:80
virtual Document * document()=0
Get the node's associated document.
To do: update description of desktop.
Definition desktop.h:149
unsigned dkey
Definition desktop.h:229
Inkscape::Selection * getSelection() const
Definition desktop.h:188
void presentWindow()
Definition desktop.cpp:986
Typed SVG document implementation.
Definition document.h:101
Glib::ustring msg
Glib::RefPtr< Gtk::IconTheme > icon_theme
double c[8][4]
Editable view implementation.
void sp_transientize(Gtk::Window &window)
Make the argument dialog transient to the currently active document window.
Event handler for dialog windows.
A window for floating docks.
static char const *const current
Definition dir-util.cpp:71
static char const dots[]
Definition dir-util.cpp:69
TODO: insert short description here.
Consolidates version info for Inkscape, its various dependencies and the OS we're running on.
Inkscape - An SVG editor.
static void(* fpe_handler)(int)
Definition inkscape.cpp:75
static void(* abrt_handler)(int)
Definition inkscape.cpp:74
static constexpr int SP_INDENT
Definition inkscape.cpp:81
void inkscape_unref(Inkscape::Application &in)
Definition inkscape.cpp:99
static void(* bus_handler)(int)
Definition inkscape.cpp:78
static void(* ill_handler)(int)
Definition inkscape.cpp:76
void inkscape_ref(Inkscape::Application &in)
C++ification TODO list.
Definition inkscape.cpp:94
static void(* segv_handler)(int)
Definition inkscape.cpp:73
Raw stack of active status messages.
void dump_fopen_call(char const *utf8name, char const *id)
Definition sys.cpp:37
FILE * fopen_utf8name(char const *utf8name, char const *mode)
Open a file with g_fopen().
Definition sys.cpp:72
void init_latin_keys_group()
Initialize Latin keys group handling.
Glib::RefPtr< Gtk::Builder > create_builder(const char *filename)
Helper class to stream background task notifications as a series of messages.
std::string debug_info()
Return full debug info.
TODO: insert short description here.
void sp_repr_save_stream(Document *doc, FILE *fp, gchar const *default_ns, bool compress, gchar const *const old_href_abs_base, gchar const *const new_href_abs_base)
Definition repr-io.cpp:645
Inkscape::IO::Resource - simple resource API.
auto len
Definition safe-printf.h:21
SPRoot: SVG <svg> implementation.
SPDesktop * desktop
Gtk <themes> helper code.
Glib::RefPtr< Gtk::Builder > builder