Code

Merge and cleanup of GSoC C++-ification project.
[inkscape.git] / src / extension / execution-env.cpp
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;
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;
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;
149 void
150 ExecutionEnv::workingCanceled( const int /*resp*/) {
151     cancel();
152     undo();
153     return;
156 void
157 ExecutionEnv::cancel (void) {
158     SPDesktop *desktop = (SPDesktop *)_doc;
159     desktop->clearWaitingCursor();
160     _effect->get_imp()->cancelProcessing();
161     return;
164 void
165 ExecutionEnv::undo (void) {
166     DocumentUndo::cancel(_doc->doc());
167     reselect();
168     return;
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;
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;
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;
218 void
219 ExecutionEnv::runComplete (void) {
220     _mainloop->quit();
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;
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 :