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 _effect(effect),
34 _prefsVisible(false),
35 _finished(false),
36 _humanWait(false),
37 _canceled(false),
38 _prefsChanged(false),
39 _livePreview(true),
40 _selfdelete(false),
41 _changeSignal(changeSignal),
42 _doc(doc) {
44 SPDesktop *desktop = (SPDesktop *)_doc;
45 sp_namedview_document_from_window(desktop);
47 if (desktop != NULL) {
48 Inkscape::Util::GSListConstIterator<SPItem *> selected =
49 sp_desktop_selection(desktop)->itemList();
50 while ( selected != NULL ) {
51 Glib::ustring selected_id;
52 selected_id = SP_OBJECT_ID(*selected);
53 _selected.insert(_selected.end(), selected_id);
54 //std::cout << "Selected: " << selected_id << std::endl;
55 ++selected;
56 }
57 }
59 _mainloop = Glib::MainLoop::create(false);
61 if (prefDialog == NULL) {
62 if (controls != NULL) {
63 createPrefsDialog(controls);
64 } else {
65 createWorkingDialog();
66 }
67 } else {
68 _visibleDialog = prefDialog;
69 _prefsVisible = true;
71 // We came from a dialog, we'll need to die by ourselves.
72 _selfdelete = true;
73 }
75 if (_changeSignal != NULL) {
76 _changesig = _changeSignal->connect(sigc::mem_fun(this, &ExecutionEnv::preferencesChange));
77 }
79 return;
80 }
82 ExecutionEnv::~ExecutionEnv (void) {
83 _dialogsig.disconnect();
84 if (_prefsVisible) {
85 _changesig.disconnect();
86 }
87 if (_visibleDialog != NULL && !_shutdown) {
88 delete _visibleDialog;
89 }
90 if (_changeSignal != NULL && !_shutdown) {
91 delete _changeSignal;
92 }
93 return;
94 }
96 void
97 ExecutionEnv::preferencesChange (void) {
98 //std::cout << "Preferences are a changin'" << std::endl;
99 _prefsChanged = true;
100 if (_humanWait) {
101 _mainloop->quit();
102 documentCancel();
103 _humanWait = false;
104 } else {
105 processingCancel();
106 documentCancel();
107 }
108 return;
109 }
111 void
112 ExecutionEnv::createPrefsDialog (Gtk::Widget * controls) {
113 _visibleDialog = new PrefDialog(_effect->get_name(), _effect->get_help(), controls, this, _effect, _changeSignal);
114 _visibleDialog->signal_response().connect(sigc::mem_fun(this, &ExecutionEnv::preferencesResponse));
115 _visibleDialog->show();
116 _dialogsig = _visibleDialog->signal_response().connect(sigc::mem_fun(this, &ExecutionEnv::preferencesResponse));
118 _prefsVisible = true;
119 return;
120 }
122 void
123 ExecutionEnv::createWorkingDialog (void) {
124 if (_visibleDialog != NULL) {
125 delete _visibleDialog;
126 }
127 if (_changeSignal != NULL) {
128 delete _changeSignal;
129 _changeSignal = NULL;
130 }
132 gchar * dlgmessage = g_strdup_printf(_("'%s' working, please wait..."), _effect->get_name());
133 _visibleDialog = new Gtk::MessageDialog(dlgmessage,
134 false, // use markup
135 Gtk::MESSAGE_INFO,
136 Gtk::BUTTONS_CANCEL,
137 true); // modal
138 _dialogsig = _visibleDialog->signal_response().connect(sigc::mem_fun(this, &ExecutionEnv::workingCanceled));
139 g_free(dlgmessage);
140 _visibleDialog->show();
142 _prefsVisible = false;
143 return;
144 }
146 void
147 ExecutionEnv::workingCanceled (const int resp) {
148 processingCancel();
149 documentCancel();
150 _finished = true;
151 return;
152 }
154 void
155 ExecutionEnv::preferencesResponse (const int resp) {
156 if (resp == Gtk::RESPONSE_OK) {
157 if (_humanWait && _livePreview) {
158 documentCommit();
159 _mainloop->quit();
160 _finished = true;
161 } else {
162 createWorkingDialog();
163 if (!_livePreview) {
164 _mainloop->quit();
165 _humanWait = false;
166 }
167 }
168 } else {
169 if (_humanWait) {
170 _mainloop->quit();
171 } else {
172 processingCancel();
173 }
174 documentCancel();
175 _finished = true;
176 }
177 return;
178 }
180 void
181 ExecutionEnv::processingComplete(void) {
182 //std::cout << "Processing Complete" << std::endl;
183 if (_prefsChanged) { return; } // do it all again
184 if (_prefsVisible) {
185 _humanWait = true;
186 } else {
187 documentCommit();
188 _finished = true;
189 }
190 return;
191 }
193 void
194 ExecutionEnv::processingCancel (void) {
195 _effect->get_imp()->cancelProcessing();
196 return;
197 }
199 void
200 ExecutionEnv::documentCancel (void) {
201 _canceled = true;
202 return;
203 }
205 void
206 ExecutionEnv::documentCommit (void) {
207 sp_document_done(_doc->doc(), SP_VERB_NONE, _(_effect->get_name()));
208 Effect::set_last_effect(_effect);
209 return;
210 }
212 void
213 ExecutionEnv::reselect (void) {
214 if (_doc == NULL) { return; }
215 SPDocument * doc = _doc->doc();
216 if (doc == NULL) { return; }
218 SPDesktop *desktop = (SPDesktop *)_doc;
219 sp_namedview_document_from_window(desktop);
221 if (desktop == NULL) { return; }
223 Inkscape::Selection * selection = sp_desktop_selection(desktop);
225 for (std::list<Glib::ustring>::iterator i = _selected.begin(); i != _selected.end(); i++) {
226 SPObject * obj = doc->getObjectById(i->c_str());
227 if (obj != NULL) {
228 selection->add(obj);
229 }
230 }
232 return;
233 }
235 void
236 ExecutionEnv::run (void) {
237 while (!_finished) {
238 _canceled = false;
239 if (_humanWait) {
240 _mainloop->run();
241 } else {
242 _prefsChanged = false;
243 _effect->get_imp()->effect(_effect, _doc);
244 processingComplete();
245 }
246 if (_canceled) {
247 sp_document_cancel(_doc->doc());
248 reselect();
249 }
250 }
251 if (_selfdelete) {
252 delete this;
253 }
254 return;
255 }
257 void
258 ExecutionEnv::livePreview (bool state) {
259 _mainloop->quit();
260 if (_livePreview && !state) {
261 documentCancel();
262 _humanWait = true;
263 }
264 if (!_livePreview && state) {
265 _humanWait = false;
266 }
267 _livePreview = state;
268 return;
269 }
271 void
272 ExecutionEnv::shutdown (bool del) {
273 if (_humanWait) {
274 _mainloop->quit();
275 } else {
276 processingCancel();
277 }
278 documentCancel();
280 _finished = true;
281 _visibleDialog = NULL;
282 }
283 _selfdelete = del;
285 return;
286 }
288 } } /* namespace Inkscape, Extension */
292 /*
293 Local Variables:
294 mode:c++
295 c-file-style:"stroustrup"
296 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
297 indent-tabs-mode:nil
298 fill-column:99
299 End:
300 */
301 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :