Code

Rework dialog management. Use singleton behavior for dialogs when
[inkscape.git] / src / ui / dialog / livepatheffect-editor.cpp
1 /**
2  * \brief LivePathEffect dialog
3  *
4  * Authors:
5  *   Johan Engelen <j.b.c.engelen@utwente.nl>
6  *
7  * Copyright (C) 2007 Author
8  *
9  * Released under GNU GPL.  Read the file 'COPYING' for more information.
10  */
12 #ifdef HAVE_CONFIG_H
13 # include <config.h>
14 #endif
16 #include <glibmm/i18n.h>
17 #include "livepatheffect-editor.h"
18 #include "verbs.h"
19 #include "selection.h"
20 #include "sp-shape.h"
21 #include "sp-path.h"
22 #include "live_effects/effect.h"
23 #include "live_effects/lpeobject.h"
24 #include "gtkmm/widget.h"
25 #include <vector>
26 #include "inkscape.h"
27 #include "desktop-handles.h"
28 #include "desktop.h"
29 #include "document-private.h"
30 #include "xml/node.h"
31 #include "xml/document.h"
33 namespace Inkscape {
34 class Application;
36 namespace UI {
37 namespace Dialog {
40 /*####################
41  * Callback functions
42  */
43 static void lpeeditor_selection_changed (Inkscape::Selection * selection, gpointer data)
44 {
45     LivePathEffectEditor *lpeeditor = static_cast<LivePathEffectEditor *>(data);
46     lpeeditor->onSelectionChanged(selection);
47 }
49 static void lpeeditor_selection_modified( Inkscape::Selection *selection, guint /*flags*/, gpointer data )
50 {
51     lpeeditor_selection_changed (selection, data);
52 }
55 /*#######################
56  * LivePathEffectEditor
57  */
59 LivePathEffectEditor::LivePathEffectEditor() 
60     : UI::Widget::Panel("", "dialogs.livepatheffect", SP_VERB_DIALOG_LIVE_PATH_EFFECT),
61       combo_effecttype(Inkscape::LivePathEffect::LPETypeConverter),
62       button_apply(_("_Apply"), _("Apply chosen effect to selection")),
63       button_remove(_("_Remove"), _("Remove effect from selection")),
64       effectwidget(NULL),
65       explain_label("", Gtk::ALIGN_CENTER),
66       effectapplication_frame(_("Apply new effect")),
67       effectcontrol_frame(_("Current effect")),
68       current_desktop(NULL)
69 {
70     Gtk::Box *contents = _getContents();
71     contents->set_spacing(4);
73     effectapplication_hbox.set_spacing(4);
74     effectcontrol_vbox.set_spacing(4);
76     effectapplication_hbox.pack_start(combo_effecttype, true, true);
77     effectapplication_hbox.pack_start(button_apply, true, true);
78     effectapplication_frame.add(effectapplication_hbox);
80     effectcontrol_vbox.pack_start(explain_label, true, true);
81     effectcontrol_vbox.pack_end(button_remove, true, true);
82     effectcontrol_frame.add(effectcontrol_vbox);
84     contents->pack_start(effectapplication_frame, true, true);
85     contents->pack_start(effectcontrol_frame, true, true);
87     // connect callback functions to buttons
88     button_apply.signal_clicked().connect(sigc::mem_fun(*this, &LivePathEffectEditor::onApply));
89     button_remove.signal_clicked().connect(sigc::mem_fun(*this, &LivePathEffectEditor::onRemove));
91     show_all_children();
93     button_remove.hide();
94 }
96 LivePathEffectEditor::~LivePathEffectEditor() 
97 {
98     if (effectwidget) {
99         effectcontrol_vbox.remove(*effectwidget);
100         effectwidget = NULL;
101     }
103     if (current_desktop) {
104         selection_changed_connection.disconnect();
105         selection_modified_connection.disconnect();
106     }
109 void
110 LivePathEffectEditor::showParams(LivePathEffect::Effect* effect)
112     if (effectwidget) {
113         effectcontrol_vbox.remove(*effectwidget);
114         effectwidget = NULL;
115     }
117     explain_label.set_markup("<b>" + effect->getName() + "</b>");
118     effectwidget = effect->getWidget();
119     if (effectwidget) {
120         effectcontrol_vbox.pack_start(*effectwidget, true, true);
121     }
122     button_remove.show();
124     effectcontrol_vbox.show_all_children();
125     // fixme: do resizing of dialog 
128 void
129 LivePathEffectEditor::showText(Glib::ustring const &str)
131     if (effectwidget) {
132         effectcontrol_vbox.remove(*effectwidget);
133         effectwidget = NULL;
134     }
136     explain_label.set_label(str);
137     button_remove.hide();
139     // fixme: do resizing of dialog ?
142 void
143 LivePathEffectEditor::set_sensitize_all(bool sensitive)
145     combo_effecttype.set_sensitive(sensitive);
146     button_apply.set_sensitive(sensitive);
147     button_remove.set_sensitive(sensitive);
150 void
151 LivePathEffectEditor::onSelectionChanged(Inkscape::Selection *sel)
153     if ( sel && !sel->isEmpty() ) {
154         SPItem *item = sel->singleItem();
155         if ( item ) {
156             if ( SP_IS_SHAPE(item) ) {
157                 SPShape *shape = SP_SHAPE(item);
158                 LivePathEffectObject *lpeobj = sp_shape_get_livepatheffectobject(shape);
159                 set_sensitize_all(true);
160                 if (lpeobj) {
161                     if (lpeobj->lpe) {
162                         showParams(lpeobj->lpe);
163                     } else {
164                         showText(_("Unknown effect is applied"));
165                     }
166                 } else {
167                     showText(_("No effect applied"));
168                     button_remove.set_sensitive(false);
169                 }
170             } else {
171                 showText(_("Item is not a shape or path"));
172                 set_sensitize_all(false);
173             }
174         } else {
175             showText(_("Only one item can be selected"));
176             set_sensitize_all(false);
177         }
178     } else {
179         showText(_("Empty selection"));
180         set_sensitize_all(false);
181     }
184 void 
185 LivePathEffectEditor::setDesktop(SPDesktop *desktop)
187     Panel::setDesktop(desktop);
189     if ( desktop == current_desktop ) {
190         return;
191     }
193     if (current_desktop) {
194         selection_changed_connection.disconnect();
195         selection_modified_connection.disconnect();
196     }
198     current_desktop = desktop;
199     if (desktop) {
200         Inkscape::Selection *selection = sp_desktop_selection(desktop);
201         selection_changed_connection = selection->connectChanged(
202             sigc::bind (sigc::ptr_fun(&lpeeditor_selection_changed), this ) );
203         selection_modified_connection = selection->connectModified(
204             sigc::bind (sigc::ptr_fun(&lpeeditor_selection_modified), this ) );
206         onSelectionChanged(selection);
207     } else {
208         onSelectionChanged(NULL);
209     }
215 /*########################################################################
216 # BUTTON CLICK HANDLERS    (callbacks)
217 ########################################################################*/
219 // TODO:  factor out the effect applying code which can be called from anywhere. (selection-chemistry.cpp also needs it)
221 void
222 LivePathEffectEditor::onApply()
224     Inkscape::Selection *sel = _getSelection();
225     if ( sel && !sel->isEmpty() ) {
226         SPItem *item = sel->singleItem();
227         if ( item && SP_IS_SHAPE(item) ) {
228             SPDocument *doc = current_desktop->doc();
230             const Util::EnumData<LivePathEffect::EffectType>* data = combo_effecttype.get_active_data();
231             if (!data) return;
233             Inkscape::XML::Document *xml_doc = sp_document_repr_doc(doc);
234             Inkscape::XML::Node *repr = xml_doc->createElement("inkscape:path-effect");
235             repr->setAttribute("effect", data->key.c_str() );
237             SP_OBJECT_REPR(SP_DOCUMENT_DEFS(doc))->addChild(repr, NULL); // adds to <defs> and assigns the 'id' attribute
238             const gchar * repr_id = repr->attribute("id");
239             Inkscape::GC::release(repr);
241             gchar *href = g_strdup_printf("#%s", repr_id);
242             sp_shape_set_path_effect(SP_SHAPE(item), href);
243             g_free(href);
245             // make sure there is an original-d for paths!!!
246             if ( SP_IS_PATH(item) ) {
247                 Inkscape::XML::Node *pathrepr = SP_OBJECT_REPR(item);
248                 if ( ! pathrepr->attribute("inkscape:original-d") ) {
249                     pathrepr->setAttribute("inkscape:original-d", pathrepr->attribute("d"));
250                 }
251             }
253             LivePathEffectObject *lpeobj = sp_shape_get_livepatheffectobject(SP_SHAPE(item));
254             if (lpeobj && lpeobj->lpe) {
255                 lpeobj->lpe->resetDefaults(item);
256             }
258             sp_document_done(doc, SP_VERB_DIALOG_LIVE_PATH_EFFECT, 
259                              _("Create and apply path effect"));
260         }
261     }
264 void
265 LivePathEffectEditor::onRemove()
267     Inkscape::Selection *sel = _getSelection();
268     if ( sel && !sel->isEmpty() ) {
269         SPItem *item = sel->singleItem();
270         if ( item && SP_IS_SHAPE(item) ) {
271             sp_shape_remove_path_effect(SP_SHAPE(item));
272             sp_document_done ( sp_desktop_document (current_desktop), SP_VERB_DIALOG_LIVE_PATH_EFFECT, 
273                                _("Remove path effect") );
274         }
275     }
280 } // namespace Dialog
281 } // namespace UI
282 } // namespace Inkscape