Code

r16893@shi: ted | 2007-10-30 07:31:04 -0700
[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     _effect(effect),
45         _docCache(docCache) {
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) {
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                 Implementation::ImplementationDocumentCache * _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     _timersig = Glib::signal_timeout().connect(sigc::mem_fun(this, &ExecutionEnv::preferencesTimer), 100, Glib::PRIORITY_DEFAULT_IDLE);
125     return;
128 bool
129 ExecutionEnv::preferencesTimer (void) {
130     //std::cout << "Preferences are a changin'" << std::endl;
131     _prefsChanged = true;
132     if (_humanWait) {
133         _mainloop->quit();
134         documentCancel();
135         _humanWait = false;
136     } else {
137         processingCancel();
138         documentCancel();
139     }
140     return false;
143 void
144 ExecutionEnv::createPrefsDialog (Gtk::Widget * controls) {
145     _visibleDialog = new PrefDialog(_effect->get_name(), _effect->get_help(), controls, this, _effect, _changeSignal);
146     _visibleDialog->show();
147     _dialogsig = _visibleDialog->signal_response().connect(sigc::mem_fun(this, &ExecutionEnv::preferencesResponse));
149     _prefsVisible = true;
150     return;
153 void
154 ExecutionEnv::createWorkingDialog (void) {
155     if (_visibleDialog != NULL) {
156         delete _visibleDialog;
157     }
158     if (_changeSignal != NULL) {
159         delete _changeSignal;
160         _changeSignal = NULL;
161     }
163     gchar * dlgmessage = g_strdup_printf(_("'%s' working, please wait..."), _effect->get_name());
164     _visibleDialog = new Gtk::MessageDialog(dlgmessage,
165                                false, // use markup
166                                Gtk::MESSAGE_INFO,
167                                Gtk::BUTTONS_CANCEL,
168                                true); // modal
169     _dialogsig = _visibleDialog->signal_response().connect(sigc::mem_fun(this, &ExecutionEnv::workingCanceled));
170     g_free(dlgmessage);
171     _visibleDialog->show();
173     _prefsVisible = false;
174     return;
177 void
178 ExecutionEnv::workingCanceled (const int resp) {
179     processingCancel();
180     documentCancel();
181     _finished = true;
182     return;
185 void
186 ExecutionEnv::preferencesResponse (const int resp) {
187     if (resp == Gtk::RESPONSE_OK) {
188         if (_humanWait && _livePreview) {
189             documentCommit();
190             _mainloop->quit();
191             _finished = true;
192         } else {
193             createWorkingDialog();
194             if (!_livePreview) {
195                 _mainloop->quit();
196                 _humanWait = false;
197             }
198         }
199     } else {
200         if (_humanWait) {
201             _mainloop->quit();
202         } else {
203             processingCancel();
204         }
205         documentCancel();
206         _finished = true;
207     }
208     return;
211 void
212 ExecutionEnv::processingComplete(void) {
213     //std::cout << "Processing Complete" << std::endl;
214     if (_prefsChanged) { return; } // do it all again
215     if (_prefsVisible) {
216         _humanWait = true;
217     } else {
218         documentCommit();
219         _finished = true;
220     }
221     return;
224 void
225 ExecutionEnv::processingCancel (void) {
226     _effect->get_imp()->cancelProcessing();
227     return;
230 void
231 ExecutionEnv::documentCancel (void) {
232     _canceled = true;
233     return;
236 void
237 ExecutionEnv::documentCommit (void) {
238     sp_document_done(_doc->doc(), SP_VERB_NONE, _(_effect->get_name()));
239     Effect::set_last_effect(_effect);
240     _effect->get_imp()->commitDocument();
241     return;
244 void
245 ExecutionEnv::reselect (void) {
246     if (_doc == NULL) { return; }
247     SPDocument * doc = _doc->doc();
248     if (doc == NULL) { return; }
250     SPDesktop *desktop = (SPDesktop *)_doc;
251     sp_namedview_document_from_window(desktop);
253     if (desktop == NULL) { return; }
255     Inkscape::Selection * selection = sp_desktop_selection(desktop);
257     for (std::list<Glib::ustring>::iterator i = _selected.begin(); i != _selected.end(); i++) {
258         SPObject * obj = doc->getObjectById(i->c_str());
259         if (obj != NULL) {
260             selection->add(obj);
261         }
262     }
264     return;
267 void
268 ExecutionEnv::run (void) {
269     while (!_finished) {
270         _canceled = false;
271         if (_humanWait) {
272             _mainloop->run();
273         } else {
274             _prefsChanged = false;
275                         genDocCache();
276             _effect->get_imp()->effect(_effect, _doc, _docCache);
277             processingComplete();
278         }
279         if (_canceled) {
280             sp_document_cancel(_doc->doc());
281             reselect();
282         }
283     }
284     if (_selfdelete) {
285         delete this;
286     }
287     return;
290 void
291 ExecutionEnv::livePreview (bool state) { 
292     _mainloop->quit();
293     if (_livePreview && !state) {
294         documentCancel();
295         _humanWait = true;
296     }
297     if (!_livePreview && state) {
298         _humanWait = false;
299     }
300     _livePreview = state;
301         if (!_livePreview) {
302                 killDocCache();
303         }
304     return;
307 void
308 ExecutionEnv::shutdown (bool del) { 
309     if (_humanWait) {
310         _mainloop->quit();
311     } else {
312         processingCancel();
313     }
314     documentCancel();
316     _finished = true;
317     _shutdown = true;
318     _selfdelete = del;
320     return;
323 } }  /* namespace Inkscape, Extension */
327 /*
328   Local Variables:
329   mode:c++
330   c-file-style:"stroustrup"
331   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
332   indent-tabs-mode:nil
333   fill-column:99
334   End:
335 */
336 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :