1 /*
2 * Authors:
3 * Ted Gould <ted@gould.cx>
4 * Abhishek Sharma
5 *
6 * Copyright (C) 2007-2008 Authors
7 *
8 * Released under GNU GPL, read the file 'COPYING' for more information
9 */
11 #include <config.h>
13 #include "gtkmm/messagedialog.h"
15 #include "execution-env.h"
16 #include "prefdialog.h"
17 #include "implementation/implementation.h"
19 #include "selection.h"
20 #include "effect.h"
21 #include "document.h"
22 #include "desktop.h"
23 #include "ui/view/view.h"
24 #include "sp-namedview.h"
25 #include "desktop-handles.h"
26 #include "display/sp-canvas.h"
28 #include "util/glib-list-iterators.h"
30 namespace Inkscape {
31 namespace Extension {
33 /** \brief Create an execution environment that will allow the effect
34 to execute independently.
35 \param effect The effect that we should execute
36 \param doc The Document to execute on
37 \param docCache The cache created for that document
38 \param show_working Show the working dialog
39 \param show_error Show the error dialog (not working)
41 Grabs the selection of the current document so that it can get
42 restored. Will generate a document cache if one isn't provided.
43 */
44 ExecutionEnv::ExecutionEnv (Effect * effect, Inkscape::UI::View::View * doc, Implementation::ImplementationDocumentCache * docCache, bool show_working, bool show_errors) :
45 _state(ExecutionEnv::INIT),
46 _visibleDialog(NULL),
47 _mainloop(NULL),
48 _doc(doc),
49 _docCache(docCache),
50 _effect(effect),
51 _show_working(show_working),
52 _show_errors(show_errors)
53 {
54 SPDesktop *desktop = (SPDesktop *)_doc;
55 sp_namedview_document_from_window(desktop);
57 if (desktop != NULL) {
58 Inkscape::Util::GSListConstIterator<SPItem *> selected =
59 sp_desktop_selection(desktop)->itemList();
60 while ( selected != NULL ) {
61 Glib::ustring selected_id;
62 selected_id = (*selected)->getId();
63 _selected.insert(_selected.end(), selected_id);
64 //std::cout << "Selected: " << selected_id << std::endl;
65 ++selected;
66 }
67 }
69 genDocCache();
71 return;
72 }
74 /** \brief Destroy an execution environment
76 Destroys the dialog if created and the document cache.
77 */
78 ExecutionEnv::~ExecutionEnv (void) {
79 if (_visibleDialog != NULL) {
80 _visibleDialog->hide();
81 delete _visibleDialog;
82 _visibleDialog = NULL;
83 }
84 killDocCache();
85 return;
86 }
88 /** \brief Generate a document cache if needed
90 If there isn't one we create a new one from the implementation
91 from the effect's implementation.
92 */
93 void
94 ExecutionEnv::genDocCache (void) {
95 if (_docCache == NULL) {
96 // printf("Gen Doc Cache\n");
97 _docCache = _effect->get_imp()->newDocCache(_effect, _doc);
98 }
99 return;
100 }
102 /** \brief Destory a document cache
104 Just delete it.
105 */
106 void
107 ExecutionEnv::killDocCache (void) {
108 if (_docCache != NULL) {
109 // printf("Killed Doc Cache\n");
110 delete _docCache;
111 _docCache = NULL;
112 }
113 return;
114 }
116 /** \brief Create the working dialog
118 Builds the dialog with a message saying that the effect is working.
119 And make sure to connect to the cancel.
120 */
121 void
122 ExecutionEnv::createWorkingDialog (void) {
123 if (_visibleDialog != NULL) {
124 _visibleDialog->hide();
125 delete _visibleDialog;
126 _visibleDialog = NULL;
127 }
129 SPDesktop *desktop = (SPDesktop *)_doc;
130 GtkWidget *toplevel = gtk_widget_get_toplevel(&(desktop->canvas->widget));
131 if (!toplevel || !GTK_WIDGET_TOPLEVEL (toplevel))
132 return;
133 Gtk::Window *window = Glib::wrap(GTK_WINDOW(toplevel), false);
135 gchar * dlgmessage = g_strdup_printf(_("'%s' working, please wait..."), _(_effect->get_name()));
136 _visibleDialog = new Gtk::MessageDialog(*window,
137 dlgmessage,
138 false, // use markup
139 Gtk::MESSAGE_INFO,
140 Gtk::BUTTONS_CANCEL,
141 true); // modal
142 _visibleDialog->signal_response().connect(sigc::mem_fun(this, &ExecutionEnv::workingCanceled));
143 g_free(dlgmessage);
144 _visibleDialog->show();
146 return;
147 }
149 void
150 ExecutionEnv::workingCanceled( const int /*resp*/) {
151 cancel();
152 undo();
153 return;
154 }
156 void
157 ExecutionEnv::cancel (void) {
158 SPDesktop *desktop = (SPDesktop *)_doc;
159 desktop->clearWaitingCursor();
160 _effect->get_imp()->cancelProcessing();
161 return;
162 }
164 void
165 ExecutionEnv::undo (void) {
166 DocumentUndo::cancel(_doc->doc());
167 reselect();
168 return;
169 }
171 void
172 ExecutionEnv::commit (void) {
173 DocumentUndo::done(_doc->doc(), SP_VERB_NONE, _(_effect->get_name()));
174 Effect::set_last_effect(_effect);
175 _effect->get_imp()->commitDocument();
176 killDocCache();
177 return;
178 }
180 void
181 ExecutionEnv::reselect (void) {
182 if (_doc == NULL) { return; }
183 SPDocument * doc = _doc->doc();
184 if (doc == NULL) { return; }
186 SPDesktop *desktop = (SPDesktop *)_doc;
187 sp_namedview_document_from_window(desktop);
189 if (desktop == NULL) { return; }
191 Inkscape::Selection * selection = sp_desktop_selection(desktop);
193 for (std::list<Glib::ustring>::iterator i = _selected.begin(); i != _selected.end(); i++) {
194 SPObject * obj = doc->getObjectById(i->c_str());
195 if (obj != NULL) {
196 selection->add(obj);
197 }
198 }
200 return;
201 }
203 void
204 ExecutionEnv::run (void) {
205 _state = ExecutionEnv::RUNNING;
206 if (_show_working) {
207 createWorkingDialog();
208 }
209 SPDesktop *desktop = (SPDesktop *)_doc;
210 desktop->setWaitingCursor();
211 _effect->get_imp()->effect(_effect, _doc, _docCache);
212 desktop->clearWaitingCursor();
213 _state = ExecutionEnv::COMPLETE;
214 // _runComplete.signal();
215 return;
216 }
218 void
219 ExecutionEnv::runComplete (void) {
220 _mainloop->quit();
221 }
223 bool
224 ExecutionEnv::wait (void) {
225 if (_state != ExecutionEnv::COMPLETE) {
226 if (_mainloop) {
227 _mainloop = Glib::MainLoop::create(false);
228 }
230 sigc::connection conn = _runComplete.connect(sigc::mem_fun(this, &ExecutionEnv::runComplete));
231 _mainloop->run();
233 conn.disconnect();
234 }
236 return true;
237 }
241 } } /* namespace Inkscape, Extension */
245 /*
246 Local Variables:
247 mode:c++
248 c-file-style:"stroustrup"
249 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
250 indent-tabs-mode:nil
251 fill-column:99
252 End:
253 */
254 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :