/* * Authors: * Ted Gould * * Copyright (C) 2007 Authors * * Released under GNU GPL, read the file 'COPYING' for more information */ #include #include "gtkmm/messagedialog.h" #include "execution-env.h" #include "prefdialog.h" #include "implementation/implementation.h" #include "selection.h" #include "effect.h" #include "document.h" #include "ui/view/view.h" #include "sp-namedview.h" #include "desktop-handles.h" #include "util/glib-list-iterators.h" namespace Inkscape { namespace Extension { ExecutionEnv::ExecutionEnv (Effect * effect, Inkscape::UI::View::View * doc, Gtk::Widget * controls, sigc::signal * changeSignal, Gtk::Dialog * prefDialog) : _visibleDialog(NULL), _prefsVisible(false), _finished(false), _humanWait(false), _canceled(false), _prefsChanged(false), _livePreview(true), _shutdown(false), _selfdelete(false), _changeSignal(changeSignal), _doc(doc), _effect(effect) { SPDesktop *desktop = (SPDesktop *)_doc; sp_namedview_document_from_window(desktop); if (desktop != NULL) { Inkscape::Util::GSListConstIterator selected = sp_desktop_selection(desktop)->itemList(); while ( selected != NULL ) { Glib::ustring selected_id; selected_id = SP_OBJECT_ID(*selected); _selected.insert(_selected.end(), selected_id); //std::cout << "Selected: " << selected_id << std::endl; ++selected; } } _mainloop = Glib::MainLoop::create(false); if (prefDialog == NULL) { if (controls != NULL) { createPrefsDialog(controls); } else { createWorkingDialog(); } } else { _visibleDialog = prefDialog; _prefsVisible = true; _dialogsig = _visibleDialog->signal_response().connect(sigc::mem_fun(this, &ExecutionEnv::preferencesResponse)); // We came from a dialog, we'll need to die by ourselves. _selfdelete = true; } if (_changeSignal != NULL) { _changesig = _changeSignal->connect(sigc::mem_fun(this, &ExecutionEnv::preferencesChange)); } return; } ExecutionEnv::~ExecutionEnv (void) { _dialogsig.disconnect(); _timersig.disconnect(); if (_prefsVisible) { _changesig.disconnect(); } if (_visibleDialog != NULL && !_shutdown) { delete _visibleDialog; } if (_changeSignal != NULL && !_shutdown) { delete _changeSignal; } return; } void ExecutionEnv::preferencesChange (void) { _timersig.disconnect(); _timersig = Glib::signal_timeout().connect(sigc::mem_fun(this, &ExecutionEnv::preferencesTimer), 100, Glib::PRIORITY_DEFAULT_IDLE); return; } bool ExecutionEnv::preferencesTimer (void) { //std::cout << "Preferences are a changin'" << std::endl; _prefsChanged = true; if (_humanWait) { _mainloop->quit(); documentCancel(); _humanWait = false; } else { processingCancel(); documentCancel(); } return false; } void ExecutionEnv::createPrefsDialog (Gtk::Widget * controls) { _visibleDialog = new PrefDialog(_effect->get_name(), _effect->get_help(), controls, this, _effect, _changeSignal); _visibleDialog->show(); _dialogsig = _visibleDialog->signal_response().connect(sigc::mem_fun(this, &ExecutionEnv::preferencesResponse)); _prefsVisible = true; return; } void ExecutionEnv::createWorkingDialog (void) { if (_visibleDialog != NULL) { delete _visibleDialog; } if (_changeSignal != NULL) { delete _changeSignal; _changeSignal = NULL; } gchar * dlgmessage = g_strdup_printf(_("'%s' working, please wait..."), _effect->get_name()); _visibleDialog = new Gtk::MessageDialog(dlgmessage, false, // use markup Gtk::MESSAGE_INFO, Gtk::BUTTONS_CANCEL, true); // modal _dialogsig = _visibleDialog->signal_response().connect(sigc::mem_fun(this, &ExecutionEnv::workingCanceled)); g_free(dlgmessage); _visibleDialog->show(); _prefsVisible = false; return; } void ExecutionEnv::workingCanceled (const int resp) { processingCancel(); documentCancel(); _finished = true; return; } void ExecutionEnv::preferencesResponse (const int resp) { if (resp == Gtk::RESPONSE_OK) { if (_humanWait && _livePreview) { documentCommit(); _mainloop->quit(); _finished = true; } else { createWorkingDialog(); if (!_livePreview) { _mainloop->quit(); _humanWait = false; } } } 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) { _effect->get_imp()->cancelProcessing(); return; } void ExecutionEnv::documentCancel (void) { _canceled = true; return; } void ExecutionEnv::documentCommit (void) { sp_document_done(_doc->doc(), SP_VERB_NONE, _(_effect->get_name())); Effect::set_last_effect(_effect); _effect->get_imp()->commitDocument(); 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); if (desktop == NULL) { return; } Inkscape::Selection * selection = sp_desktop_selection(desktop); for (std::list::iterator i = _selected.begin(); i != _selected.end(); i++) { SPObject * obj = doc->getObjectById(i->c_str()); if (obj != NULL) { selection->add(obj); } } return; } 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(); } } if (_selfdelete) { delete this; } return; } void ExecutionEnv::livePreview (bool state) { _mainloop->quit(); if (_livePreview && !state) { documentCancel(); _humanWait = true; } if (!_livePreview && state) { _humanWait = false; } _livePreview = state; return; } void ExecutionEnv::shutdown (bool del) { if (_humanWait) { _mainloop->quit(); } else { processingCancel(); } documentCancel(); _finished = true; _shutdown = true; _selfdelete = del; return; } } } /* namespace Inkscape, Extension */ /* Local Variables: mode:c++ c-file-style:"stroustrup" c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +)) indent-tabs-mode:nil fill-column:99 End: */ // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :