// SPDX-License-Identifier: GPL-2.0-or-later /** * @file * Object for managing a set of dialogs, including their signals and * construction/caching/destruction of them. */ /* Authors: * Bryce W. Harrington * Jon Phillips * Gustav Broberg * * Copyright (C) 2004-2007 Authors * * Released under GNU GPL v2+, read the file 'COPYING' for more information. */ #include "ui/dialog/dialog-manager.h" #include "style.h" #include "ui/dialog/align-and-distribute.h" #include "ui/dialog/document-metadata.h" #include "ui/dialog/document-properties.h" #include "ui/dialog/extension-editor.h" #include "ui/dialog/fill-and-stroke.h" #include "ui/dialog/filter-editor.h" #include "ui/dialog/filter-effects-dialog.h" #include "ui/dialog/find.h" #include "ui/dialog/glyphs.h" #include "ui/dialog/inkscape-preferences.h" #include "ui/dialog/input.h" #include "ui/dialog/livepatheffect-editor.h" #include "ui/dialog/memory.h" #include "ui/dialog/messages.h" #include "ui/dialog/paint-servers.h" #include "ui/dialog/symbols.h" #include "ui/dialog/tile.h" # include "ui/dialog/tracedialog.h" #include "ui/dialog/transformation.h" #include "ui/dialog/undo-history.h" #include "ui/dialog/panel-dialog.h" #include "ui/dialog/layers.h" #include "ui/dialog/icon-preview.h" //#include "ui/dialog/print-colors-preview-dialog.h" #include "ui/dialog/clonetiler.h" #include "ui/dialog/export.h" #include "ui/dialog/object-attributes.h" #include "ui/dialog/object-properties.h" #include "ui/dialog/objects.h" #include "ui/dialog/selectorsdialog.h" #if HAVE_ASPELL # include "ui/dialog/spellcheck.h" #endif #include "ui/dialog/tags.h" #include "ui/dialog/styledialog.h" #include "ui/dialog/svg-fonts-dialog.h" #include "ui/dialog/text-edit.h" #include "ui/dialog/xml-tree.h" #include "util/ege-appear-time-tracker.h" namespace Inkscape { namespace UI { namespace Dialog { namespace { using namespace Behavior; template inline Dialog *create() { return PanelDialog::template create(); } } /** * This class is provided as a container for Inkscape's various * dialogs. This allows InkscapeApplication to treat the various * dialogs it invokes, as abstractions. * * DialogManager is essentially a cache of dialogs. It lets us * initialize dialogs lazily - instead of constructing them during * application startup, they're constructed the first time they're * actually invoked by InkscapeApplication. The constructed * dialog is held here after that, so future invocations of the * dialog don't need to get re-constructed each time. The memory for * the dialogs are then reclaimed when the DialogManager is destroyed. * * In addition, DialogManager also serves as a signal manager for * dialogs. It provides a set of signals that can be sent to all * dialogs for doing things such as hiding/unhiding them, etc. * DialogManager ensures that every dialog it handles will listen * to these signals. * */ DialogManager::DialogManager() { using namespace Behavior; Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int dialogs_type = prefs->getIntLimited("/options/dialogtype/value", DOCK, 0, 1); // The preferences dialog is broken, the DockBehavior code resizes it's floating window to the smallest size registerFactory("InkscapePreferences", &create); if (dialogs_type == FLOATING) { registerFactory("AlignAndDistribute", &create); registerFactory("DocumentMetadata", &create); registerFactory("DocumentProperties", &create); registerFactory("ExtensionEditor", &create); registerFactory("FillAndStroke", &create); registerFactory("FilterEffectsDialog", &create); registerFactory("FilterEditorDialog", &create); registerFactory("Find", &create); registerFactory("Glyphs", &create); registerFactory("IconPreviewPanel", &create); registerFactory("LayersPanel", &create); registerFactory("ObjectsPanel", &create); registerFactory("TagsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); registerFactory("ObjectAttributes", &create); registerFactory("ObjectProperties", &create); // registerFactory("PrintColorsPreviewDialog", &create); registerFactory("SvgFontsDialog", &create); registerFactory("Swatches", &create); registerFactory("TileDialog", &create); registerFactory("Symbols", &create); registerFactory("PaintServers", &create); registerFactory("StyleDialog", &create); registerFactory("Trace", &create); registerFactory("Transformation", &create); registerFactory("UndoHistory", &create); registerFactory("InputDevices", &create); registerFactory("TextFont", &create); #if HAVE_ASPELL registerFactory("SpellCheck", &create); #endif registerFactory("Export", &create); registerFactory("CloneTiler", &create); registerFactory("XmlTree", &create); registerFactory("Selectors", &create); } else { registerFactory("AlignAndDistribute", &create); registerFactory("DocumentMetadata", &create); registerFactory("DocumentProperties", &create); registerFactory("ExtensionEditor", &create); registerFactory("FillAndStroke", &create); registerFactory("FilterEffectsDialog", &create); registerFactory("FilterEditorDialog", &create); registerFactory("Find", &create); registerFactory("Glyphs", &create); registerFactory("IconPreviewPanel", &create); registerFactory("LayersPanel", &create); registerFactory("ObjectsPanel", &create); registerFactory("TagsPanel", &create); registerFactory("LivePathEffect", &create); registerFactory("Memory", &create); registerFactory("Messages", &create); registerFactory("ObjectAttributes", &create); registerFactory("ObjectProperties", &create); // registerFactory("PrintColorsPreviewDialog", &create); registerFactory("SvgFontsDialog", &create); registerFactory("Swatches", &create); registerFactory("TileDialog", &create); registerFactory("Symbols", &create); registerFactory("PaintServers", &create); registerFactory("Trace", &create); registerFactory("Transformation", &create); registerFactory("UndoHistory", &create); registerFactory("InputDevices", &create); registerFactory("TextFont", &create); #if HAVE_ASPELL registerFactory("SpellCheck", &create); #endif registerFactory("Export", &create); registerFactory("CloneTiler", &create); registerFactory("XmlTree", &create); registerFactory("Selectors", &create); } } DialogManager::~DialogManager() { // TODO: Disconnect the signals // TODO: Do we need to explicitly delete the dialogs? // Appears to cause a segfault if we do } DialogManager &DialogManager::getInstance() { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int dialogs_type = prefs->getIntLimited("/options/dialogtype/value", DOCK, 0, 1); /* Use singleton behavior for floating dialogs */ if (dialogs_type == FLOATING) { static DialogManager *instance = nullptr; if (!instance) instance = new DialogManager(); return *instance; } return *new DialogManager(); } /** * Registers a dialog factory function used to create the named dialog. */ void DialogManager::registerFactory(gchar const *name, DialogManager::DialogFactory factory) { registerFactory(g_quark_from_string(name), factory); } /** * Registers a dialog factory function used to create the named dialog. */ void DialogManager::registerFactory(GQuark name, DialogManager::DialogFactory factory) { _factory_map[name] = factory; } /** * Fetches the named dialog, creating it if it has not already been * created (assuming a factory has been registered for it). */ Dialog *DialogManager::getDialog(gchar const *name) { return getDialog(g_quark_from_string(name)); } /** * Fetches the named dialog, creating it if it has not already been * created (assuming a factory has been registered for it). */ Dialog *DialogManager::getDialog(GQuark name) { DialogMap::iterator dialog_found; dialog_found = _dialog_map.find(name); Dialog *dialog=nullptr; if ( dialog_found != _dialog_map.end() ) { dialog = dialog_found->second; } else { FactoryMap::iterator factory_found; factory_found = _factory_map.find(name); if ( factory_found != _factory_map.end() ) { dialog = factory_found->second(); _dialog_map[name] = dialog; } } return dialog; } /** * Shows the named dialog, creating it if necessary. */ void DialogManager::showDialog(gchar const *name, bool grabfocus) { showDialog(g_quark_from_string(name), grabfocus); } /** * Shows the named dialog, creating it if necessary. */ void DialogManager::showDialog(GQuark name, bool /*grabfocus*/) { bool wantTiming = Inkscape::Preferences::get()->getBool("/dialogs/debug/trackAppear", false); GTimer *timer = (wantTiming) ? g_timer_new() : nullptr; // if needed, must be created/started before getDialog() Dialog *dialog = getDialog(name); if ( dialog ) { if ( wantTiming ) { gchar const * nameStr = g_quark_to_string(name); ege::AppearTimeTracker *tracker = new ege::AppearTimeTracker(timer, dialog->gobj(), nameStr); tracker->setAutodelete(true); timer = nullptr; } // should check for grabfocus, but lp:1348927 prevents it dialog->present(); } if ( timer ) { g_timer_destroy(timer); timer = nullptr; } } } // namespace Dialog } // namespace UI } // 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 :