1 /** @file
2 * @brief Object for managing a set of dialogs, including their signals and
3 * construction/caching/destruction of them.
4 */
5 /* Authors:
6 * Bryce W. Harrington <bryce@bryceharrington.org>
7 * Jon Phillips <jon@rejon.org>
8 * Gustav Broberg <broberg@kth.se>
9 *
10 * Copyright (C) 2004-2007 Authors
11 *
12 * Released under GNU GPL. Read the file 'COPYING' for more information.
13 */
15 #ifdef HAVE_CONFIG_H
16 # include <config.h>
17 #endif
19 #include "ui/dialog/dialog-manager.h"
21 #include "ui/dialog/align-and-distribute.h"
22 #include "ui/dialog/document-metadata.h"
23 #include "ui/dialog/document-properties.h"
24 #include "ui/dialog/extension-editor.h"
25 #include "ui/dialog/fill-and-stroke.h"
26 #include "ui/dialog/filter-effects-dialog.h"
27 #include "ui/dialog/find.h"
28 #include "ui/dialog/glyphs.h"
29 #include "ui/dialog/inkscape-preferences.h"
30 #include "ui/dialog/input.h"
31 #include "ui/dialog/livepatheffect-editor.h"
32 #include "ui/dialog/memory.h"
33 #include "ui/dialog/messages.h"
34 #include "ui/dialog/scriptdialog.h"
35 #include "ui/dialog/tile.h"
36 #include "ui/dialog/tracedialog.h"
37 #include "ui/dialog/transformation.h"
38 #include "ui/dialog/undo-history.h"
39 #include "ui/dialog/panel-dialog.h"
40 #include "ui/dialog/layers.h"
41 #include "ui/dialog/icon-preview.h"
42 #include "ui/dialog/floating-behavior.h"
43 #include "ui/dialog/dock-behavior.h"
44 //#include "ui/dialog/print-colors-preview-dialog.h"
45 #include "util/ege-appear-time-tracker.h"
46 #include "preferences.h"
48 #ifdef ENABLE_SVG_FONTS
49 #include "ui/dialog/svg-fonts-dialog.h"
50 #endif // ENABLE_SVG_FONTS
52 namespace Inkscape {
53 namespace UI {
54 namespace Dialog {
56 namespace {
58 using namespace Behavior;
60 template <typename T, typename B>
61 inline Dialog *create() { return PanelDialog<B>::template create<T>(); }
63 }
65 /**
66 * This class is provided as a container for Inkscape's various
67 * dialogs. This allows Inkscape::Application to treat the various
68 * dialogs it invokes, as abstractions.
69 *
70 * DialogManager is essentially a cache of dialogs. It lets us
71 * initialize dialogs lazily - instead of constructing them during
72 * application startup, they're constructed the first time they're
73 * actually invoked by Inkscape::Application. The constructed
74 * dialog is held here after that, so future invokations of the
75 * dialog don't need to get re-constructed each time. The memory for
76 * the dialogs are then reclaimed when the DialogManager is destroyed.
77 *
78 * In addition, DialogManager also serves as a signal manager for
79 * dialogs. It provides a set of signals that can be sent to all
80 * dialogs for doing things such as hiding/unhiding them, etc.
81 * DialogManager ensures that every dialog it handles will listen
82 * to these signals.
83 *
84 */
85 DialogManager::DialogManager() {
87 using namespace Behavior;
88 using namespace Inkscape::UI::Dialogs; // temporary
90 Inkscape::Preferences *prefs = Inkscape::Preferences::get();
91 int dialogs_type = prefs->getIntLimited("/options/dialogtype/value", DOCK, 0, 1);
93 if (dialogs_type == FLOATING) {
94 registerFactory("AlignAndDistribute", &create<AlignAndDistribute, FloatingBehavior>);
95 registerFactory("DocumentMetadata", &create<DocumentMetadata, FloatingBehavior>);
96 registerFactory("DocumentProperties", &create<DocumentProperties, FloatingBehavior>);
97 registerFactory("ExtensionEditor", &create<ExtensionEditor, FloatingBehavior>);
98 registerFactory("FillAndStroke", &create<FillAndStroke, FloatingBehavior>);
99 registerFactory("FilterEffectsDialog", &create<FilterEffectsDialog, FloatingBehavior>);
100 registerFactory("Find", &create<Find, FloatingBehavior>);
101 registerFactory("Glyphs", &create<GlyphsPanel, FloatingBehavior>);
102 registerFactory("IconPreviewPanel", &create<IconPreviewPanel, FloatingBehavior>);
103 registerFactory("InkscapePreferences", &create<InkscapePreferences, FloatingBehavior>);
104 registerFactory("LayersPanel", &create<LayersPanel, FloatingBehavior>);
105 registerFactory("LivePathEffect", &create<LivePathEffectEditor, FloatingBehavior>);
106 registerFactory("Memory", &create<Memory, FloatingBehavior>);
107 registerFactory("Messages", &create<Messages, FloatingBehavior>);
108 // registerFactory("PrintColorsPreviewDialog", &create<PrintColorsPreviewDialog, FloatingBehavior>);
109 registerFactory("Script", &create<ScriptDialog, FloatingBehavior>);
110 #ifdef ENABLE_SVG_FONTS
111 registerFactory("SvgFontsDialog", &create<SvgFontsDialog, FloatingBehavior>);
112 #endif
113 registerFactory("Swatches", &create<SwatchesPanel, FloatingBehavior>);
114 registerFactory("TileDialog", &create<TileDialog, FloatingBehavior>);
115 registerFactory("Trace", &create<TraceDialog, FloatingBehavior>);
116 registerFactory("Transformation", &create<Transformation, FloatingBehavior>);
117 registerFactory("UndoHistory", &create<UndoHistory, FloatingBehavior>);
118 registerFactory("InputDevices", &create<InputDialog, FloatingBehavior>);
120 } else {
122 registerFactory("AlignAndDistribute", &create<AlignAndDistribute, DockBehavior>);
123 registerFactory("DocumentMetadata", &create<DocumentMetadata, DockBehavior>);
124 registerFactory("DocumentProperties", &create<DocumentProperties, DockBehavior>);
125 registerFactory("ExtensionEditor", &create<ExtensionEditor, DockBehavior>);
126 registerFactory("FillAndStroke", &create<FillAndStroke, DockBehavior>);
127 registerFactory("FilterEffectsDialog", &create<FilterEffectsDialog, DockBehavior>);
128 registerFactory("Find", &create<Find, DockBehavior>);
129 registerFactory("Glyphs", &create<GlyphsPanel, DockBehavior>);
130 registerFactory("IconPreviewPanel", &create<IconPreviewPanel, DockBehavior>);
131 registerFactory("InkscapePreferences", &create<InkscapePreferences, DockBehavior>);
132 registerFactory("LayersPanel", &create<LayersPanel, DockBehavior>);
133 registerFactory("LivePathEffect", &create<LivePathEffectEditor, DockBehavior>);
134 registerFactory("Memory", &create<Memory, DockBehavior>);
135 registerFactory("Messages", &create<Messages, DockBehavior>);
136 // registerFactory("PrintColorsPreviewDialog", &create<PrintColorsPreviewDialog, DockBehavior>);
137 registerFactory("Script", &create<ScriptDialog, DockBehavior>);
138 #ifdef ENABLE_SVG_FONTS
139 registerFactory("SvgFontsDialog", &create<SvgFontsDialog, DockBehavior>);
140 #endif
141 registerFactory("Swatches", &create<SwatchesPanel, DockBehavior>);
142 registerFactory("TileDialog", &create<TileDialog, DockBehavior>);
143 registerFactory("Trace", &create<TraceDialog, DockBehavior>);
144 registerFactory("Transformation", &create<Transformation, DockBehavior>);
145 registerFactory("UndoHistory", &create<UndoHistory, DockBehavior>);
146 registerFactory("InputDevices", &create<InputDialog, DockBehavior>);
148 }
149 }
151 DialogManager::~DialogManager() {
152 // TODO: Disconnect the signals
153 // TODO: Do we need to explicitly delete the dialogs?
154 // Appears to cause a segfault if we do
155 }
158 DialogManager &DialogManager::getInstance()
159 {
160 Inkscape::Preferences *prefs = Inkscape::Preferences::get();
161 int dialogs_type = prefs->getIntLimited("/options/dialogtype/value", DOCK, 0, 1);
163 /* Use singleton behavior for floating dialogs */
164 if (dialogs_type == FLOATING) {
165 static DialogManager *instance = 0;
167 if (!instance)
168 instance = new DialogManager();
169 return *instance;
170 }
172 return *new DialogManager();
173 }
175 /**
176 * Registers a dialog factory function used to create the named dialog.
177 */
178 void DialogManager::registerFactory(gchar const *name,
179 DialogManager::DialogFactory factory)
180 {
181 registerFactory(g_quark_from_string(name), factory);
182 }
184 /**
185 * Registers a dialog factory function used to create the named dialog.
186 */
187 void DialogManager::registerFactory(GQuark name,
188 DialogManager::DialogFactory factory)
189 {
190 _factory_map[name] = factory;
191 }
193 /**
194 * Fetches the named dialog, creating it if it has not already been
195 * created (assuming a factory has been registered for it).
196 */
197 Dialog *DialogManager::getDialog(gchar const *name) {
198 return getDialog(g_quark_from_string(name));
199 }
201 /**
202 * Fetches the named dialog, creating it if it has not already been
203 * created (assuming a factory has been registered for it).
204 */
205 Dialog *DialogManager::getDialog(GQuark name) {
206 DialogMap::iterator dialog_found;
207 dialog_found = _dialog_map.find(name);
209 Dialog *dialog=NULL;
210 if ( dialog_found != _dialog_map.end() ) {
211 dialog = dialog_found->second;
212 } else {
213 FactoryMap::iterator factory_found;
214 factory_found = _factory_map.find(name);
216 if ( factory_found != _factory_map.end() ) {
217 dialog = factory_found->second();
218 _dialog_map[name] = dialog;
219 }
220 }
222 return dialog;
223 }
225 /**
226 * Shows the named dialog, creating it if necessary.
227 */
228 void DialogManager::showDialog(gchar const *name) {
229 showDialog(g_quark_from_string(name));
230 }
232 /**
233 * Shows the named dialog, creating it if necessary.
234 */
235 void DialogManager::showDialog(GQuark name) {
236 bool wantTiming = Inkscape::Preferences::get()->getBool("/dialogs/debug/trackAppear", false);
237 GTimer *timer = (wantTiming) ? g_timer_new() : 0; // if needed, must be created/started before getDialog()
238 Dialog *dialog = getDialog(name);
239 if ( dialog ) {
240 if ( wantTiming ) {
241 gchar const * nameStr = g_quark_to_string(name);
242 ege::AppearTimeTracker *tracker = new ege::AppearTimeTracker(timer, dialog->gobj(), nameStr);
243 tracker->setAutodelete(true);
244 timer = 0;
245 }
246 dialog->present();
247 }
249 if ( timer ) {
250 g_timer_destroy(timer);
251 timer = 0;
252 }
253 }
255 } // namespace Dialog
256 } // namespace UI
257 } // namespace Inkscape
259 /*
260 Local Variables:
261 mode:c++
262 c-file-style:"stroustrup"
263 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
264 indent-tabs-mode:nil
265 fill-column:99
266 End:
267 */
268 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :