Code

r17821@shi: ted | 2008-01-31 12:59:57 -0800
[inkscape.git] / src / extension / execution-env.cpp
1 /*
2  * Authors:
3  *   Ted Gould <ted@gould.cx>
4  *
5  * Copyright (C) 2007 Authors
6  *
7  * Released under GNU GPL, read the file 'COPYING' for more information
8  */
10 #include <config.h>
12 #include "gtkmm/messagedialog.h"
14 #include "execution-env.h"
15 #include "prefdialog.h"
16 #include "implementation/implementation.h"
18 #include "selection.h"
19 #include "effect.h"
20 #include "document.h"
21 #include "desktop.h"
22 #include "ui/view/view.h"
23 #include "sp-namedview.h"
24 #include "desktop-handles.h"
26 #include "util/glib-list-iterators.h"
28 namespace Inkscape {
29 namespace Extension {
32 ExecutionEnv::ExecutionEnv (Effect * effect, Inkscape::UI::View::View * doc, Gtk::Widget * controls, sigc::signal<void> * changeSignal, Gtk::Dialog * prefDialog, Implementation::ImplementationDocumentCache * docCache) :
33     _visibleDialog(NULL),
34     _prefsVisible(false),
35     _finished(false),
36     _humanWait(false),
37     _canceled(false),
38     _prefsChanged(false),
39     _livePreview(true),
40     _shutdown(false),
41     _selfdelete(false),
42     _changeSignal(changeSignal),
43     _doc(doc),
44     _docCache(docCache),
45     _effect(effect)
46 {
47     SPDesktop *desktop = (SPDesktop *)_doc;
48     sp_namedview_document_from_window(desktop);
50     if (desktop != NULL) {
51         Inkscape::Util::GSListConstIterator<SPItem *> selected =
52              sp_desktop_selection(desktop)->itemList();
53         while ( selected != NULL ) {
54             Glib::ustring selected_id;
55             selected_id = SP_OBJECT_ID(*selected);
56             _selected.insert(_selected.end(), selected_id);
57             //std::cout << "Selected: " << selected_id << std::endl;
58             ++selected;
59         }
60     }
62     _mainloop = Glib::MainLoop::create(false);
64     if (prefDialog == NULL) {
65         if (controls != NULL) {
66             createPrefsDialog(controls);
67         } else {
68             createWorkingDialog();
69         }
70     } else {
71         _visibleDialog = prefDialog;
72         _prefsVisible = true;
73         _dialogsig = _visibleDialog->signal_response().connect(sigc::mem_fun(this, &ExecutionEnv::preferencesResponse));
75         // We came from a dialog, we'll need to die by ourselves.
76         _selfdelete = true;
77     }
78     
79     if (_changeSignal != NULL) {
80         _changesig = _changeSignal->connect(sigc::mem_fun(this, &ExecutionEnv::preferencesChange));
81     }
83     return;
84 }
86 ExecutionEnv::~ExecutionEnv (void) {
87     _dialogsig.disconnect();
88     _timersig.disconnect();
89     if (_prefsVisible) {
90         _changesig.disconnect();
91     }
92     if (_visibleDialog != NULL && !_shutdown && !_prefsVisible) {
93         delete _visibleDialog;
94     }
95     if (_changeSignal != NULL && !_shutdown) {
96         delete _changeSignal;
97     }
98         killDocCache();
99     return;
102 void
103 ExecutionEnv::genDocCache (void) {
104 if (_docCache == NULL) {
105                 // printf("Gen Doc Cache\n");
106                 _docCache = _effect->get_imp()->newDocCache(_effect, _doc);
107         }
108         return;
111 void
112 ExecutionEnv::killDocCache (void) {
113         if (_docCache != NULL) {
114                 // printf("Killed Doc Cache\n");
115                 delete _docCache;
116                 _docCache = NULL;
117         }
118         return;
121 void
122 ExecutionEnv::preferencesChange (void) {
123     _timersig.disconnect();
124         if (_livePreview) {
125                 _timersig = Glib::signal_timeout().connect(sigc::mem_fun(this, &ExecutionEnv::preferencesTimer), 100, Glib::PRIORITY_DEFAULT_IDLE);
126         }
127     return;
130 bool
131 ExecutionEnv::preferencesTimer (void) {
132     //std::cout << "Preferences are a changin'" << std::endl;
133     _prefsChanged = true;
134     if (_humanWait) {
135         _mainloop->quit();
136         documentCancel();
137         _humanWait = false;
138     } else {
139         processingCancel();
140         documentCancel();
141     }
142     return false;
145 void
146 ExecutionEnv::createPrefsDialog (Gtk::Widget * controls) {
147     _visibleDialog = new PrefDialog(_effect->get_name(), _effect->get_help(), controls, this, _effect, _changeSignal);
148     _visibleDialog->show();
149     _dialogsig = _visibleDialog->signal_response().connect(sigc::mem_fun(this, &ExecutionEnv::preferencesResponse));
151     _prefsVisible = true;
152     return;
155 void
156 ExecutionEnv::createWorkingDialog (void) {
157     if (_visibleDialog != NULL) {
158         delete _visibleDialog;
159     }
160     if (_changeSignal != NULL) {
161         delete _changeSignal;
162         _changeSignal = NULL;
163     }
165     gchar * dlgmessage = g_strdup_printf(_("'%s' working, please wait..."), _effect->get_name());
166     _visibleDialog = new Gtk::MessageDialog(dlgmessage,
167                                false, // use markup
168                                Gtk::MESSAGE_INFO,
169                                Gtk::BUTTONS_CANCEL,
170                                true); // modal
171     _dialogsig = _visibleDialog->signal_response().connect(sigc::mem_fun(this, &ExecutionEnv::workingCanceled));
172     g_free(dlgmessage);
173     _visibleDialog->show();
175     _prefsVisible = false;
176     return;
179 void
180 ExecutionEnv::workingCanceled( const int /*resp*/ ) {
181         printf("Working Canceled\n");
182     processingCancel();
183     documentCancel();
184     _finished = true;
185     return;
188 void
189 ExecutionEnv::preferencesResponse (const int resp) {
190     if (resp == Gtk::RESPONSE_OK) {
191         if (_humanWait && _livePreview) {
192             documentCommit();
193             _mainloop->quit();
194             _finished = true;
195         } else {
196             createWorkingDialog();
197             if (!_livePreview) {
198                 _mainloop->quit();
199                 _humanWait = false;
200             }
201         }
202     } else {
203         if (_humanWait) {
204             _mainloop->quit();
205         } else {
206             processingCancel();
207         }
208         documentCancel();
209         _finished = true;
210     }
211     return;
214 void
215 ExecutionEnv::processingComplete(void) {
216     //std::cout << "Processing Complete" << std::endl;
217     if (_prefsChanged) { return; } // do it all again
218     if (_prefsVisible) {
219         _humanWait = true;
220     } else {
221         documentCommit();
222         _finished = true;
223     }
224     return;
227 void
228 ExecutionEnv::processingCancel (void) {
229     _effect->get_imp()->cancelProcessing();
230     return;
233 void
234 ExecutionEnv::documentCancel (void) {
235     _canceled = true;
236     return;
239 void
240 ExecutionEnv::documentCommit (void) {
241     sp_document_done(_doc->doc(), SP_VERB_NONE, _(_effect->get_name()));
242     Effect::set_last_effect(_effect);
243     _effect->get_imp()->commitDocument();
244     return;
247 void
248 ExecutionEnv::reselect (void) {
249     if (_doc == NULL) { return; }
250     SPDocument * doc = _doc->doc();
251     if (doc == NULL) { return; }
253     SPDesktop *desktop = (SPDesktop *)_doc;
254     sp_namedview_document_from_window(desktop);
256     if (desktop == NULL) { return; }
258     Inkscape::Selection * selection = sp_desktop_selection(desktop);
260     for (std::list<Glib::ustring>::iterator i = _selected.begin(); i != _selected.end(); i++) {
261         SPObject * obj = doc->getObjectById(i->c_str());
262         if (obj != NULL) {
263             selection->add(obj);
264         }
265     }
267     return;
270 void
271 ExecutionEnv::run (void) {
272     while (!_finished) {
273         _canceled = false;
274         if (_humanWait) {
275             _mainloop->run();
276         } else {
277             _prefsChanged = false;
278                         genDocCache();
279             _effect->get_imp()->effect(_effect, _doc, _docCache);
280             processingComplete();
281         }
282         if (_canceled) {
283             sp_document_cancel(_doc->doc());
284             reselect();
285         }
286     }
287     if (_selfdelete) {
288         delete this;
289     }
290     return;
293 /** \brief  Set the state of live preview
294     \param state  The current state
295         
296         This will cancel the document preview and and configure
297         whether we should be waiting on the human.  It will also
298         clear the document cache.
299 */
300 void
301 ExecutionEnv::livePreview (bool state) { 
302     _mainloop->quit();
303     if (_livePreview && !state) {
304         documentCancel();
305         _humanWait = true;
306     }
307     if (!_livePreview && state) {
308         _humanWait = false;
309     }
310     _livePreview = state;
311         if (!_livePreview) {
312                 killDocCache();
313         }
314     return;
317 void
318 ExecutionEnv::shutdown (bool del) { 
319     if (_humanWait) {
320         _mainloop->quit();
321     } else {
322         processingCancel();
323     }
324     documentCancel();
326     _finished = true;
327     _shutdown = true;
328     _selfdelete = del;
330     return;
333 } }  /* namespace Inkscape, Extension */
337 /*
338   Local Variables:
339   mode:c++
340   c-file-style:"stroustrup"
341   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
342   indent-tabs-mode:nil
343   fill-column:99
344   End:
345 */
346 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :