Code

A simple layout document as to what, why and how is cppification.
[inkscape.git] / src / extension / execution-env.cpp
index 4fc559b8db9f3455035597c8ae1ec0da4a2626aa..d97c8c6de89039ad1cc44a052ce56b0c62d643ad 100644 (file)
@@ -2,7 +2,7 @@
  * Authors:
  *   Ted Gould <ted@gould.cx>
  *
- * Copyright (C) 2007 Authors
+ * Copyright (C) 2007-2008 Authors
  *
  * Released under GNU GPL, read the file 'COPYING' for more information
  */
 #include "selection.h"
 #include "effect.h"
 #include "document.h"
+#include "desktop.h"
 #include "ui/view/view.h"
 #include "sp-namedview.h"
 #include "desktop-handles.h"
+#include "display/sp-canvas.h"
 
 #include "util/glib-list-iterators.h"
 
 namespace Inkscape {
 namespace Extension {
 
+/** \brief  Create an execution environment that will allow the effect
+            to execute independently.
+    \param effect  The effect that we should execute
+    \param doc     The Document to execute on
+    \param docCache  The cache created for that document
+    \param show_working  Show the working dialog
+    \param show_error    Show the error dialog (not working)
 
-ExecutionEnv::ExecutionEnv (Effect * effect, Inkscape::UI::View::View * doc, Gtk::Widget * controls) :
-    _effect(effect),
+    Grabs the selection of the current document so that it can get
+    restored.  Will generate a document cache if one isn't provided.
+*/
+ExecutionEnv::ExecutionEnv (Effect * effect, Inkscape::UI::View::View * doc, Implementation::ImplementationDocumentCache * docCache, bool show_working, bool show_errors) :
+    _state(ExecutionEnv::INIT),
     _visibleDialog(NULL),
-    _prefsVisible(false),
-    _finished(false),
-    _humanWait(false),
-    _canceled(false),
-    _prefsChanged(false),
-    _doc(doc) {
-
+    _mainloop(NULL),
+    _doc(doc),
+    _docCache(docCache),
+    _effect(effect),
+    _show_working(show_working),
+    _show_errors(show_errors)
+{
     SPDesktop *desktop = (SPDesktop *)_doc;
     sp_namedview_document_from_window(desktop);
 
@@ -46,68 +58,82 @@ ExecutionEnv::ExecutionEnv (Effect * effect, Inkscape::UI::View::View * doc, Gtk
              sp_desktop_selection(desktop)->itemList();
         while ( selected != NULL ) {
             Glib::ustring selected_id;
-            selected_id = SP_OBJECT_ID(*selected);
+            selected_id = (*selected)->getId();
             _selected.insert(_selected.end(), selected_id);
             //std::cout << "Selected: " << selected_id << std::endl;
             ++selected;
         }
     }
 
-    _mainloop = Glib::MainLoop::create(false);
-
-    if (controls != NULL) {
-        createPrefsDialog(controls);
-    } else {
-        createWorkingDialog();
-    }
+    genDocCache();
 
     return;
 }
 
+/** \brief  Destroy an execution environment
+
+    Destroys the dialog if created and the document cache.
+*/
 ExecutionEnv::~ExecutionEnv (void) {
     if (_visibleDialog != NULL) {
+        _visibleDialog->hide();
         delete _visibleDialog;
+        _visibleDialog = NULL;
     }
+    killDocCache();
     return;
 }
 
+/** \brief  Generate a document cache if needed
+
+    If there isn't one we create a new one from the implementation
+    from the effect's implementation.
+*/
 void
-ExecutionEnv::preferencesChange (void) {
-    //std::cout << "Preferences are a changin'" << std::endl;
-    _prefsChanged = true;
-    if (_humanWait) {
-        _mainloop->quit();
-        documentCancel();
-        _humanWait = false;
-    } else {
-        processingCancel();
-        documentCancel();
+ExecutionEnv::genDocCache (void) {
+    if (_docCache == NULL) {
+        // printf("Gen Doc Cache\n");
+        _docCache = _effect->get_imp()->newDocCache(_effect, _doc);
     }
     return;
 }
 
+/** \brief  Destory a document cache
+
+    Just delete it.
+*/
 void
-ExecutionEnv::createPrefsDialog (Gtk::Widget * controls) {
-    if (_visibleDialog != NULL) {
-        delete _visibleDialog;
+ExecutionEnv::killDocCache (void) {
+    if (_docCache != NULL) {
+        // printf("Killed Doc Cache\n");
+        delete _docCache;
+        _docCache = NULL;
     }
-
-    _visibleDialog = new PrefDialog(_effect->get_name(), _effect->get_help(), controls);
-    _visibleDialog->signal_response().connect(sigc::mem_fun(this, &ExecutionEnv::preferencesResponse));
-    _visibleDialog->show();
-
-    _prefsVisible = true;
     return;
 }
 
+/** \brief  Create the working dialog
+
+    Builds the dialog with a message saying that the effect is working.
+    And make sure to connect to the cancel.
+*/
 void
 ExecutionEnv::createWorkingDialog (void) {
     if (_visibleDialog != NULL) {
+        _visibleDialog->hide();
         delete _visibleDialog;
+        _visibleDialog = NULL;
     }
 
-    gchar * dlgmessage = g_strdup_printf(_("The effect '%s' is working on your document.  Please wait."), _effect->get_name());
-    _visibleDialog = new Gtk::MessageDialog(dlgmessage,
+    SPDesktop *desktop = (SPDesktop *)_doc;
+    GtkWidget *toplevel = gtk_widget_get_toplevel(&(desktop->canvas->widget));
+    if (!toplevel || !GTK_WIDGET_TOPLEVEL (toplevel))
+        return;
+    Gtk::Window *window = Glib::wrap(GTK_WINDOW(toplevel), false);
+
+    gchar * dlgmessage = g_strdup_printf(_("'%s' working, please wait..."), _(_effect->get_name()));
+    _visibleDialog = new Gtk::MessageDialog(*window,
+                               dlgmessage,
                                false, // use markup
                                Gtk::MESSAGE_INFO,
                                Gtk::BUTTONS_CANCEL,
@@ -116,75 +142,45 @@ ExecutionEnv::createWorkingDialog (void) {
     g_free(dlgmessage);
     _visibleDialog->show();
 
-    _prefsVisible = false;
     return;
 }
 
 void
-ExecutionEnv::workingCanceled (const int resp) {
-    processingCancel();
-    documentCancel();
-    _finished = true;
+ExecutionEnv::workingCanceled( const int /*resp*/) {
+    cancel();
+    undo();
     return;
 }
 
 void
-ExecutionEnv::preferencesResponse (const int resp) {
-    if (resp == Gtk::RESPONSE_OK) {
-        if (_humanWait) {
-            documentCommit();
-            _mainloop->quit();
-            _finished = true;
-        } else {
-            createWorkingDialog();
-        }
-    } else {
-        if (_humanWait) {
-            _mainloop->quit();
-        } else {
-            processingCancel();
-        }
-        documentCancel();
-        _finished = true;
-    }
-    return;
-}
-
-void
-ExecutionEnv::processingComplete(void) {
-    //std::cout << "Processing Complete" << std::endl;
-    if (_prefsChanged) { return; } // do it all again
-    if (_prefsVisible) {
-        _humanWait = true;
-    } else {
-        documentCommit();
-        _finished = true;
-    }
-    return;
-}
-
-void
-ExecutionEnv::processingCancel (void) {
+ExecutionEnv::cancel (void) {
+    SPDesktop *desktop = (SPDesktop *)_doc;
+    desktop->clearWaitingCursor();
     _effect->get_imp()->cancelProcessing();
     return;
 }
 
 void
-ExecutionEnv::documentCancel (void) {
-    _canceled = true;
+ExecutionEnv::undo (void) {
+    SPDocumentUndo::cancel(_doc->doc());
+    reselect();
     return;
 }
 
 void
-ExecutionEnv::documentCommit (void) {
-    sp_document_done(_doc->doc(), SP_VERB_NONE, _(_effect->get_name()));
+ExecutionEnv::commit (void) {
+    SPDocumentUndo::done(_doc->doc(), SP_VERB_NONE, _(_effect->get_name()));
     Effect::set_last_effect(_effect);
+    _effect->get_imp()->commitDocument();
+    killDocCache();
     return;
 }
 
 void
 ExecutionEnv::reselect (void) {
+    if (_doc == NULL) { return; }
     SPDocument * doc = _doc->doc();
+    if (doc == NULL) { return; }
 
     SPDesktop *desktop = (SPDesktop *)_doc;
     sp_namedview_document_from_window(desktop);
@@ -194,7 +190,10 @@ ExecutionEnv::reselect (void) {
     Inkscape::Selection * selection = sp_desktop_selection(desktop);
 
     for (std::list<Glib::ustring>::iterator i = _selected.begin(); i != _selected.end(); i++) {
-        selection->add(doc->getObjectById(i->c_str()));
+        SPObject * obj = doc->getObjectById(i->c_str());
+        if (obj != NULL) {
+            selection->add(obj);
+        }
     }
 
     return;
@@ -202,23 +201,40 @@ ExecutionEnv::reselect (void) {
 
 void
 ExecutionEnv::run (void) {
-    while (!_finished) {
-        _canceled = false;
-        if (_humanWait) {
-            _mainloop->run();
-        } else {
-            _prefsChanged = false;
-            _effect->get_imp()->effect(_effect, _doc);
-            processingComplete();
-        }
-        if (_canceled) {
-            sp_document_cancel(_doc->doc());
-            reselect();
-        }
+    _state = ExecutionEnv::RUNNING;
+    if (_show_working) {
+        createWorkingDialog();
     }
+    SPDesktop *desktop = (SPDesktop *)_doc;
+    desktop->setWaitingCursor();
+    _effect->get_imp()->effect(_effect, _doc, _docCache);
+    desktop->clearWaitingCursor();
+    _state = ExecutionEnv::COMPLETE;
+    // _runComplete.signal();
     return;
 }
 
+void
+ExecutionEnv::runComplete (void) {
+    _mainloop->quit();
+}
+
+bool
+ExecutionEnv::wait (void) {
+    if (_state != ExecutionEnv::COMPLETE) {
+        if (_mainloop) {
+            _mainloop = Glib::MainLoop::create(false);
+        }
+
+        sigc::connection conn = _runComplete.connect(sigc::mem_fun(this, &ExecutionEnv::runComplete));
+        _mainloop->run();
+
+        conn.disconnect();
+    }
+
+    return true;
+}
+
 
 
 } }  /* namespace Inkscape, Extension */