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 }
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;
100 }
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;
109 }
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;
119 }
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;
126 }
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;
141 }
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;
151 }
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;
175 }
177 void
178 ExecutionEnv::workingCanceled (const int resp) {
179 processingCancel();
180 documentCancel();
181 _finished = true;
182 return;
183 }
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;
209 }
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;
222 }
224 void
225 ExecutionEnv::processingCancel (void) {
226 _effect->get_imp()->cancelProcessing();
227 return;
228 }
230 void
231 ExecutionEnv::documentCancel (void) {
232 _canceled = true;
233 return;
234 }
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;
242 }
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;
265 }
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;
288 }
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;
305 }
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;
321 }
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 :