Code

r16474@tres: ted | 2007-08-31 21:37:33 -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 "ui/view/view.h"
22 #include "sp-namedview.h"
23 #include "desktop-handles.h"
25 #include "util/glib-list-iterators.h"
27 namespace Inkscape {
28 namespace Extension {
31 ExecutionEnv::ExecutionEnv (Effect * effect, Inkscape::UI::View::View * doc, Gtk::Widget * controls, sigc::signal<void> * changeSignal, Gtk::Dialog * prefDialog) :
32     _visibleDialog(NULL),
33     _prefsVisible(false),
34     _finished(false),
35     _humanWait(false),
36     _canceled(false),
37     _prefsChanged(false),
38     _livePreview(true),
39     _shutdown(false),
40     _selfdelete(false),
41     _changeSignal(changeSignal),
42     _doc(doc),
43     _effect(effect) {
45     SPDesktop *desktop = (SPDesktop *)_doc;
46     sp_namedview_document_from_window(desktop);
48     if (desktop != NULL) {
49         Inkscape::Util::GSListConstIterator<SPItem *> selected =
50              sp_desktop_selection(desktop)->itemList();
51         while ( selected != NULL ) {
52             Glib::ustring selected_id;
53             selected_id = SP_OBJECT_ID(*selected);
54             _selected.insert(_selected.end(), selected_id);
55             //std::cout << "Selected: " << selected_id << std::endl;
56             ++selected;
57         }
58     }
60     _mainloop = Glib::MainLoop::create(false);
62     if (prefDialog == NULL) {
63         if (controls != NULL) {
64             createPrefsDialog(controls);
65         } else {
66             createWorkingDialog();
67         }
68     } else {
69         _visibleDialog = prefDialog;
70         _prefsVisible = true;
71         _dialogsig = _visibleDialog->signal_response().connect(sigc::mem_fun(this, &ExecutionEnv::preferencesResponse));
73         // We came from a dialog, we'll need to die by ourselves.
74         _selfdelete = true;
75     }
76     
77     if (_changeSignal != NULL) {
78         _changesig = _changeSignal->connect(sigc::mem_fun(this, &ExecutionEnv::preferencesChange));
79     }
81     return;
82 }
84 ExecutionEnv::~ExecutionEnv (void) {
85     _dialogsig.disconnect();
86     _timersig.disconnect();
87     if (_prefsVisible) {
88         _changesig.disconnect();
89     }
90     if (_visibleDialog != NULL && !_shutdown) {
91         delete _visibleDialog;
92     }
93     if (_changeSignal != NULL && !_shutdown) {
94         delete _changeSignal;
95     }
96     return;
97 }
99 void
100 ExecutionEnv::preferencesChange (void) {
101     _timersig.disconnect();
102     _timersig = Glib::signal_timeout().connect(sigc::mem_fun(this, &ExecutionEnv::preferencesTimer), 100, Glib::PRIORITY_DEFAULT_IDLE);
103     return;
106 bool
107 ExecutionEnv::preferencesTimer (void) {
108     //std::cout << "Preferences are a changin'" << std::endl;
109     _prefsChanged = true;
110     if (_humanWait) {
111         _mainloop->quit();
112         documentCancel();
113         _humanWait = false;
114     } else {
115         processingCancel();
116         documentCancel();
117     }
118     return false;
121 void
122 ExecutionEnv::createPrefsDialog (Gtk::Widget * controls) {
123     _visibleDialog = new PrefDialog(_effect->get_name(), _effect->get_help(), controls, this, _effect, _changeSignal);
124     _visibleDialog->show();
125     _dialogsig = _visibleDialog->signal_response().connect(sigc::mem_fun(this, &ExecutionEnv::preferencesResponse));
127     _prefsVisible = true;
128     return;
131 void
132 ExecutionEnv::createWorkingDialog (void) {
133     if (_visibleDialog != NULL) {
134         delete _visibleDialog;
135     }
136     if (_changeSignal != NULL) {
137         delete _changeSignal;
138         _changeSignal = NULL;
139     }
141     gchar * dlgmessage = g_strdup_printf(_("'%s' working, please wait..."), _effect->get_name());
142     _visibleDialog = new Gtk::MessageDialog(dlgmessage,
143                                false, // use markup
144                                Gtk::MESSAGE_INFO,
145                                Gtk::BUTTONS_CANCEL,
146                                true); // modal
147     _dialogsig = _visibleDialog->signal_response().connect(sigc::mem_fun(this, &ExecutionEnv::workingCanceled));
148     g_free(dlgmessage);
149     _visibleDialog->show();
151     _prefsVisible = false;
152     return;
155 void
156 ExecutionEnv::workingCanceled (const int resp) {
157     processingCancel();
158     documentCancel();
159     _finished = true;
160     return;
163 void
164 ExecutionEnv::preferencesResponse (const int resp) {
165     if (resp == Gtk::RESPONSE_OK) {
166         if (_humanWait && _livePreview) {
167             documentCommit();
168             _mainloop->quit();
169             _finished = true;
170         } else {
171             createWorkingDialog();
172             if (!_livePreview) {
173                 _mainloop->quit();
174                 _humanWait = false;
175             }
176         }
177     } else {
178         if (_humanWait) {
179             _mainloop->quit();
180         } else {
181             processingCancel();
182         }
183         documentCancel();
184         _finished = true;
185     }
186     return;
189 void
190 ExecutionEnv::processingComplete(void) {
191     //std::cout << "Processing Complete" << std::endl;
192     if (_prefsChanged) { return; } // do it all again
193     if (_prefsVisible) {
194         _humanWait = true;
195     } else {
196         documentCommit();
197         _finished = true;
198     }
199     return;
202 void
203 ExecutionEnv::processingCancel (void) {
204     _effect->get_imp()->cancelProcessing();
205     return;
208 void
209 ExecutionEnv::documentCancel (void) {
210     _canceled = true;
211     return;
214 void
215 ExecutionEnv::documentCommit (void) {
216     sp_document_done(_doc->doc(), SP_VERB_NONE, _(_effect->get_name()));
217     Effect::set_last_effect(_effect);
218     return;
221 void
222 ExecutionEnv::reselect (void) {
223     if (_doc == NULL) { return; }
224     SPDocument * doc = _doc->doc();
225     if (doc == NULL) { return; }
227     SPDesktop *desktop = (SPDesktop *)_doc;
228     sp_namedview_document_from_window(desktop);
230     if (desktop == NULL) { return; }
232     Inkscape::Selection * selection = sp_desktop_selection(desktop);
234     for (std::list<Glib::ustring>::iterator i = _selected.begin(); i != _selected.end(); i++) {
235         SPObject * obj = doc->getObjectById(i->c_str());
236         if (obj != NULL) {
237             selection->add(obj);
238         }
239     }
241     return;
244 void
245 ExecutionEnv::run (void) {
246     while (!_finished) {
247         _canceled = false;
248         if (_humanWait) {
249             _mainloop->run();
250         } else {
251             _prefsChanged = false;
252             _effect->get_imp()->effect(_effect, _doc);
253             processingComplete();
254         }
255         if (_canceled) {
256             sp_document_cancel(_doc->doc());
257             reselect();
258         }
259     }
260     if (_selfdelete) {
261         delete this;
262     }
263     return;
266 void
267 ExecutionEnv::livePreview (bool state) { 
268     _mainloop->quit();
269     if (_livePreview && !state) {
270         documentCancel();
271         _humanWait = true;
272     }
273     if (!_livePreview && state) {
274         _humanWait = false;
275     }
276     _livePreview = state;
277     return;
280 void
281 ExecutionEnv::shutdown (bool del) { 
282     if (_humanWait) {
283         _mainloop->quit();
284     } else {
285         processingCancel();
286     }
287     documentCancel();
289     _finished = true;
290     _shutdown = true;
291     _selfdelete = del;
293     return;
296 } }  /* namespace Inkscape, Extension */
300 /*
301   Local Variables:
302   mode:c++
303   c-file-style:"stroustrup"
304   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
305   indent-tabs-mode:nil
306   fill-column:99
307   End:
308 */
309 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :