index f2f1a0295827e9837d0943b4abc8e9746bcec957..20f0d0b3dec0eee3bbdb72b521418455e875610b 100644 (file)
--- a/src/extension/effect.cpp
+++ b/src/extension/effect.cpp
#include "desktop-handles.h"
#include "selection.h"
#include "sp-namedview.h"
-#include "document.h"
-#include "prefdialog.h"
+#include "desktop.h"
#include "implementation/implementation.h"
#include "effect.h"
+#include "execution-env.h"
#include "timer.h"
-#include "ui/view/view.h"
-#include "gtkmm/messagedialog.h"
-#include "util/glib-list-iterators.h"
/* Inkscape::Extension::Effect */
Effect * Effect::_last_effect = NULL;
Inkscape::XML::Node * Effect::_effects_list = NULL;
+Inkscape::XML::Node * Effect::_filters_list = NULL;
+
+#define EFFECTS_LIST "effects-list"
+#define FILTERS_LIST "filters-list"
Effect::Effect (Inkscape::XML::Node * in_repr, Implementation::Implementation * in_imp)
: Extension(in_repr, in_imp),
_name_noprefs(Glib::ustring(get_name()) + _(" (No preferences)")),
_verb(get_id(), get_name(), NULL, NULL, this, true),
_verb_nopref(_id_noprefs.c_str(), _name_noprefs.c_str(), NULL, NULL, this, false),
- _menu_node(NULL), _workingDialog(true)
+ _menu_node(NULL), _workingDialog(true),
+ _prefDialog(NULL)
{
Inkscape::XML::Node * local_effects_menu = NULL;
bool hidden = false;
no_doc = false;
+ no_live_preview = false;
if (repr != NULL) {
for (Inkscape::XML::Node *child = sp_repr_children(repr); child != NULL; child = child->next()) {
- if (!strcmp(child->name(), "effect")) {
- if (child->attribute("needs-document") && !strcmp(child->attribute("needs-document"), "no")) {
+ if (!strcmp(child->name(), INKSCAPE_EXTENSION_NS "effect")) {
+ if (child->attribute("needs-document") && !strcmp(child->attribute("needs-document"), "false")) {
no_doc = true;
}
+ if (child->attribute("needs-live-preview") && !strcmp(child->attribute("needs-live-preview"), "false")) {
+ no_live_preview = true;
+ }
for (Inkscape::XML::Node *effect_child = sp_repr_children(child); effect_child != NULL; effect_child = effect_child->next()) {
- if (!strcmp(effect_child->name(), "effects-menu")) {
+ if (!strcmp(effect_child->name(), INKSCAPE_EXTENSION_NS "effects-menu")) {
// printf("Found local effects menu in %s\n", this->get_name());
local_effects_menu = sp_repr_children(effect_child);
- if (effect_child->attribute("hidden") && !strcmp(effect_child->attribute("hidden"), "yes")) {
+ if (effect_child->attribute("hidden") && !strcmp(effect_child->attribute("hidden"), "true")) {
hidden = true;
}
}
- if (!strcmp(effect_child->name(), "menu-name") ||
- !strcmp(effect_child->name(), "_menu-name")) {
+ if (!strcmp(effect_child->name(), INKSCAPE_EXTENSION_NS "menu-name") ||
+ !strcmp(effect_child->name(), INKSCAPE_EXTENSION_NS "_menu-name")) {
// printf("Found local effects menu in %s\n", this->get_name());
_verb.set_name(sp_repr_children(effect_child)->content());
}
- if (!strcmp(effect_child->name(), "menu-tip") ||
- !strcmp(effect_child->name(), "_menu-tip")) {
+ if (!strcmp(effect_child->name(), INKSCAPE_EXTENSION_NS "menu-tip") ||
+ !strcmp(effect_child->name(), INKSCAPE_EXTENSION_NS "_menu-tip")) {
// printf("Found local effects menu in %s\n", this->get_name());
_verb.set_tip(sp_repr_children(effect_child)->content());
}
} // children of "inkscape-extension"
} // if we have an XML file
- if (_effects_list == NULL && INKSCAPE != NULL) {
- find_effects_list(inkscape_get_menus(INKSCAPE));
+ if (INKSCAPE != NULL) {
+ if (_effects_list == NULL)
+ _effects_list = find_menu(inkscape_get_menus(INKSCAPE), EFFECTS_LIST);
+ if (_filters_list == NULL)
+ _filters_list = find_menu(inkscape_get_menus(INKSCAPE), FILTERS_LIST);
}
- if (_effects_list != NULL) {
+ if ((_effects_list != NULL || _filters_list != NULL)) {
Inkscape::XML::Document *xml_doc;
xml_doc = _effects_list->document();
_menu_node = xml_doc->createElement("verb");
_menu_node->setAttribute("verb-id", this->get_id(), false);
- if (!hidden)
- merge_menu(_effects_list->parent(), _effects_list, local_effects_menu, _menu_node);
+ if (!hidden) {
+ if (_filters_list &&
+ local_effects_menu &&
+ local_effects_menu->attribute("name") &&
+ !strcmp(local_effects_menu->attribute("name"), _("Filters"))) {
+ merge_menu(_filters_list->parent(), _filters_list, sp_repr_children(local_effects_menu), _menu_node);
+ } else if (_effects_list) {
+ merge_menu(_effects_list->parent(), _effects_list, local_effects_menu, _menu_node);
+ }
+ }
}
return;
if (start != NULL) {
Inkscape::XML::Node * menupass;
- for (menupass = start->next(); menupass != NULL; menupass = menupass->next()) {
+ for (menupass = start; menupass != NULL && strcmp(menupass->name(), "separator"); menupass = menupass->next()) {
gchar const * compare_char = NULL;
if (!strcmp(menupass->name(), "verb")) {
gchar const * verbid = menupass->attribute("verb-id");
Inkscape::Verb * verb = Inkscape::Verb::getbyid(verbid);
if (verb == NULL) {
+ g_warning("Unable to find verb '%s' which is referred to in the menus.", verbid);
continue;
}
compare_char = verb->get_name();
compare_char = menupass->attribute("_name");
}
+ position = menupass->position() + 1;
+
/* This will cause us to skip tags we don't understand */
if (compare_char == NULL) {
continue;
{
if (get_last_effect() == this)
set_last_effect(NULL);
+ if (_menu_node)
+ Inkscape::GC::release(_menu_node);
return;
}
return true;
}
-class ExecutionEnv {
-private:
- Effect * _effect;
- Gtk::Dialog * _visibleDialog;
- bool _prefsVisible;
- bool _finished;
- bool _humanWait;
- bool _canceled;
- bool _prefsChanged;
- Glib::RefPtr<Glib::MainLoop> _mainloop;
- Inkscape::UI::View::View * _doc;
- std::list<Glib::ustring> _selected;
-
-public:
- void run (void);
-
- ExecutionEnv (Effect * effect, Inkscape::UI::View::View * doc, Gtk::Widget * controls = NULL) :
- _effect(effect),
- _visibleDialog(NULL),
- _prefsVisible(false),
- _finished(false),
- _humanWait(false),
- _canceled(false),
- _prefsChanged(false),
- _doc(doc) {
-
- SPDesktop *desktop = (SPDesktop *)_doc;
- sp_namedview_document_from_window(desktop);
-
- if (desktop != NULL) {
- Inkscape::Util::GSListConstIterator<SPItem *> 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 (controls != NULL) {
- createPrefsDialog(controls);
- } else {
- createWorkingDialog();
- }
-
- return;
- }
-
- ~ExecutionEnv (void) {
- if (_visibleDialog != NULL) {
- delete _visibleDialog;
- }
- return;
- }
-
- void preferencesChange (void) {
- //std::cout << "Preferences are a changin'" << std::endl;
- _prefsChanged = true;
- if (_humanWait) {
- _mainloop->quit();
- documentCancel();
- _humanWait = false;
- } else {
- processingCancel();
- documentCancel();
- }
- return;
- }
-
-private:
- void createPrefsDialog (Gtk::Widget * controls) {
- if (_visibleDialog != NULL) {
- delete _visibleDialog;
- }
-
- _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;
- }
-
- void createWorkingDialog (void) {
- if (_visibleDialog != NULL) {
- delete _visibleDialog;
- }
-
- gchar * dlgmessage = g_strdup_printf(_("The effect '%s' is working on your document. Please wait."), _effect->get_name());
- _visibleDialog = new Gtk::MessageDialog(dlgmessage,
- false, // use markup
- Gtk::MESSAGE_INFO,
- Gtk::BUTTONS_CANCEL,
- true); // modal
- _visibleDialog->signal_response().connect(sigc::mem_fun(this, &ExecutionEnv::workingCanceled));
- g_free(dlgmessage);
- _visibleDialog->show();
-
- _prefsVisible = false;
- return;
- }
-
- void workingCanceled (const int resp) {
- processingCancel();
- documentCancel();
- _finished = true;
- return;
- }
-
- void 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 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 processingCancel (void) {
- _effect->get_imp()->cancelProcessing();
- return;
- }
-
- void documentCancel (void) {
- _canceled = true;
- return;
- }
-
- void documentCommit (void) {
- sp_document_done(_doc->doc(), SP_VERB_NONE, _(_effect->get_name()));
- Effect::set_last_effect(_effect);
- return;
- }
-
- void reselect (void) {
- SPDocument * doc = _doc->doc();
-
- SPDesktop *desktop = (SPDesktop *)_doc;
- sp_namedview_document_from_window(desktop);
-
- if (desktop == NULL) { return; }
-
- 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()));
- }
-
- 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();
- }
- }
- return;
-}
-
bool
Effect::prefs (Inkscape::UI::View::View * doc)
{
- if (!loaded())
- set_state(Extension::STATE_LOADED);
- if (!loaded()) return false;
-
- sigc::signal<void> changeSignal;
+ if (_prefDialog != NULL) {
+ _prefDialog->raise();
+ return true;
+ }
- Gtk::Widget * controls;
- controls = imp->prefs_effect(this, doc, &changeSignal);
- if (controls == NULL) {
- // std::cout << "No preferences for Effect" << std::endl;
+ if (param_visible_count() == 0) {
+ effect(doc);
return true;
}
- ExecutionEnv executionEnv(this, doc, controls);
- changeSignal.connect(sigc::mem_fun(executionEnv, &ExecutionEnv::preferencesChange));
+ if (!loaded())
+ set_state(Extension::STATE_LOADED);
+ if (!loaded()) return false;
- timer->lock();
- executionEnv.run();
- timer->unlock();
+ _prefDialog = new PrefDialog(this->get_name(), this->get_help(), NULL, this);
+ _prefDialog->show();
return true;
}
void
Effect::effect (Inkscape::UI::View::View * doc)
{
+ //printf("Execute effect\n");
if (!loaded())
set_state(Extension::STATE_LOADED);
if (!loaded()) return;
- ExecutionEnv executionEnv(this, doc, NULL);
+ ExecutionEnv executionEnv(this, doc);
+ timer->lock();
executionEnv.run();
+ if (executionEnv.wait()) {
+ executionEnv.commit();
+ } else {
+ executionEnv.cancel();
+ }
+ timer->unlock();
return;
}
return;
}
-#define EFFECTS_LIST "effects-list"
-
-bool
-Effect::find_effects_list (Inkscape::XML::Node * menustruct)
+Inkscape::XML::Node *
+Effect::find_menu (Inkscape::XML::Node * menustruct, const gchar *name)
{
if (menustruct == NULL) return false;
for (Inkscape::XML::Node * child = menustruct;
child != NULL;
child = child->next()) {
- if (!strcmp(child->name(), EFFECTS_LIST)) {
- _effects_list = child;
- return true;
+ if (!strcmp(child->name(), name)) {
+ return child;
}
Inkscape::XML::Node * firstchild = child->firstChild();
- if (firstchild != NULL)
- if (find_effects_list(firstchild))
- return true;
+ if (firstchild != NULL) {
+ Inkscape::XML::Node *found = find_menu (firstchild, name);
+ if (found)
+ return found;
+ }
}
- return false;
+ return NULL;
}
+
Gtk::VBox *
Effect::get_info_widget(void)
{
return Extension::get_info_widget();
}
+void
+Effect::set_pref_dialog (PrefDialog * prefdialog)
+{
+ _prefDialog = prefdialog;
+ return;
+}
+
/** \brief Create an action for a \c EffectVerb
\param view Which view the action should be created for
\return The built action.
/** \brief Decode the verb code and take appropriate action */
void
-Effect::EffectVerb::perform (SPAction *action, void * data, void *pdata)
+Effect::EffectVerb::perform( SPAction *action, void * data, void */*pdata*/ )
{
Inkscape::UI::View::View * current_view = sp_action_get_view(action);
// SPDocument * current_document = current_view->doc;