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 }
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;
104 }
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;
119 }
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;
129 }
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;
153 }
155 void
156 ExecutionEnv::workingCanceled (const int resp) {
157 processingCancel();
158 documentCancel();
159 _finished = true;
160 return;
161 }
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;
187 }
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;
200 }
202 void
203 ExecutionEnv::processingCancel (void) {
204 _effect->get_imp()->cancelProcessing();
205 return;
206 }
208 void
209 ExecutionEnv::documentCancel (void) {
210 _canceled = true;
211 return;
212 }
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;
219 }
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;
242 }
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;
264 }
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;
278 }
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;
294 }
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 :