1 /*
2 * Authors:
3 * Ted Gould <ted@gould.cx>
4 *
5 * Copyright (C) 2007-2008 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"
25 #include "display/sp-canvas.h"
27 #include "util/glib-list-iterators.h"
29 namespace Inkscape {
30 namespace Extension {
32 /** \brief Create an execution environment that will allow the effect
33 to execute independently.
34 \param effect The effect that we should execute
35 \param doc The Document to execute on
36 \param docCache The cache created for that document
37 \param show_working Show the working dialog
38 \param show_error Show the error dialog (not working)
40 Grabs the selection of the current document so that it can get
41 restored. Will generate a document cache if one isn't provided.
42 */
43 ExecutionEnv::ExecutionEnv (Effect * effect, Inkscape::UI::View::View * doc, Implementation::ImplementationDocumentCache * docCache, bool show_working, bool show_errors) :
44 _state(ExecutionEnv::INIT),
45 _visibleDialog(NULL),
46 _mainloop(NULL),
47 _doc(doc),
48 _docCache(docCache),
49 _effect(effect),
50 _show_working(show_working),
51 _show_errors(show_errors)
52 {
53 SPDesktop *desktop = (SPDesktop *)_doc;
54 sp_namedview_document_from_window(desktop);
56 if (desktop != NULL) {
57 Inkscape::Util::GSListConstIterator<SPItem *> selected =
58 sp_desktop_selection(desktop)->itemList();
59 while ( selected != NULL ) {
60 Glib::ustring selected_id;
61 selected_id = SP_OBJECT_ID(*selected);
62 _selected.insert(_selected.end(), selected_id);
63 //std::cout << "Selected: " << selected_id << std::endl;
64 ++selected;
65 }
66 }
68 genDocCache();
70 return;
71 }
73 /** \brief Destroy an execution environment
75 Destroys the dialog if created and the document cache.
76 */
77 ExecutionEnv::~ExecutionEnv (void) {
78 if (_visibleDialog != NULL) {
79 _visibleDialog->hide();
80 delete _visibleDialog;
81 _visibleDialog = NULL;
82 }
83 killDocCache();
84 return;
85 }
87 /** \brief Generate a document cache if needed
89 If there isn't one we create a new one from the implementation
90 from the effect's implementation.
91 */
92 void
93 ExecutionEnv::genDocCache (void) {
94 if (_docCache == NULL) {
95 // printf("Gen Doc Cache\n");
96 _docCache = _effect->get_imp()->newDocCache(_effect, _doc);
97 }
98 return;
99 }
101 /** \brief Destory a document cache
103 Just delete it.
104 */
105 void
106 ExecutionEnv::killDocCache (void) {
107 if (_docCache != NULL) {
108 // printf("Killed Doc Cache\n");
109 delete _docCache;
110 _docCache = NULL;
111 }
112 return;
113 }
115 /** \brief Create the working dialog
117 Builds the dialog with a message saying that the effect is working.
118 And make sure to connect to the cancel.
119 */
120 void
121 ExecutionEnv::createWorkingDialog (void) {
122 if (_visibleDialog != NULL) {
123 _visibleDialog->hide();
124 delete _visibleDialog;
125 _visibleDialog = NULL;
126 }
128 SPDesktop *desktop = (SPDesktop *)_doc;
129 GtkWidget *toplevel = gtk_widget_get_toplevel(&(desktop->canvas->widget));
130 if (!toplevel || !GTK_WIDGET_TOPLEVEL (toplevel))
131 return;
132 Gtk::Window *window = Glib::wrap(GTK_WINDOW(toplevel), false);
134 gchar * dlgmessage = g_strdup_printf(_("'%s' working, please wait..."), _effect->get_name());
135 _visibleDialog = new Gtk::MessageDialog(*window,
136 dlgmessage,
137 false, // use markup
138 Gtk::MESSAGE_INFO,
139 Gtk::BUTTONS_CANCEL,
140 true); // modal
141 _visibleDialog->signal_response().connect(sigc::mem_fun(this, &ExecutionEnv::workingCanceled));
142 g_free(dlgmessage);
143 _visibleDialog->show();
145 return;
146 }
148 void
149 ExecutionEnv::workingCanceled( const int /*resp*/) {
150 cancel();
151 undo();
152 return;
153 }
155 void
156 ExecutionEnv::cancel (void) {
157 _effect->get_imp()->cancelProcessing();
158 return;
159 }
161 void
162 ExecutionEnv::undo (void) {
163 sp_document_cancel(_doc->doc());
164 reselect();
165 return;
166 }
168 void
169 ExecutionEnv::commit (void) {
170 sp_document_done(_doc->doc(), SP_VERB_NONE, _(_effect->get_name()));
171 Effect::set_last_effect(_effect);
172 _effect->get_imp()->commitDocument();
173 killDocCache();
174 return;
175 }
177 void
178 ExecutionEnv::reselect (void) {
179 if (_doc == NULL) { return; }
180 SPDocument * doc = _doc->doc();
181 if (doc == NULL) { return; }
183 SPDesktop *desktop = (SPDesktop *)_doc;
184 sp_namedview_document_from_window(desktop);
186 if (desktop == NULL) { return; }
188 Inkscape::Selection * selection = sp_desktop_selection(desktop);
190 for (std::list<Glib::ustring>::iterator i = _selected.begin(); i != _selected.end(); i++) {
191 SPObject * obj = doc->getObjectById(i->c_str());
192 if (obj != NULL) {
193 selection->add(obj);
194 }
195 }
197 return;
198 }
200 void
201 ExecutionEnv::run (void) {
202 _state = ExecutionEnv::RUNNING;
203 if (_show_working) {
204 createWorkingDialog();
205 }
206 _effect->get_imp()->effect(_effect, _doc, _docCache);
207 _state = ExecutionEnv::COMPLETE;
208 // _runComplete.signal();
209 return;
210 }
212 void
213 ExecutionEnv::runComplete (void) {
214 _mainloop->quit();
215 }
217 bool
218 ExecutionEnv::wait (void) {
219 if (_state != ExecutionEnv::COMPLETE) {
220 if (_mainloop) {
221 _mainloop = Glib::MainLoop::create(false);
222 }
224 sigc::connection conn = _runComplete.connect(sigc::mem_fun(this, &ExecutionEnv::runComplete));
225 _mainloop->run();
227 conn.disconnect();
228 }
230 return true;
231 }
235 } } /* namespace Inkscape, Extension */
239 /*
240 Local Variables:
241 mode:c++
242 c-file-style:"stroustrup"
243 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
244 indent-tabs-mode:nil
245 fill-column:99
246 End:
247 */
248 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :