Code

Disabling transientize callback - it's currently causing some data loss
[inkscape.git] / src / application / editor.cpp
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()
102     if (getActiveDesktop()) {
103         return sp_desktop_document (getActiveDesktop());
104     }
106     return NULL;
109 void
110 Editor::addDocument (SPDocument *doc)
112     g_assert (!g_slist_find (_instance->_documents, doc));
113     _instance->_documents = g_slist_append (_instance->_documents, doc);
116 void
117 Editor::removeDocument (SPDocument *doc)
119     g_assert (g_slist_find (_instance->_documents, doc));
120     _instance->_documents = g_slist_remove (_instance->_documents, doc);
123 SPDesktop* 
124 Editor::createDesktop (SPDocument* doc)
126     g_assert (doc != 0);
127     (new Inkscape::UI::View::EditWidget (doc))->present();
128     sp_document_unref (doc);
129     SPDesktop *dt = getActiveDesktop();
130     reactivateDesktop (dt);
131     return dt;
134 /// Returns the currently active desktop
135 SPDesktop*
136 Editor::getActiveDesktop()
138     if (_instance->_desktops == NULL) {
139         return NULL;
140     }
142     return (SPDesktop *) _instance->_desktops->data;
145 /// Add desktop to list of desktops
146 void
147 Editor::addDesktop (SPDesktop *dt)
149     g_return_if_fail (dt != 0);
150     g_assert (!g_slist_find (_instance->_desktops, dt));
152     _instance->_desktops = g_slist_append (_instance->_desktops, dt);
154     if (isDesktopActive (dt)) {
155         _instance->_desktop_activated_signal.emit (dt);
156         _instance->_event_context_set_signal.emit (sp_desktop_event_context (dt));
157         _instance->_selection_set_signal.emit (sp_desktop_selection (dt));
158         _instance->_selection_changed_signal.emit (sp_desktop_selection (dt));
159     }
162 /// Remove desktop from list of desktops
163 void
164 Editor::removeDesktop (SPDesktop *dt)
166     g_return_if_fail (dt != 0);
167     g_assert (g_slist_find (_instance->_desktops, dt));
169     if (dt == _instance->_desktops->data) {  // is it the active desktop?
170         _instance->_desktop_deactivated_signal.emit (dt);
171         if (_instance->_desktops->next != 0) {
172             SPDesktop * new_desktop = (SPDesktop *) _instance->_desktops->next->data;
173             _instance->_desktops = g_slist_remove (_instance->_desktops, new_desktop);
174             _instance->_desktops = g_slist_prepend (_instance->_desktops, new_desktop);
175             _instance->_desktop_activated_signal.emit (new_desktop);
176             _instance->_event_context_set_signal.emit (sp_desktop_event_context (new_desktop));
177             _instance->_selection_set_signal.emit (sp_desktop_selection (new_desktop));
178             _instance->_selection_changed_signal.emit (sp_desktop_selection (new_desktop));
179         } else {
180             _instance->_event_context_set_signal.emit (0);
181             if (sp_desktop_selection(dt))
182                 sp_desktop_selection(dt)->clear();
183         }
184     }
186     _instance->_desktops = g_slist_remove (_instance->_desktops, dt);
188     // if this was the last desktop, shut down the program
189     if (_instance->_desktops == NULL) {
190         _instance->_shutdown_signal.emit();
191         Inkscape::NSApplication::Application::exit();
192     }
195 void 
196 Editor::activateDesktop (SPDesktop* dt)
198     g_assert (dt != 0);
199     if (isDesktopActive (dt))
200         return;
202     g_assert (g_slist_find (_instance->_desktops, dt));
203     SPDesktop *curr = (SPDesktop*)_instance->_desktops->data;
204     _instance->_desktop_deactivated_signal.emit (curr);
206     _instance->_desktops = g_slist_remove (_instance->_desktops, dt);
207     _instance->_desktops = g_slist_prepend (_instance->_desktops, dt);
209     _instance->_desktop_activated_signal.emit (dt);
210     _instance->_event_context_set_signal.emit (sp_desktop_event_context(dt));
211     _instance->_selection_set_signal.emit (sp_desktop_selection(dt));
212     _instance->_selection_changed_signal.emit (sp_desktop_selection(dt));
215 void 
216 Editor::reactivateDesktop (SPDesktop* dt)
218     g_assert (dt != 0);
219     if (isDesktopActive(dt))
220         _instance->_desktop_activated_signal.emit (dt);
223 bool
224 Editor::isDuplicatedView (SPDesktop* dt)
226     SPDocument const* document = dt->doc();
227     if (!document) {
228         return false;
229     }
230     for ( GSList *iter = _instance->_desktops ; iter ; iter = iter->next ) {
231         SPDesktop *other_desktop=(SPDesktop *)iter->data;
232         SPDocument *other_document=other_desktop->doc();
233         if ( other_document == document && other_desktop != dt ) {
234             return true;
235         }
236     }
237     return false;
240  /// Returns the event context
241 //SPEventContext*
242 //Editor::getEventContext()
243 //{
244 //    if (getActiveDesktop()) {
245 //        return sp_desktop_event_context (getActiveDesktop());
246 //    }
247 //
248 //    return NULL;
249 //}
252 void 
253 Editor::selectionModified (Inkscape::Selection* sel, guint flags)
255     g_return_if_fail (sel != NULL);
256     if (isDesktopActive (sel->desktop()))
257         _instance->_selection_modified_signal.emit (sel, flags);
260 void 
261 Editor::selectionChanged (Inkscape::Selection* sel)
263     g_return_if_fail (sel != NULL);
264     if (isDesktopActive (sel->desktop()))
265         _instance->_selection_changed_signal.emit (sel);
268 void 
269 Editor::subSelectionChanged (SPDesktop* dt)
271     g_return_if_fail (dt != NULL);
272     if (isDesktopActive (dt)) 
273         _instance->_subselection_changed_signal.emit (dt);
276 void 
277 Editor::selectionSet (Inkscape::Selection* sel)
279     g_return_if_fail (sel != NULL);
280     if (isDesktopActive (sel->desktop())) {
281         _instance->_selection_set_signal.emit (sel);
282         _instance->_selection_changed_signal.emit (sel);
283     }
286 void 
287 Editor::eventContextSet (SPEventContext* ec)
289     g_return_if_fail (ec != NULL);
290     g_return_if_fail (SP_IS_EVENT_CONTEXT (ec));
291     if (isDesktopActive (ec->desktop))
292         _instance->_event_context_set_signal.emit (ec);
295 void
296 Editor::hideDialogs()
298     _instance->_dialogs_hidden_signal.emit();
299     _instance->_dialogs_toggle = false;
302 void
303 Editor::unhideDialogs()
305     _instance->_dialogs_unhidden_signal.emit();
306     _instance->_dialogs_toggle = true;
309 void
310 Editor::toggleDialogs()
312     if (_dialogs_toggle) {
313         hideDialogs();
314     } else {
315         unhideDialogs();
316     }
319 void
320 Editor::refreshDisplay()
322     // TODO
325 void
326 Editor::exit()
328     //emit shutdown signal so that dialogs could remember layout
329     _shutdown_signal.emit();
330     Inkscape::Preferences::save();
333 //==================================================================
335 sigc::connection 
336 Editor::connectSelectionModified 
337 (const sigc::slot<void, Inkscape::Selection*, guint> &slot)
339     return _instance->_selection_modified_signal.connect (slot);
342 sigc::connection 
343 Editor::connectSelectionChanged 
344 (const sigc::slot<void, Inkscape::Selection*> &slot)
346     return _instance->_selection_changed_signal.connect (slot);
349 sigc::connection 
350 Editor::connectSubselectionChanged (const sigc::slot<void, SPDesktop*> &slot)
352     return _instance->_subselection_changed_signal.connect (slot);
355 sigc::connection 
356 Editor::connectSelectionSet (const sigc::slot<void, Inkscape::Selection*> &slot)
358     return _instance->_selection_set_signal.connect (slot);
361 sigc::connection 
362 Editor::connectEventContextSet (const sigc::slot<void, SPEventContext*> &slot)
364     return _instance->_event_context_set_signal.connect (slot);
367 sigc::connection 
368 Editor::connectDesktopActivated (const sigc::slot<void, SPDesktop*> &slot)
370     return _instance->_desktop_activated_signal.connect (slot);
373 sigc::connection 
374 Editor::connectDesktopDeactivated (const sigc::slot<void, SPDesktop*> &slot)
376     return _instance->_desktop_deactivated_signal.connect (slot);
378     
379 sigc::connection 
380 Editor::connectShutdown (const sigc::slot<void> &slot)
382     return _instance->_shutdown_signal.connect (slot);
385 sigc::connection 
386 Editor::connectDialogsHidden (const sigc::slot<void> &slot)
388     return _instance->_dialogs_hidden_signal.connect (slot);
391 sigc::connection 
392 Editor::connectDialogsUnhidden (const sigc::slot<void> &slot)
394     return _instance->_dialogs_unhidden_signal.connect (slot);
397 sigc::connection 
398 Editor::connectExternalChange (const sigc::slot<void> &slot)
400     return _instance->_external_change_signal.connect (slot);
404 } // namespace NSApplication
405 } // namespace Inkscape
407 /*
408   Local Variables:
409   mode:c++
410   c-file-style:"stroustrup"
411   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
412   indent-tabs-mode:nil
413   fill-column:99
414   End:
415 */
416 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :