56984dcbb99095d85b1c65e4ecf0221bffe198ba
1 /** \file
2 * \brief Editor Implementation class declaration for Inkscape. This
3 * singleton class implements much of the functionality of the former
4 * 'inkscape' object and its services and signals.
5 *
6 * Authors:
7 * Bryce W. Harrington <bryce@bryceharrington.org>
8 * Derek P. Moore <derekm@hackunix.org>
9 * Ralf Stephan <ralf@ark.in-berlin.de>
10 *
11 * Copyright (C) 2004-2005 Authors
12 *
13 * Released under GNU GPL. Read the file 'COPYING' for more information.
14 */
16 #ifdef HAVE_CONFIG_H
17 # include <config.h>
18 #endif
20 /*
21 TODO: Replace SPDocument with the new Inkscape::Document
22 TODO: Change 'desktop's to 'view*'s
23 TODO: Add derivation from Inkscape::Application::RunMode
24 */
27 #include "path-prefix.h"
28 #include "io/sys.h"
29 #include "sp-object-repr.h"
30 #include <desktop-handles.h>
31 #include "document.h"
32 #include "sp-namedview.h"
33 #include "event-context.h"
34 #include "sp-guide.h"
35 #include "selection.h"
36 #include "editor.h"
37 #include "application/application.h"
38 #include "preferences.h"
39 #include "ui/view/edit-widget.h"
41 namespace Inkscape {
42 namespace NSApplication {
44 static Editor *_instance = 0;
45 static void *_window;
47 Editor*
48 Editor::create (gint argc, char **argv)
49 {
50 if (_instance == 0)
51 {
52 _instance = new Editor (argc, argv);
53 _instance->init();
54 }
55 return _instance;
56 }
58 Editor::Editor (gint argc, char **argv)
59 : _documents (0),
60 _desktops (0),
61 _argv0 (argv[0]),
62 _dialogs_toggle (true)
64 {
65 sp_object_type_register ("sodipodi:namedview", SP_TYPE_NAMEDVIEW);
66 sp_object_type_register ("sodipodi:guide", SP_TYPE_GUIDE);
68 Inkscape::Preferences::load();
69 }
71 bool
72 Editor::init()
73 {
74 // Load non-local template until we have everything right
75 // This code formerly lived in file.cpp
76 //
77 gchar const *tmpl = g_build_filename ((INKSCAPE_TEMPLATESDIR), "default.svg", NULL);
78 bool have_default = Inkscape::IO::file_test (tmpl, G_FILE_TEST_IS_REGULAR);
79 SPDocument *doc = sp_document_new (have_default? tmpl:0, true, true);
80 g_return_val_if_fail (doc != 0, false);
81 Inkscape::UI::View::EditWidget *ew = new Inkscape::UI::View::EditWidget (doc);
82 sp_document_unref (doc);
83 _window = ew->getWindow();
84 return ew != 0;
85 }
87 Editor::~Editor()
88 {
89 }
91 /// Returns the Window representation of this application object
92 void*
93 Editor::getWindow()
94 {
95 return _window;
96 }
98 /// Returns the active document
99 SPDocument*
100 Editor::getActiveDocument()
101 {
102 if (getActiveDesktop()) {
103 return sp_desktop_document (getActiveDesktop());
104 }
106 return NULL;
107 }
109 void
110 Editor::addDocument (SPDocument *doc)
111 {
112 if ( _instance->_document_set.find(doc) == _instance->_document_set.end() ) {
113 _instance->_documents = g_slist_append (_instance->_documents, doc);
114 }
115 _instance->_document_set.insert(doc);
116 }
118 void
119 Editor::removeDocument (SPDocument *doc)
120 {
121 _instance->_document_set.erase(doc);
122 if ( _instance->_document_set.find(doc) == _instance->_document_set.end() ) {
123 _instance->_documents = g_slist_remove (_instance->_documents, doc);
124 }
125 }
127 SPDesktop*
128 Editor::createDesktop (SPDocument* doc)
129 {
130 g_assert (doc != 0);
131 (new Inkscape::UI::View::EditWidget (doc))->present();
132 sp_document_unref (doc);
133 SPDesktop *dt = getActiveDesktop();
134 reactivateDesktop (dt);
135 return dt;
136 }
138 /// Returns the currently active desktop
139 SPDesktop*
140 Editor::getActiveDesktop()
141 {
142 if (_instance->_desktops == NULL) {
143 return NULL;
144 }
146 return (SPDesktop *) _instance->_desktops->data;
147 }
149 /// Add desktop to list of desktops
150 void
151 Editor::addDesktop (SPDesktop *dt)
152 {
153 g_return_if_fail (dt != 0);
154 g_assert (!g_slist_find (_instance->_desktops, dt));
156 _instance->_desktops = g_slist_append (_instance->_desktops, dt);
158 if (isDesktopActive (dt)) {
159 _instance->_desktop_activated_signal.emit (dt);
160 _instance->_event_context_set_signal.emit (sp_desktop_event_context (dt));
161 _instance->_selection_set_signal.emit (sp_desktop_selection (dt));
162 _instance->_selection_changed_signal.emit (sp_desktop_selection (dt));
163 }
164 }
166 /// Remove desktop from list of desktops
167 void
168 Editor::removeDesktop (SPDesktop *dt)
169 {
170 g_return_if_fail (dt != 0);
171 g_assert (g_slist_find (_instance->_desktops, dt));
173 if (dt == _instance->_desktops->data) { // is it the active desktop?
174 _instance->_desktop_deactivated_signal.emit (dt);
175 if (_instance->_desktops->next != 0) {
176 SPDesktop * new_desktop = (SPDesktop *) _instance->_desktops->next->data;
177 _instance->_desktops = g_slist_remove (_instance->_desktops, new_desktop);
178 _instance->_desktops = g_slist_prepend (_instance->_desktops, new_desktop);
179 _instance->_desktop_activated_signal.emit (new_desktop);
180 _instance->_event_context_set_signal.emit (sp_desktop_event_context (new_desktop));
181 _instance->_selection_set_signal.emit (sp_desktop_selection (new_desktop));
182 _instance->_selection_changed_signal.emit (sp_desktop_selection (new_desktop));
183 } else {
184 _instance->_event_context_set_signal.emit (0);
185 if (sp_desktop_selection(dt))
186 sp_desktop_selection(dt)->clear();
187 }
188 }
190 _instance->_desktops = g_slist_remove (_instance->_desktops, dt);
192 // if this was the last desktop, shut down the program
193 if (_instance->_desktops == NULL) {
194 _instance->_shutdown_signal.emit();
195 Inkscape::NSApplication::Application::exit();
196 }
197 }
199 void
200 Editor::activateDesktop (SPDesktop* dt)
201 {
202 g_assert (dt != 0);
203 if (isDesktopActive (dt))
204 return;
206 g_assert (g_slist_find (_instance->_desktops, dt));
207 SPDesktop *curr = (SPDesktop*)_instance->_desktops->data;
208 _instance->_desktop_deactivated_signal.emit (curr);
210 _instance->_desktops = g_slist_remove (_instance->_desktops, dt);
211 _instance->_desktops = g_slist_prepend (_instance->_desktops, dt);
213 _instance->_desktop_activated_signal.emit (dt);
214 _instance->_event_context_set_signal.emit (sp_desktop_event_context(dt));
215 _instance->_selection_set_signal.emit (sp_desktop_selection(dt));
216 _instance->_selection_changed_signal.emit (sp_desktop_selection(dt));
217 }
219 void
220 Editor::reactivateDesktop (SPDesktop* dt)
221 {
222 g_assert (dt != 0);
223 if (isDesktopActive(dt))
224 _instance->_desktop_activated_signal.emit (dt);
225 }
227 bool
228 Editor::isDuplicatedView (SPDesktop* dt)
229 {
230 SPDocument const* document = dt->doc();
231 if (!document) {
232 return false;
233 }
234 for ( GSList *iter = _instance->_desktops ; iter ; iter = iter->next ) {
235 SPDesktop *other_desktop=(SPDesktop *)iter->data;
236 SPDocument *other_document=other_desktop->doc();
237 if ( other_document == document && other_desktop != dt ) {
238 return true;
239 }
240 }
241 return false;
242 }
244 /// Returns the event context
245 //SPEventContext*
246 //Editor::getEventContext()
247 //{
248 // if (getActiveDesktop()) {
249 // return sp_desktop_event_context (getActiveDesktop());
250 // }
251 //
252 // return NULL;
253 //}
256 void
257 Editor::selectionModified (Inkscape::Selection* sel, guint flags)
258 {
259 g_return_if_fail (sel != NULL);
260 if (isDesktopActive (sel->desktop()))
261 _instance->_selection_modified_signal.emit (sel, flags);
262 }
264 void
265 Editor::selectionChanged (Inkscape::Selection* sel)
266 {
267 g_return_if_fail (sel != NULL);
268 if (isDesktopActive (sel->desktop()))
269 _instance->_selection_changed_signal.emit (sel);
270 }
272 void
273 Editor::subSelectionChanged (SPDesktop* dt)
274 {
275 g_return_if_fail (dt != NULL);
276 if (isDesktopActive (dt))
277 _instance->_subselection_changed_signal.emit (dt);
278 }
280 void
281 Editor::selectionSet (Inkscape::Selection* sel)
282 {
283 g_return_if_fail (sel != NULL);
284 if (isDesktopActive (sel->desktop())) {
285 _instance->_selection_set_signal.emit (sel);
286 _instance->_selection_changed_signal.emit (sel);
287 }
288 }
290 void
291 Editor::eventContextSet (SPEventContext* ec)
292 {
293 g_return_if_fail (ec != NULL);
294 g_return_if_fail (SP_IS_EVENT_CONTEXT (ec));
295 if (isDesktopActive (ec->desktop))
296 _instance->_event_context_set_signal.emit (ec);
297 }
299 void
300 Editor::hideDialogs()
301 {
302 _instance->_dialogs_hidden_signal.emit();
303 _instance->_dialogs_toggle = false;
304 }
306 void
307 Editor::unhideDialogs()
308 {
309 _instance->_dialogs_unhidden_signal.emit();
310 _instance->_dialogs_toggle = true;
311 }
313 void
314 Editor::toggleDialogs()
315 {
316 if (_dialogs_toggle) {
317 hideDialogs();
318 } else {
319 unhideDialogs();
320 }
321 }
323 void
324 Editor::refreshDisplay()
325 {
326 // TODO
327 }
329 void
330 Editor::exit()
331 {
332 //emit shutdown signal so that dialogs could remember layout
333 _shutdown_signal.emit();
334 Inkscape::Preferences::save();
335 }
337 //==================================================================
339 sigc::connection
340 Editor::connectSelectionModified
341 (const sigc::slot<void, Inkscape::Selection*, guint> &slot)
342 {
343 return _instance->_selection_modified_signal.connect (slot);
344 }
346 sigc::connection
347 Editor::connectSelectionChanged
348 (const sigc::slot<void, Inkscape::Selection*> &slot)
349 {
350 return _instance->_selection_changed_signal.connect (slot);
351 }
353 sigc::connection
354 Editor::connectSubselectionChanged (const sigc::slot<void, SPDesktop*> &slot)
355 {
356 return _instance->_subselection_changed_signal.connect (slot);
357 }
359 sigc::connection
360 Editor::connectSelectionSet (const sigc::slot<void, Inkscape::Selection*> &slot)
361 {
362 return _instance->_selection_set_signal.connect (slot);
363 }
365 sigc::connection
366 Editor::connectEventContextSet (const sigc::slot<void, SPEventContext*> &slot)
367 {
368 return _instance->_event_context_set_signal.connect (slot);
369 }
371 sigc::connection
372 Editor::connectDesktopActivated (const sigc::slot<void, SPDesktop*> &slot)
373 {
374 return _instance->_desktop_activated_signal.connect (slot);
375 }
377 sigc::connection
378 Editor::connectDesktopDeactivated (const sigc::slot<void, SPDesktop*> &slot)
379 {
380 return _instance->_desktop_deactivated_signal.connect (slot);
381 }
383 sigc::connection
384 Editor::connectShutdown (const sigc::slot<void> &slot)
385 {
386 return _instance->_shutdown_signal.connect (slot);
387 }
389 sigc::connection
390 Editor::connectDialogsHidden (const sigc::slot<void> &slot)
391 {
392 return _instance->_dialogs_hidden_signal.connect (slot);
393 }
395 sigc::connection
396 Editor::connectDialogsUnhidden (const sigc::slot<void> &slot)
397 {
398 return _instance->_dialogs_unhidden_signal.connect (slot);
399 }
401 sigc::connection
402 Editor::connectExternalChange (const sigc::slot<void> &slot)
403 {
404 return _instance->_external_change_signal.connect (slot);
405 }
408 } // namespace NSApplication
409 } // namespace Inkscape
411 /*
412 Local Variables:
413 mode:c++
414 c-file-style:"stroustrup"
415 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
416 indent-tabs-mode:nil
417 fill-column:99
418 End:
419 */
420 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :