Code

Prevent localized doubles from being written into filter matrices
[inkscape.git] / src / ui / dialog / filter-effects-dialog.cpp
index 98951f28c4c25755d75f9f784e7b72ab069be069..3fbb3663d86d27bbf1dfcbfd1c970b8a062e1d6a 100644 (file)
@@ -1,10 +1,12 @@
-/**
- * \brief Filter Effects dialog
- *
- * Authors:
+/** @file
+ * @brief Filter Effects dialog
+ */
+/* Authors:
  *   Nicholas Bishop <nicholasbishop@gmail.org>
  *   Rodrigo Kumpera <kumpera@gmail.com>
- *   Felipe C. da S. Sanches <felipe.sanches@gmail.com>
+ *   Felipe C. da S. Sanches <juca@members.fsf.org>
+ *   Jon A. Cruz <jon@joncruz.org>
+ *   Abhishek Sharma
  *
  * Copyright (C) 2007 Authors
  *
@@ -15,7 +17,7 @@
 # include <config.h>
 #endif
 
-#include <gtk/gtktreeview.h>
+#include <gtk/gtk.h>
 #include <gtkmm/cellrenderertext.h>
 #include <gtkmm/colorbutton.h>
 #include <gtkmm/messagedialog.h>
@@ -27,8 +29,6 @@
 #include <gtkmm/tooltips.h>
 #include <glibmm/i18n.h>
 
-#include "application/application.h"
-#include "application/editor.h"
 #include "desktop.h"
 #include "desktop-handles.h"
 #include "dialog-manager.h"
 #include "filter-enums.h"
 #include "inkscape.h"
 #include "path-prefix.h"
-#include "prefs-utils.h"
+#include "preferences.h"
 #include "selection.h"
-#include "sp-feblend.h"
-#include "sp-fecolormatrix.h"
-#include "sp-fecomponenttransfer.h"
-#include "sp-fecomposite.h"
-#include "sp-feconvolvematrix.h"
-#include "sp-fedisplacementmap.h"
-#include "sp-fedistantlight.h"
-#include "sp-femerge.h"
-#include "sp-femergenode.h"
-#include "sp-feoffset.h"
-#include "sp-fepointlight.h"
-#include "sp-fespotlight.h"
+#include "filters/blend.h"
+#include "filters/colormatrix.h"
+#include "filters/componenttransfer.h"
+#include "filters/composite.h"
+#include "filters/convolvematrix.h"
+#include "filters/displacementmap.h"
+#include "filters/distantlight.h"
+#include "filters/merge.h"
+#include "filters/mergenode.h"
+#include "filters/offset.h"
+#include "filters/pointlight.h"
+#include "filters/spotlight.h"
 #include "sp-filter-primitive.h"
 #include "sp-gaussian-blur.h"
 
 #include "style.h"
 #include "svg/svg-color.h"
+#include "svg/stringstream.h"
 #include "ui/dialog/filedialog.h"
 #include "verbs.h"
 #include "xml/node.h"
 #include "io/sys.h"
 #include <iostream>
 
-using namespace NR;
+using namespace Inkscape::Filters;
 
 namespace Inkscape {
 namespace UI {
 namespace Dialog {
 
+using Inkscape::UI::Widget::AttrWidget;
+using Inkscape::UI::Widget::ComboBoxEnum;
+using Inkscape::UI::Widget::DualSpinSlider;
+using Inkscape::UI::Widget::SpinSlider;
+
+
 // Returns the number of inputs available for the filter primitive type
 int input_count(const SPFilterPrimitive* prim)
 {
@@ -84,55 +91,13 @@ int input_count(const SPFilterPrimitive* prim)
     else if(SP_IS_FEMERGE(prim)) {
         // Return the number of feMergeNode connections plus an extra
         int count = 1;
-        for(const SPObject* o = prim->firstChild(); o; o = o->next, ++count);
+        for(const SPObject* o = prim->firstChild(); o; o = o->next, ++count){};
         return count;
     }
     else
         return 1;
 }
 
-// Very simple observer that just emits a signal if anything happens to a node
-class FilterEffectsDialog::SignalObserver : public XML::NodeObserver
-{
-public:
-    SignalObserver()
-        : _oldsel(0)
-    {}
-
-    // Add this observer to the SPObject and remove it from any previous object
-    void set(SPObject* o)
-    {
-        if(_oldsel && _oldsel->repr)
-            _oldsel->repr->removeObserver(*this);
-        if(o && o->repr)
-            o->repr->addObserver(*this);
-        _oldsel = o;
-    }
-
-    void notifyChildAdded(XML::Node&, XML::Node&, XML::Node*)
-    { signal_changed()(); }
-
-    void notifyChildRemoved(XML::Node&, XML::Node&, XML::Node*)
-    { signal_changed()(); }
-
-    void notifyChildOrderChanged(XML::Node&, XML::Node&, XML::Node*, XML::Node*)
-    { signal_changed()(); }
-
-    void notifyContentChanged(XML::Node&, Util::ptr_shared<char>, Util::ptr_shared<char>)
-    {}
-
-    void notifyAttributeChanged(XML::Node&, GQuark, Util::ptr_shared<char>, Util::ptr_shared<char>)
-    { signal_changed()(); }
-
-    sigc::signal<void>& signal_changed()
-    {
-        return _signal_changed;
-    }
-private:
-    sigc::signal<void> _signal_changed;
-    SPObject* _oldsel;
-};
-
 class CheckButtonAttr : public Gtk::CheckButton, public AttrWidget
 {
 public:
@@ -178,7 +143,7 @@ public:
     {
         if (tip_text) _tt.set_tip(*this, tip_text);
         set_range(lower, upper);
-        set_increments(step_inc, step_inc * 5);
+        set_increments(step_inc, 0);
 
         signal_value_changed().connect(signal_attr_changed().make_slot());
     }
@@ -209,17 +174,19 @@ template< typename T> class ComboWithTooltip : public Gtk::EventBox
 public:
     ComboWithTooltip<T>(T default_value, const Util::EnumDataConverter<T>& c, const SPAttributeEnum a = SP_ATTR_INVALID, char* tip_text = NULL)
     {
-        if (tip_text) _tt.set_tip(*this, tip_text);
-        combo = new ComboBoxEnum<T>(default_value, c, a);
+        if (tip_text) {
+            _tt.set_tip(*this, tip_text);
+        }
+        combo = new ComboBoxEnum<T>(default_value, c, a, false);
         add(*combo);
         show_all();
     }
-    
+
     ~ComboWithTooltip()
     {
         delete combo;
     }
-    
+
     ComboBoxEnum<T>* get_attrwidget()
     {
         return combo;
@@ -271,8 +238,8 @@ public:
         if (tt2) _tt.set_tip(_s2, tt2);
         _s1.set_range(lower, upper);
         _s2.set_range(lower, upper);
-        _s1.set_increments(step_inc, step_inc * 5);
-        _s2.set_increments(step_inc, step_inc * 5);
+        _s1.set_increments(step_inc, 0);
+        _s2.set_increments(step_inc, 0);
 
         _s1.signal_value_changed().connect(signal_attr_changed().make_slot());
         _s2.signal_value_changed().connect(signal_attr_changed().make_slot());
@@ -315,7 +282,7 @@ public:
         }
         _s1.set_value(n.getNumber());
         _s2.set_value(n.getOptNumber());
-        
+
     }
 private:
     Gtk::SpinButton _s1, _s2;
@@ -338,6 +305,7 @@ public:
     // Returns the color in 'rgb(r,g,b)' form.
     Glib::ustring get_as_attribute() const
     {
+        // no doubles here, so we can use the standard string stream.
         std::ostringstream os;
         const Gdk::Color c = get_color();
         const int r = c.get_red() / 257, g = c.get_green() / 257, b = c.get_blue() / 257;//TO-DO: verify this. This sounds a lot strange! shouldn't it be 256?
@@ -405,7 +373,8 @@ public:
 
     Glib::ustring get_as_attribute() const
     {
-        std::ostringstream os;
+        // use SVGOStringStream to output SVG-compatible doubles
+        Inkscape::SVGOStringStream os;
 
         for(Gtk::TreeIter iter = _model->children().begin();
             iter != _model->children().end(); ++iter) {
@@ -501,7 +470,8 @@ class FilterEffectsDialog::ColorMatrixValues : public Gtk::Frame, public AttrWid
 public:
     ColorMatrixValues()
         : AttrWidget(SP_ATTR_VALUES),
-          _matrix(SP_ATTR_VALUES, _("This matrix determines a linear transform on colour space. Each line affects one of the color components. Each column determines how much of each color component from the input is passed to the output. The last column does not depend on input colors, so can be used to adjust a constant component value.")),
+          // TRANSLATORS: this dialog is accessible via menu Filters - Filter editor
+          _matrix(SP_ATTR_VALUES, _("This matrix determines a linear transform on color space. Each line affects one of the color components. Each column determines how much of each color component from the input is passed to the output. The last column does not depend on input colors, so can be used to adjust a constant component value.")),
           _saturation(0, 0, 1, 0.1, 0.01, 2, SP_ATTR_VALUES),
           _angle(0, 0, 360, 0.1, 0.01, 1, SP_ATTR_VALUES),
           _label(_("None"), Gtk::ALIGN_LEFT),
@@ -659,9 +629,10 @@ private:
     void select_file(){
 
         //# Get the current directory for finding files
+        Inkscape::Preferences *prefs = Inkscape::Preferences::get();
         Glib::ustring open_path;
-        char *attr = (char *)prefs_get_string_attribute("dialogs.open", "path");
-        if (attr)
+        Glib::ustring attr = prefs->getString("/dialogs/open/path");
+        if (!attr.empty())
             open_path = attr;
 
         //# Test if the open_path directory exists
@@ -682,7 +653,7 @@ private:
                   Inkscape::UI::Dialog::FileOpenDialog::create(
                      *_desktop->getToplevel(),
                      open_path,
-                     Inkscape::UI::Dialog::SVG_TYPES,/*TODO: any image, not justy svg*/
+                     Inkscape::UI::Dialog::SVG_TYPES,/*TODO: any image, not just svg*/
                      (char const *)_("Select an image to be used as feImage input"));
         }
 
@@ -705,7 +676,7 @@ private:
 
             open_path = fileName;
             open_path.append(G_DIR_SEPARATOR_S);
-            prefs_set_string_attribute("dialogs.open", "path", open_path.c_str());
+            prefs->setString("/dialogs/open/path", open_path);
 
             _entry.set_text(fileName);
         }
@@ -869,7 +840,7 @@ public:
         std::vector<double> default_values;
         default_values.push_back(def1);
         default_values.push_back(def2);
-        
+
         std::vector<char*> tips;
         tips.push_back(tip1);
         tips.push_back(tip2);
@@ -944,7 +915,8 @@ private:
         hb->set_spacing(12);
 
         if(label != "") {
-            lbl = Gtk::manage(new Gtk::Label(label + (label == "" ? "" : ":"), Gtk::ALIGN_LEFT));
+            //lbl = Gtk::manage(new Gtk::Label(label + (label == "" ? "" : ":"), Gtk::ALIGN_LEFT)); colon now in label (LP #358921)
+            lbl = Gtk::manage(new Gtk::Label(label, Gtk::ALIGN_LEFT));
             hb->pack_start(*lbl, false, false);
             _size_group->add_widget(*lbl);
             lbl->show();
@@ -1054,15 +1026,18 @@ private:
                !(ls == 1 && SP_IS_FEPOINTLIGHT(child)) &&
                !(ls == 2 && SP_IS_FESPOTLIGHT(child))) {
                 if(child)
-                    sp_repr_unparent(child->repr);
+                    //XML Tree being used directly here while it shouldn't be.
+                    sp_repr_unparent(child->getRepr());
 
                 if(ls != -1) {
-                    Inkscape::XML::Document *xml_doc = sp_document_repr_doc(prim->document);
+                    Inkscape::XML::Document *xml_doc = prim->document->getReprDoc();
                     Inkscape::XML::Node *repr = xml_doc->createElement(_light_source.get_active_data()->key.c_str());
-                    prim->repr->appendChild(repr);
+                    //XML Tree being used directly here while it shouldn't be.
+                    prim->getRepr()->appendChild(repr);
+                    Inkscape::GC::release(repr);
                 }
 
-                sp_document_done(prim->document, SP_VERB_DIALOG_FILTER_EFFECTS, _("New light source"));
+                DocumentUndo::done(prim->document, SP_VERB_DIALOG_FILTER_EFFECTS, _("New light source"));
                 update();
             }
 
@@ -1115,7 +1090,7 @@ Glib::RefPtr<Gtk::Menu> create_popup_menu(Gtk::Widget& parent, sigc::slot<void>
 
 /*** FilterModifier ***/
 FilterEffectsDialog::FilterModifier::FilterModifier(FilterEffectsDialog& d)
-    : _dialog(d), _add(Gtk::Stock::NEW), _observer(new SignalObserver)
+    : _dialog(d), _add(Gtk::Stock::NEW), _observer(new Inkscape::XML::SignalObserver)
 {
     Gtk::ScrolledWindow* sw = Gtk::manage(new Gtk::ScrolledWindow);
     pack_start(*sw);
@@ -1153,6 +1128,8 @@ FilterEffectsDialog::FilterModifier::FilterModifier(FilterEffectsDialog& d)
 
     g_signal_connect(G_OBJECT(INKSCAPE), "activate_desktop",
                      G_CALLBACK(&FilterModifier::on_activate_desktop), this);
+    g_signal_connect(G_OBJECT(INKSCAPE), "deactivate_desktop",
+                     G_CALLBACK(&FilterModifier::on_deactivate_desktop), this);
 
     on_activate_desktop(INKSCAPE, d.getDesktop(), this);
     update_filters();
@@ -1172,14 +1149,20 @@ void FilterEffectsDialog::FilterModifier::on_activate_desktop(Application*, SPDe
 
     me->_resource_changed.disconnect();
     me->_resource_changed =
-        sp_document_resources_changed_connect(sp_desktop_document(desktop), "filter",
-                                              sigc::mem_fun(me, &FilterModifier::update_filters));
+        sp_desktop_document(desktop)->connectResourcesChanged("filter",sigc::mem_fun(me, &FilterModifier::update_filters));
 
     me->_dialog.setDesktop(desktop);
 
     me->update_filters();
 }
 
+void FilterEffectsDialog::FilterModifier::on_deactivate_desktop(Application*, SPDesktop* /*desktop*/, FilterModifier* me)
+{
+    me->_doc_replaced.disconnect();
+    me->_resource_changed.disconnect();
+    me->_dialog.setDesktop(NULL);
+}
+
 
 // When the selection changes, show the active filter(s) in the dialog
 void FilterEffectsDialog::FilterModifier::on_inkscape_change_selection(Application */*inkscape*/,
@@ -1237,7 +1220,7 @@ void FilterEffectsDialog::FilterModifier::on_name_edited(const Glib::ustring& pa
     if(iter) {
         SPFilter* filter = (*iter)[_columns.filter];
         filter->setLabel(text.c_str());
-        sp_document_done(filter->document, SP_VERB_DIALOG_FILTER_EFFECTS, _("Rename filter"));
+        DocumentUndo::done(filter->document, SP_VERB_DIALOG_FILTER_EFFECTS, _("Rename filter"));
         if(iter)
             (*iter)[_columns.label] = text;
     }
@@ -1273,7 +1256,7 @@ void FilterEffectsDialog::FilterModifier::on_selection_toggled(const Glib::ustri
         }
 
         update_selection(sel);
-        sp_document_done(doc, SP_VERB_DIALOG_FILTER_EFFECTS,  _("Apply filter"));
+        DocumentUndo::done(doc, SP_VERB_DIALOG_FILTER_EFFECTS,  _("Apply filter"));
     }
 }
 
@@ -1283,7 +1266,7 @@ void FilterEffectsDialog::FilterModifier::update_filters()
 {
     SPDesktop* desktop = _dialog.getDesktop();
     SPDocument* document = sp_desktop_document(desktop);
-    const GSList* filters = sp_document_get_resource_list(document, "filter");
+    const GSList* filters = document->getResourceList("filter");
 
     _model->clear();
 
@@ -1292,7 +1275,7 @@ void FilterEffectsDialog::FilterModifier::update_filters()
         SPFilter* f = (SPFilter*)l->data;
         row[_columns.filter] = f;
         const gchar* lbl = f->label();
-        const gchar* id = SP_OBJECT_ID(f);
+        const gchar* id = f->getId();
         row[_columns.label] = lbl ? lbl : (id ? id : "filter");
     }
 
@@ -1342,14 +1325,14 @@ void FilterEffectsDialog::FilterModifier::add_filter()
 
     const int count = _model->children().size();
     std::ostringstream os;
-    os << "filter" << count;
+    os << _("filter") << count;
     filter->setLabel(os.str().c_str());
 
     update_filters();
 
     select_filter(filter);
 
-    sp_document_done(doc, SP_VERB_DIALOG_FILTER_EFFECTS, _("Add filter"));
+    DocumentUndo::done(doc, SP_VERB_DIALOG_FILTER_EFFECTS, _("Add filter"));
 }
 
 void FilterEffectsDialog::FilterModifier::remove_filter()
@@ -1358,9 +1341,11 @@ void FilterEffectsDialog::FilterModifier::remove_filter()
 
     if(filter) {
         SPDocument* doc = filter->document;
-        sp_repr_unparent(filter->repr);
 
-        sp_document_done(doc, SP_VERB_DIALOG_FILTER_EFFECTS, _("Remove filter"));
+        //XML Tree being used directly here while it shouldn't be.
+        sp_repr_unparent(filter->getRepr());
+
+        DocumentUndo::done(doc, SP_VERB_DIALOG_FILTER_EFFECTS, _("Remove filter"));
 
         update_filters();
     }
@@ -1375,7 +1360,7 @@ void FilterEffectsDialog::FilterModifier::duplicate_filter()
         repr = repr->duplicate(repr->document());
         parent->appendChild(repr);
 
-        sp_document_done(filter->document, SP_VERB_DIALOG_FILTER_EFFECTS, _("Duplicate filter"));
+        DocumentUndo::done(filter->document, SP_VERB_DIALOG_FILTER_EFFECTS, _("Duplicate filter"));
 
         update_filters();
     }
@@ -1430,7 +1415,7 @@ void FilterEffectsDialog::CellRendererConnection::get_size_vfunc(
 FilterEffectsDialog::PrimitiveList::PrimitiveList(FilterEffectsDialog& d)
     : _dialog(d),
       _in_drag(0),
-      _observer(new SignalObserver)
+      _observer(new Inkscape::XML::SignalObserver)
 {
     d.signal_expose_event().connect(sigc::mem_fun(*this, &PrimitiveList::on_expose_signal));
 
@@ -1467,7 +1452,7 @@ int FilterEffectsDialog::PrimitiveList::init_text()
     _vertical_layout = Pango::Layout::create(context);
 
     int maxfont = 0;
-    for(int i = 0; i < FPInputConverter.end; ++i) {
+    for(unsigned int i = 0; i < FPInputConverter._length; ++i) {
         _vertical_layout->set_text(_(FPInputConverter.get_label((FilterPrimitiveInput)i).c_str()));
         int fontw, fonth;
         _vertical_layout->get_pixel_size(fontw, fonth);
@@ -1510,9 +1495,11 @@ void FilterEffectsDialog::PrimitiveList::update()
             if(prim) {
                 Gtk::TreeModel::Row row = *_model->append();
                 row[_columns.primitive] = prim;
-                row[_columns.type_id] = FPConverter.get_id_from_key(prim->repr->name());
+
+                //XML Tree being used directly here while it shouldn't be.
+                row[_columns.type_id] = FPConverter.get_id_from_key(prim->getRepr()->name());
                 row[_columns.type] = _(FPConverter.get_label(row[_columns.type_id]).c_str());
-                row[_columns.id] = SP_OBJECT_ID(prim);
+                row[_columns.id] = prim->getId();
 
                 if(prim == active_prim) {
                     get_selection()->select(row);
@@ -1563,10 +1550,11 @@ void FilterEffectsDialog::PrimitiveList::remove_selected()
     if(prim) {
         _observer->set(0);
 
-        sp_repr_unparent(prim->repr);
+        //XML Tree being used directly here while it shouldn't be.
+        sp_repr_unparent(prim->getRepr());
 
-        sp_document_done(sp_desktop_document(_dialog.getDesktop()), SP_VERB_DIALOG_FILTER_EFFECTS,
-                         _("Remove filter primitive"));
+        DocumentUndo::done(sp_desktop_document(_dialog.getDesktop()), SP_VERB_DIALOG_FILTER_EFFECTS,
+                           _("Remove filter primitive"));
 
         update();
     }
@@ -1591,8 +1579,8 @@ bool FilterEffectsDialog::PrimitiveList::on_expose_signal(GdkEventExpose* e)
         int vis_x, vis_y;
         tree_to_widget_coords(vis.get_x(), vis.get_y(), vis_x, vis_y);
 
-        text_start_x = rct.get_x() + rct.get_width() - _connection_cell.get_text_width() * (FPInputConverter.end + 1) + 1;
-        for(int i = 0; i < FPInputConverter.end; ++i) {
+        text_start_x = rct.get_x() + rct.get_width() - _connection_cell.get_text_width() * (FPInputConverter._length + 1) + 1;
+        for(unsigned int i = 0; i < FPInputConverter._length; ++i) {
             _vertical_layout->set_text(_(FPInputConverter.get_label((FilterPrimitiveInput)i).c_str()));
             const int x = text_start_x + _connection_cell.get_text_width() * (i + 1);
             get_bin_window()->draw_rectangle(get_style()->get_bg_gc(Gtk::STATE_NORMAL), true, x, vis_y, _connection_cell.get_text_width(), vis.get_height());
@@ -1808,7 +1796,7 @@ int FilterEffectsDialog::PrimitiveList::find_index(const Gtk::TreeIter& target)
 {
     int i = 0;
     for(Gtk::TreeIter iter = _model->children().begin();
-        iter != target; ++iter, ++i);
+        iter != target; ++iter, ++i){};
     return i;
 }
 
@@ -1898,13 +1886,14 @@ bool FilterEffectsDialog::PrimitiveList::on_button_release_event(GdkEventButton*
             Gdk::Rectangle rct;
             get_cell_area(path, *col, rct);
             const int twidth = _connection_cell.get_text_width();
-            const int sources_x = rct.get_width() - twidth * FPInputConverter.end;
+            const int sources_x = rct.get_width() - twidth * FPInputConverter._length;
             if(cx > sources_x) {
                 int src = (cx - sources_x) / twidth;
-                if(src < 0)
+                if (src < 0) {
                     src = 0;
-                else if(src >= FPInputConverter.end)
-                    src = FPInputConverter.end - 1;
+                } else if(src >= static_cast<int>(FPInputConverter._length)) {
+                    src = FPInputConverter._length - 1;
+                }
                 result = FPInputConverter.get_key((FilterPrimitiveInput)src);
                 in_val = result.c_str();
             }
@@ -1935,9 +1924,11 @@ bool FilterEffectsDialog::PrimitiveList::on_button_release_event(GdkEventButton*
                     if(c == _in_drag && SP_IS_FEMERGENODE(o)) {
                         // If input is null, delete it
                         if(!in_val) {
-                            sp_repr_unparent(o->repr);
-                            sp_document_done(prim->document, SP_VERB_DIALOG_FILTER_EFFECTS,
-                                             _("Remove merge node"));
+
+                            //XML Tree being used directly here while it shouldn't be.
+                            sp_repr_unparent(o->getRepr());
+                            DocumentUndo::done(prim->document, SP_VERB_DIALOG_FILTER_EFFECTS,
+                                               _("Remove merge node"));
                             (*get_selection()->get_selected())[_columns.primitive] = prim;
                         }
                         else
@@ -1947,10 +1938,12 @@ bool FilterEffectsDialog::PrimitiveList::on_button_release_event(GdkEventButton*
                 }
                 // Add new input?
                 if(!handled && c == _in_drag && in_val) {
-                    Inkscape::XML::Document *xml_doc = sp_document_repr_doc(prim->document);
+                    Inkscape::XML::Document *xml_doc = prim->document->getReprDoc();
                     Inkscape::XML::Node *repr = xml_doc->createElement("svg:feMergeNode");
                     repr->setAttribute("inkscape:collect", "always");
-                    prim->repr->appendChild(repr);
+
+                    //XML Tree being used directly here while it shouldn't be.
+                    prim->getRepr()->appendChild(repr);
                     SPFeMergeNode *node = SP_FEMERGENODE(prim->document->getObjectByRepr(repr));
                     Inkscape::GC::release(repr);
                     _dialog.set_attr(node, SP_ATTR_IN, in_val);
@@ -2053,7 +2046,7 @@ void FilterEffectsDialog::PrimitiveList::on_drag_end(const Glib::RefPtr<Gdk::Dra
 
     filter->requestModified(SP_OBJECT_MODIFIED_FLAG);
 
-    sp_document_done(filter->document, SP_VERB_DIALOG_FILTER_EFFECTS, _("Reorder filter primitive"));
+    DocumentUndo::done(filter->document, SP_VERB_DIALOG_FILTER_EFFECTS, _("Reorder filter primitive"));
 }
 
 // If a connection is dragged towards the top or bottom of the list, the list should scroll to follow.
@@ -2085,16 +2078,16 @@ int FilterEffectsDialog::PrimitiveList::primitive_count() const
 /*** FilterEffectsDialog ***/
 
 FilterEffectsDialog::FilterEffectsDialog()
-    : UI::Widget::Panel("", "dialogs.filtereffects", SP_VERB_DIALOG_FILTER_EFFECTS),
-      _filter_modifier(*this),
-      _primitive_list(*this),
+    : UI::Widget::Panel("", "/dialogs/filtereffects", SP_VERB_DIALOG_FILTER_EFFECTS),
       _add_primitive_type(FPConverter),
       _add_primitive(_("Add Effect:")),
       _empty_settings(_("No effect selected"), Gtk::ALIGN_LEFT),
       _no_filter_selected(_("No filter selected"), Gtk::ALIGN_LEFT),
       _settings_initialized(false),
       _locked(false),
-      _attr_lock(false)
+      _attr_lock(false),
+      _filter_modifier(*this),
+      _primitive_list(*this)
 {
     _settings = new Settings(*this, _settings_tab1, sigc::mem_fun(*this, &FilterEffectsDialog::set_attr_direct),
                              NR_FILTER_ENDPRIMITIVETYPE);
@@ -2178,91 +2171,91 @@ void FilterEffectsDialog::init_settings_widgets()
 
     _empty_settings.set_sensitive(false);
     _settings_tab1.pack_start(_empty_settings);
-    
+
     _no_filter_selected.set_sensitive(false);
     _settings_tab2.pack_start(_no_filter_selected);
     _settings_initialized = true;
 
     _filter_general_settings->type(0);
-    _filter_general_settings->add_multispinbutton(/*default x:*/ (double) -0.1, /*default y:*/ (double) -0.1, SP_ATTR_X, SP_ATTR_Y, _("Coordinates"), -100, 100, 0.01, 0.1, 2, _("X coordinate of the left corners of filter effects region"), _("Y coordinate of the upper corners of filter effects region"));
-    _filter_general_settings->add_multispinbutton(/*default width:*/ (double) 1.2, /*default height:*/ (double) 1.2, SP_ATTR_WIDTH, SP_ATTR_HEIGHT, _("Dimensions"), 0, 1000, 0.01, 0.1, 2, _("Width of filter effects region"), _("Height of filter effects region"));
+    _filter_general_settings->add_multispinbutton(/*default x:*/ (double) -0.1, /*default y:*/ (double) -0.1, SP_ATTR_X, SP_ATTR_Y, _("Coordinates:"), -100, 100, 0.01, 0.1, 2, _("X coordinate of the left corners of filter effects region"), _("Y coordinate of the upper corners of filter effects region"));
+    _filter_general_settings->add_multispinbutton(/*default width:*/ (double) 1.2, /*default height:*/ (double) 1.2, SP_ATTR_WIDTH, SP_ATTR_HEIGHT, _("Dimensions:"), 0, 1000, 0.01, 0.1, 2, _("Width of filter effects region"), _("Height of filter effects region"));
 
     _settings->type(NR_FILTER_BLEND);
-    _settings->add_combo(BLEND_NORMAL, SP_ATTR_MODE, _("Mode"), BlendModeConverter);
+    _settings->add_combo(BLEND_NORMAL, SP_ATTR_MODE, _("Mode:"), BlendModeConverter);
 
     _settings->type(NR_FILTER_COLORMATRIX);
-    ComboBoxEnum<FilterColorMatrixType>* colmat = _settings->add_combo(COLORMATRIX_MATRIX, SP_ATTR_TYPE, _("Type"), ColorMatrixTypeConverter, _("Indicates the type of matrix operation. The keyword 'matrix' indicates that a full 5x4 matrix of values will be provided. The other keywords represent convenience shortcuts to allow commonly used color operations to be performed without specifying a complete matrix."));
-    _color_matrix_values = _settings->add_colormatrixvalues(_("Value(s)"));
+    ComboBoxEnum<FilterColorMatrixType>* colmat = _settings->add_combo(COLORMATRIX_MATRIX, SP_ATTR_TYPE, _("Type:"), ColorMatrixTypeConverter, _("Indicates the type of matrix operation. The keyword 'matrix' indicates that a full 5x4 matrix of values will be provided. The other keywords represent convenience shortcuts to allow commonly used color operations to be performed without specifying a complete matrix."));
+    _color_matrix_values = _settings->add_colormatrixvalues(_("Value(s):"));
     colmat->signal_attr_changed().connect(sigc::mem_fun(*this, &FilterEffectsDialog::update_color_matrix));
 
     _settings->type(NR_FILTER_COMPONENTTRANSFER);
     _settings->add_notimplemented();
+    /*
     //TRANSLATORS: for info on "Slope" and "Intercept", see http://id.mind.net/~zona/mmts/functionInstitute/linearFunctions/lsif.html
-    /*_settings->add_combo(COMPONENTTRANSFER_TYPE_IDENTITY, SP_ATTR_TYPE, _("Type"), ComponentTransferTypeConverter);
-    _ct_slope = _settings->add_spinslider(SP_ATTR_SLOPE, _("Slope"), -100, 100, 1, 0.01, 1);
-    _ct_intercept = _settings->add_spinslider(SP_ATTR_INTERCEPT, _("Intercept"), -100, 100, 1, 0.01, 1);
-    _ct_amplitude = _settings->add_spinslider(SP_ATTR_AMPLITUDE, _("Amplitude"), 0, 100, 1, 0.01, 1);
-    _ct_exponent = _settings->add_spinslider(SP_ATTR_EXPONENT, _("Exponent"), 0, 100, 1, 0.01, 1);
-    _ct_offset = _settings->add_spinslider(SP_ATTR_OFFSET, _("Offset"), -100, 100, 1, 0.01, 1);*/
+    _settings->add_combo(COMPONENTTRANSFER_TYPE_IDENTITY, SP_ATTR_TYPE, _("Type"), ComponentTransferTypeConverter);
+    _ct_slope = _settings->add_spinslider(1, SP_ATTR_SLOPE, _("Slope"), -10, 10, 0.1, 0.01, 2);
+    _ct_intercept = _settings->add_spinslider(0, SP_ATTR_INTERCEPT, _("Intercept"), -10, 10, 0.1, 0.01, 2);
+    _ct_amplitude = _settings->add_spinslider(1, SP_ATTR_AMPLITUDE, _("Amplitude"), 0, 10, 0.1, 0.01, 2);
+    _ct_exponent = _settings->add_spinslider(1, SP_ATTR_EXPONENT, _("Exponent"), 0, 10, 0.1, 0.01, 2);
+    _ct_offset = _settings->add_spinslider(0, SP_ATTR_OFFSET, _("Offset"), -10, 10, 0.1, 0.01, 2);*/
 
     _settings->type(NR_FILTER_COMPOSITE);
-    _settings->add_combo(COMPOSITE_OVER, SP_ATTR_OPERATOR, _("Operator"), CompositeOperatorConverter);
-    _k1 = _settings->add_spinslider(0, SP_ATTR_K1, _("K1"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively."));
-    _k2 = _settings->add_spinslider(0, SP_ATTR_K2, _("K2"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively."));
-    _k3 = _settings->add_spinslider(0, SP_ATTR_K3, _("K3"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively."));
-    _k4 = _settings->add_spinslider(0, SP_ATTR_K4, _("K4"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively."));
+    _settings->add_combo(COMPOSITE_OVER, SP_ATTR_OPERATOR, _("Operator:"), CompositeOperatorConverter);
+    _k1 = _settings->add_spinslider(0, SP_ATTR_K1, _("K1:"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively."));
+    _k2 = _settings->add_spinslider(0, SP_ATTR_K2, _("K2:"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively."));
+    _k3 = _settings->add_spinslider(0, SP_ATTR_K3, _("K3:"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively."));
+    _k4 = _settings->add_spinslider(0, SP_ATTR_K4, _("K4:"), -10, 10, 0.1, 0.01, 2, _("If the arithmetic operation is chosen, each result pixel is computed using the formula k1*i1*i2 + k2*i1 + k3*i2 + k4 where i1 and i2 are the pixel values of the first and second inputs respectively."));
 
     _settings->type(NR_FILTER_CONVOLVEMATRIX);
-    _convolve_order = _settings->add_dualspinbutton("3", SP_ATTR_ORDER, _("Size"), 1, 5, 1, 1, 0, _("width of the convolve matrix"), _("height of the convolve matrix"));
-    _convolve_target = _settings->add_multispinbutton(/*default x:*/ (double) 0, /*default y:*/ (double) 0, SP_ATTR_TARGETX, SP_ATTR_TARGETY, _("Target"), 0, 4, 1, 1, 0, _("X coordinate of the target point in the convolve matrix. The convolution is applied to pixels around this point."), _("Y coordinate of the target point in the convolve matrix. The convolution is applied to pixels around this point."));
+    _convolve_order = _settings->add_dualspinbutton((char*)"3", SP_ATTR_ORDER, _("Size:"), 1, 5, 1, 1, 0, _("width of the convolve matrix"), _("height of the convolve matrix"));
+    _convolve_target = _settings->add_multispinbutton(/*default x:*/ (double) 0, /*default y:*/ (double) 0, SP_ATTR_TARGETX, SP_ATTR_TARGETY, _("Target:"), 0, 4, 1, 1, 0, _("X coordinate of the target point in the convolve matrix. The convolution is applied to pixels around this point."), _("Y coordinate of the target point in the convolve matrix. The convolution is applied to pixels around this point."));
     //TRANSLATORS: for info on "Kernel", see http://en.wikipedia.org/wiki/Kernel_(matrix)
-    _convolve_matrix = _settings->add_matrix(SP_ATTR_KERNELMATRIX, _("Kernel"), _("This matrix describes the convolve operation that is applied to the input image in order to calculate the pixel colors at the output. Different arrangements of values in this matrix result in various possible visual effects. An identity matrix would lead to a motion blur effect (parallel to the matrix diagonal) while a matrix filled with a constant non-zero value would lead to a common blur effect."));
+    _convolve_matrix = _settings->add_matrix(SP_ATTR_KERNELMATRIX, _("Kernel:"), _("This matrix describes the convolve operation that is applied to the input image in order to calculate the pixel colors at the output. Different arrangements of values in this matrix result in various possible visual effects. An identity matrix would lead to a motion blur effect (parallel to the matrix diagonal) while a matrix filled with a constant non-zero value would lead to a common blur effect."));
     _convolve_order->signal_attr_changed().connect(sigc::mem_fun(*this, &FilterEffectsDialog::convolve_order_changed));
-    //TODO: svg spec: The default value is the sum of all values in kernelMatrix, with the exception that if the sum is zero, then the divisor is set to 1.
-    _settings->add_spinslider(1, SP_ATTR_DIVISOR, _("Divisor"), 1, 20, 1, 0.1, 2, _("After applying the kernelMatrix to the input image to yield a number, that number is divided by divisor to yield the final destination color value. A divisor that is the sum of all the matrix values tends to have an evening effect on the overall color intensity of the result."));
-    _settings->add_spinslider(0, SP_ATTR_BIAS, _("Bias"), -10, 10, 1, 0.01, 1, _("This value is added to each component. This is useful to define a constant value as the zero response of the filter."));
-    _settings->add_combo(CONVOLVEMATRIX_EDGEMODE_DUPLICATE, SP_ATTR_EDGEMODE, _("Edge Mode"), ConvolveMatrixEdgeModeConverter, _("Determines how to extend the input image as necessary with color values so that the matrix operations can be applied when the kernel is positioned at or near the edge of the input image."));
+    _settings->add_spinslider(0, SP_ATTR_DIVISOR, _("Divisor:"), 0, 1000, 1, 0.1, 2, _("After applying the kernelMatrix to the input image to yield a number, that number is divided by divisor to yield the final destination color value. A divisor that is the sum of all the matrix values tends to have an evening effect on the overall color intensity of the result."));
+    _settings->add_spinslider(0, SP_ATTR_BIAS, _("Bias:"), -10, 10, 1, 0.01, 1, _("This value is added to each component. This is useful to define a constant value as the zero response of the filter."));
+    _settings->add_combo(CONVOLVEMATRIX_EDGEMODE_DUPLICATE, SP_ATTR_EDGEMODE, _("Edge Mode:"), ConvolveMatrixEdgeModeConverter, _("Determines how to extend the input image as necessary with color values so that the matrix operations can be applied when the kernel is positioned at or near the edge of the input image."));
     _settings->add_checkbutton(false, SP_ATTR_PRESERVEALPHA, _("Preserve Alpha"), "true", "false", _("If set, the alpha channel won't be altered by this filter primitive."));
 
     _settings->type(NR_FILTER_DIFFUSELIGHTING);
-    _settings->add_color(/*default: white*/ 0xffffffff, SP_PROP_LIGHTING_COLOR, _("Diffuse Color"), _("Defines the color of the light source"));
-    _settings->add_spinslider(1, SP_ATTR_SURFACESCALE, _("Surface Scale"), -1000, 1000, 1, 0.01, 1, _("This value amplifies the heights of the bump map defined by the input alpha channel"));
-    _settings->add_spinslider(1, SP_ATTR_DIFFUSECONSTANT, _("Constant"), 0, 100, 0.1, 0.01, 2, _("This constant affects the Phong lighting model."));
-    _settings->add_dualspinslider(SP_ATTR_KERNELUNITLENGTH, _("Kernel Unit Length"), 0.01, 10, 1, 0.01, 1);
+    _settings->add_color(/*default: white*/ 0xffffffff, SP_PROP_LIGHTING_COLOR, _("Diffuse Color:"), _("Defines the color of the light source"));
+    _settings->add_spinslider(1, SP_ATTR_SURFACESCALE, _("Surface Scale:"), -5, 5, 0.01, 0.001, 3, _("This value amplifies the heights of the bump map defined by the input alpha channel"));
+    _settings->add_spinslider(1, SP_ATTR_DIFFUSECONSTANT, _("Constant:"), 0, 5, 0.1, 0.01, 2, _("This constant affects the Phong lighting model."));
+    _settings->add_dualspinslider(SP_ATTR_KERNELUNITLENGTH, _("Kernel Unit Length:"), 0.01, 10, 1, 0.01, 1);
     _settings->add_lightsource();
 
     _settings->type(NR_FILTER_DISPLACEMENTMAP);
-    _settings->add_spinslider(0, SP_ATTR_SCALE, _("Scale"), 0, 100, 1, 0.01, 1, _("This defines the intensity of the displacement effect."));
-    _settings->add_combo(DISPLACEMENTMAP_CHANNEL_ALPHA, SP_ATTR_XCHANNELSELECTOR, _("X displacement"), DisplacementMapChannelConverter, _("Color component that controls the displacement in the X direction"));
-    _settings->add_combo(DISPLACEMENTMAP_CHANNEL_ALPHA, SP_ATTR_YCHANNELSELECTOR, _("Y displacement"), DisplacementMapChannelConverter, _("Color component that controls the displacement in the Y direction"));
+    _settings->add_spinslider(0, SP_ATTR_SCALE, _("Scale:"), 0, 100, 1, 0.01, 1, _("This defines the intensity of the displacement effect."));
+    _settings->add_combo(DISPLACEMENTMAP_CHANNEL_ALPHA, SP_ATTR_XCHANNELSELECTOR, _("X displacement:"), DisplacementMapChannelConverter, _("Color component that controls the displacement in the X direction"));
+    _settings->add_combo(DISPLACEMENTMAP_CHANNEL_ALPHA, SP_ATTR_YCHANNELSELECTOR, _("Y displacement:"), DisplacementMapChannelConverter, _("Color component that controls the displacement in the Y direction"));
 
     _settings->type(NR_FILTER_FLOOD);
-    _settings->add_color(/*default: black*/ 0, SP_PROP_FLOOD_COLOR, _("Flood Color"), _("The whole filter region will be filled with this color."));
-    _settings->add_spinslider(1, SP_PROP_FLOOD_OPACITY, _("Opacity"), 0, 1, 0.1, 0.01, 2);
+    _settings->add_color(/*default: black*/ 0, SP_PROP_FLOOD_COLOR, _("Flood Color:"), _("The whole filter region will be filled with this color."));
+    _settings->add_spinslider(1, SP_PROP_FLOOD_OPACITY, _("Opacity:"), 0, 1, 0.1, 0.01, 2);
 
     _settings->type(NR_FILTER_GAUSSIANBLUR);
-    _settings->add_dualspinslider(SP_ATTR_STDDEVIATION, _("Standard Deviation"), 0.01, 100, 1, 0.01, 1, _("The standard deviation for the blur operation."));
+    _settings->add_dualspinslider(SP_ATTR_STDDEVIATION, _("Standard Deviation:"), 0.01, 100, 1, 0.01, 1, _("The standard deviation for the blur operation."));
 
     _settings->type(NR_FILTER_MERGE);
     _settings->add_no_params();
 
     _settings->type(NR_FILTER_MORPHOLOGY);
-    _settings->add_combo(MORPHOLOGY_OPERATOR_ERODE, SP_ATTR_OPERATOR, _("Operator"), MorphologyOperatorConverter, _("Erode: performs \"thinning\" of input image.\nDilate: performs \"fattenning\" of input image."));
-    _settings->add_dualspinslider(SP_ATTR_RADIUS, _("Radius"), 0, 100, 1, 0.01, 1);
+    _settings->add_combo(MORPHOLOGY_OPERATOR_ERODE, SP_ATTR_OPERATOR, _("Operator:"), MorphologyOperatorConverter, _("Erode: performs \"thinning\" of input image.\nDilate: performs \"fattenning\" of input image."));
+    _settings->add_dualspinslider(SP_ATTR_RADIUS, _("Radius:"), 0, 100, 1, 0.01, 1);
 
     _settings->type(NR_FILTER_IMAGE);
-    _settings->add_fileorelement(SP_ATTR_XLINK_HREF, _("Source of Image"));
+    _settings->add_fileorelement(SP_ATTR_XLINK_HREF, _("Source of Image:"));
 
     _settings->type(NR_FILTER_OFFSET);
-    _settings->add_spinslider(0, SP_ATTR_DX, _("Delta X"), -100, 100, 1, 0.01, 1, _("This is how far the input image gets shifted to the right"));
-    _settings->add_spinslider(0, SP_ATTR_DY, _("Delta Y"), -100, 100, 1, 0.01, 1, _("This is how far the input image gets shifted downwards"));
+    _settings->add_spinslider(0, SP_ATTR_DX, _("Delta X:"), -100, 100, 1, 0.01, 1, _("This is how far the input image gets shifted to the right"));
+    _settings->add_spinslider(0, SP_ATTR_DY, _("Delta Y:"), -100, 100, 1, 0.01, 1, _("This is how far the input image gets shifted downwards"));
 
     _settings->type(NR_FILTER_SPECULARLIGHTING);
-    _settings->add_color(/*default: white*/ 0xffffffff, SP_PROP_LIGHTING_COLOR, _("Specular Color"), _("Defines the color of the light source"));
-    _settings->add_spinslider(1, SP_ATTR_SURFACESCALE, _("Surface Scale"), -1000, 1000, 1, 0.01, 1, _("This value amplifies the heights of the bump map defined by the input alpha channel"));
-    _settings->add_spinslider(1, SP_ATTR_SPECULARCONSTANT, _("Constant"), 0, 100, 0.1, 0.01, 2, _("This constant affects the Phong lighting model."));
-    _settings->add_spinslider(1, SP_ATTR_SPECULAREXPONENT, _("Exponent"), 1, 128, 1, 0.01, 1, _("Exponent for specular term, larger is more \"shiny\"."));
-    _settings->add_dualspinslider(SP_ATTR_KERNELUNITLENGTH, _("Kernel Unit Length"), 0.01, 10, 1, 0.01, 1);
+    _settings->add_color(/*default: white*/ 0xffffffff, SP_PROP_LIGHTING_COLOR, _("Specular Color:"), _("Defines the color of the light source"));
+    _settings->add_spinslider(1, SP_ATTR_SURFACESCALE, _("Surface Scale:"), -5, 5, 0.1, 0.01, 2, _("This value amplifies the heights of the bump map defined by the input alpha channel"));
+    _settings->add_spinslider(1, SP_ATTR_SPECULARCONSTANT, _("Constant:"), 0, 5, 0.1, 0.01, 2, _("This constant affects the Phong lighting model."));
+    _settings->add_spinslider(1, SP_ATTR_SPECULAREXPONENT, _("Exponent:"), 1, 50, 1, 0.01, 1, _("Exponent for specular term, larger is more \"shiny\"."));
+    _settings->add_dualspinslider(SP_ATTR_KERNELUNITLENGTH, _("Kernel Unit Length:"), 0.01, 10, 1, 0.01, 1);
     _settings->add_lightsource();
 
     _settings->type(NR_FILTER_TILE);
@@ -2270,10 +2263,10 @@ void FilterEffectsDialog::init_settings_widgets()
 
     _settings->type(NR_FILTER_TURBULENCE);
 //    _settings->add_checkbutton(false, SP_ATTR_STITCHTILES, _("Stitch Tiles"), "stitch", "noStitch");
-    _settings->add_combo(TURBULENCE_TURBULENCE, SP_ATTR_TYPE, _("Type"), TurbulenceTypeConverter, _("Indicates whether the filter primitive should perform a noise or turbulence function."));
-    _settings->add_dualspinslider(SP_ATTR_BASEFREQUENCY, _("Base Frequency"), 0, 0.4, 0.001, 0.01, 3);
-    _settings->add_spinslider(1, SP_ATTR_NUMOCTAVES, _("Octaves"), 1, 10, 1, 1, 0);
-    _settings->add_spinslider(0, SP_ATTR_SEED, _("Seed"), 0, 1000, 1, 1, 0, _("The starting number for the pseudo random number generator."));
+    _settings->add_combo(TURBULENCE_TURBULENCE, SP_ATTR_TYPE, _("Type:"), TurbulenceTypeConverter, _("Indicates whether the filter primitive should perform a noise or turbulence function."));
+    _settings->add_dualspinslider(SP_ATTR_BASEFREQUENCY, _("Base Frequency:"), 0, 0.4, 0.001, 0.01, 3);
+    _settings->add_spinslider(1, SP_ATTR_NUMOCTAVES, _("Octaves:"), 1, 10, 1, 1, 0);
+    _settings->add_spinslider(0, SP_ATTR_SEED, _("Seed:"), 0, 1000, 1, 1, 0, _("The starting number for the pseudo random number generator."));
 }
 
 void FilterEffectsDialog::add_primitive()
@@ -2285,13 +2278,14 @@ void FilterEffectsDialog::add_primitive()
 
         _primitive_list.select(prim);
 
-        sp_document_done(filter->document, SP_VERB_DIALOG_FILTER_EFFECTS, _("Add filter primitive"));
+        DocumentUndo::done(filter->document, SP_VERB_DIALOG_FILTER_EFFECTS, _("Add filter primitive"));
     }
 }
 
 void FilterEffectsDialog::update_primitive_infobox()
 {
-    if (prefs_get_int_attribute ("options.showfiltersinfobox", "value", 1)){
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    if (prefs->getBool("/options/showfiltersinfobox/value", true)){
         _infobox_icon.show();
         _infobox_desc.show();
     } else {
@@ -2299,74 +2293,75 @@ void FilterEffectsDialog::update_primitive_infobox()
         _infobox_desc.hide();
     }
     switch(_add_primitive_type.get_active_data()->id){
-        case(NR::NR_FILTER_BLEND):
-            _infobox_icon.set(g_strdup_printf("%s/feBlend-icon.png", INKSCAPE_PIXMAPDIR));
+        case(NR_FILTER_BLEND):
+            _infobox_icon.set_from_icon_name("feBlend-icon", Gtk::ICON_SIZE_DIALOG);
             _infobox_desc.set_markup(_("The <b>feBlend</b> filter primitive provides 4 image blending modes: screen, multiply, darken and lighten."));
             break;
-        case(NR::NR_FILTER_COLORMATRIX):
-            _infobox_icon.set(g_strdup_printf("%s/feColorMatrix-icon.png", INKSCAPE_PIXMAPDIR));
-            _infobox_desc.set_markup(_("The <b>feColorMatrix</b> filter primitive applies a matrix transformation to colour of each rendered pixel. This allows for effects like turning object to grayscale, modifying colour saturation and changing colour hue."));
+        case(NR_FILTER_COLORMATRIX):
+            _infobox_icon.set_from_icon_name("feColorMatrix-icon", Gtk::ICON_SIZE_DIALOG);
+            _infobox_desc.set_markup(_("The <b>feColorMatrix</b> filter primitive applies a matrix transformation to color of each rendered pixel. This allows for effects like turning object to grayscale, modifying color saturation and changing color hue."));
             break;
-        case(NR::NR_FILTER_COMPONENTTRANSFER):
-            _infobox_icon.set(g_strdup_printf("%s/feComponentTransfer-icon.png", INKSCAPE_PIXMAPDIR));
+        case(NR_FILTER_COMPONENTTRANSFER):
+            _infobox_icon.set_from_icon_name("feComponentTransfer-icon", Gtk::ICON_SIZE_DIALOG);
             _infobox_desc.set_markup(_("The <b>feComponentTransfer</b> filter primitive manipulates the input's color components (red, green, blue, and alpha) according to particular transfer functions, allowing operations like brightness and contrast adjustment, color balance, and thresholding."));
             break;
-        case(NR::NR_FILTER_COMPOSITE):
-            _infobox_icon.set(g_strdup_printf("%s/feComposite-icon.png", INKSCAPE_PIXMAPDIR));
-            _infobox_desc.set_markup(_("The <b>feComposite</b> filter primitive composites two images using one of the Porter-Duff blending modes or the aritmetic mode described in SVG standard. Porter-Duff blending modes are essentially logical operations between the corresponding pixel values of the images."));
+        case(NR_FILTER_COMPOSITE):
+            _infobox_icon.set_from_icon_name("feComposite-icon", Gtk::ICON_SIZE_DIALOG);
+            _infobox_desc.set_markup(_("The <b>feComposite</b> filter primitive composites two images using one of the Porter-Duff blending modes or the arithmetic mode described in SVG standard. Porter-Duff blending modes are essentially logical operations between the corresponding pixel values of the images."));
             break;
-        case(NR::NR_FILTER_CONVOLVEMATRIX):
-            _infobox_icon.set(g_strdup_printf("%s/feConvolveMatrix-icon.png", INKSCAPE_PIXMAPDIR));
+        case(NR_FILTER_CONVOLVEMATRIX):
+            _infobox_icon.set_from_icon_name("feConvolveMatrix-icon", Gtk::ICON_SIZE_DIALOG);
             _infobox_desc.set_markup(_("The <b>feConvolveMatrix</b> lets you specify a Convolution to be applied on the image. Common effects created using convolution matrices are blur, sharpening, embossing and edge detection. Note that while gaussian blur can be created using this filter primitive, the special gaussian blur primitive is faster and resolution-independent."));
             break;
-        case(NR::NR_FILTER_DIFFUSELIGHTING):
-            _infobox_icon.set(g_strdup_printf("%s/feDiffuseLighting-icon.png", INKSCAPE_PIXMAPDIR));
+        case(NR_FILTER_DIFFUSELIGHTING):
+            _infobox_icon.set_from_icon_name("feDiffuseLighting-icon", Gtk::ICON_SIZE_DIALOG);
             _infobox_desc.set_markup(_("The <b>feDiffuseLighting</b> and feSpecularLighting filter primitives create \"embossed\" shadings.  The input's alpha channel is used to provide depth information: higher opacity areas are raised toward the viewer and lower opacity areas recede away from the viewer."));
             break;
-        case(NR::NR_FILTER_DISPLACEMENTMAP):
-            _infobox_icon.set(g_strdup_printf("%s/feDisplacementMap-icon.png", INKSCAPE_PIXMAPDIR));
+        case(NR_FILTER_DISPLACEMENTMAP):
+            _infobox_icon.set_from_icon_name("feDisplacementMap-icon", Gtk::ICON_SIZE_DIALOG);
             _infobox_desc.set_markup(_("The <b>feDisplacementMap</b> filter primitive displaces the pixels in the first input using the second input as a displacement map, that shows from how far the pixel should come from. Classical examples are whirl and pinch effects."));
             break;
-        case(NR::NR_FILTER_FLOOD):
-            _infobox_icon.set(g_strdup_printf("%s/feFlood-icon.png", INKSCAPE_PIXMAPDIR));
+        case(NR_FILTER_FLOOD):
+            _infobox_icon.set_from_icon_name("feFlood-icon", Gtk::ICON_SIZE_DIALOG);
             _infobox_desc.set_markup(_("The <b>feFlood</b> filter primitive fills the region with a given color and opacity.  It is usually used as an input to other filters to apply color to a graphic."));
             break;
-        case(NR::NR_FILTER_GAUSSIANBLUR):
-            _infobox_icon.set(g_strdup_printf("%s/feGaussianBlur-icon.png", INKSCAPE_PIXMAPDIR));
+        case(NR_FILTER_GAUSSIANBLUR):
+            _infobox_icon.set_from_icon_name("feGaussianBlur-icon", Gtk::ICON_SIZE_DIALOG);
             _infobox_desc.set_markup(_("The <b>feGaussianBlur</b> filter primitive uniformly blurs its input.  It is commonly used together with feOffset to create a drop shadow effect."));
             break;
-        case(NR::NR_FILTER_IMAGE):
-            _infobox_icon.set(g_strdup_printf("%s/feImage-icon.png", INKSCAPE_PIXMAPDIR));
+        case(NR_FILTER_IMAGE):
+            _infobox_icon.set_from_icon_name("feImage-icon", Gtk::ICON_SIZE_DIALOG);
             _infobox_desc.set_markup(_("The <b>feImage</b> filter primitive fills the region with an external image or another part of the document."));
             break;
-        case(NR::NR_FILTER_MERGE):
-            _infobox_icon.set(g_strdup_printf("%s/feMerge-icon.png", INKSCAPE_PIXMAPDIR));
+        case(NR_FILTER_MERGE):
+            _infobox_icon.set_from_icon_name("feMerge-icon", Gtk::ICON_SIZE_DIALOG);
             _infobox_desc.set_markup(_("The <b>feMerge</b> filter primitive composites several temporary images inside the filter primitive to a single image. It uses normal alpha compositing for this. This is equivalent to using several feBlend primitives in 'normal' mode or several feComposite primitives in 'over' mode."));
             break;
-        case(NR::NR_FILTER_MORPHOLOGY):
-            _infobox_icon.set(g_strdup_printf("%s/feMorphology-icon.png", INKSCAPE_PIXMAPDIR));
-            _infobox_desc.set_markup(_("The <b>feMorphology</b> filter primitive provides erode and dilate effects. For single-colour objects erode makes the object thinner and dilate makes it thicker."));
+        case(NR_FILTER_MORPHOLOGY):
+            _infobox_icon.set_from_icon_name("feMorphology-icon", Gtk::ICON_SIZE_DIALOG);
+            _infobox_desc.set_markup(_("The <b>feMorphology</b> filter primitive provides erode and dilate effects. For single-color objects erode makes the object thinner and dilate makes it thicker."));
             break;
-        case(NR::NR_FILTER_OFFSET):
-            _infobox_icon.set(g_strdup_printf("%s/feOffset-icon.png", INKSCAPE_PIXMAPDIR));
+        case(NR_FILTER_OFFSET):
+            _infobox_icon.set_from_icon_name("feOffset-icon", Gtk::ICON_SIZE_DIALOG);
             _infobox_desc.set_markup(_("The <b>feOffset</b> filter primitive offsets the image by an user-defined amount. For example, this is useful for drop shadows, where the shadow is in a slightly different position than the actual object."));
             break;
-        case(NR::NR_FILTER_SPECULARLIGHTING):
-            _infobox_icon.set(g_strdup_printf("%s/feSpecularLighting-icon.png", INKSCAPE_PIXMAPDIR));
+        case(NR_FILTER_SPECULARLIGHTING):
+            _infobox_icon.set_from_icon_name("feSpecularLighting-icon", Gtk::ICON_SIZE_DIALOG);
             _infobox_desc.set_markup(_("The feDiffuseLighting and <b>feSpecularLighting</b> filter primitives create \"embossed\" shadings.  The input's alpha channel is used to provide depth information: higher opacity areas are raised toward the viewer and lower opacity areas recede away from the viewer."));
             break;
-        case(NR::NR_FILTER_TILE):
-            _infobox_icon.set(g_strdup_printf("%s/feTile-icon.png", INKSCAPE_PIXMAPDIR));
+        case(NR_FILTER_TILE):
+            _infobox_icon.set_from_icon_name("feTile-icon", Gtk::ICON_SIZE_DIALOG);
             _infobox_desc.set_markup(_("The <b>feTile</b> filter primitive tiles a region with its input graphic"));
             break;
-        case(NR::NR_FILTER_TURBULENCE):
-            _infobox_icon.set(g_strdup_printf("%s/feTurbulence-icon.png", INKSCAPE_PIXMAPDIR));
+        case(NR_FILTER_TURBULENCE):
+            _infobox_icon.set_from_icon_name("feTurbulence-icon", Gtk::ICON_SIZE_DIALOG);
             _infobox_desc.set_markup(_("The <b>feTurbulence</b> filter primitive renders Perlin noise. This kind of noise is useful in simulating several nature phenomena like clouds, fire and smoke and in generating complex textures like marble or granite."));
             break;
         default:
             g_assert(false);
             break;
     }
+    _infobox_icon.set_pixel_size(96);
 }
 
 void FilterEffectsDialog::duplicate_primitive()
@@ -2379,7 +2374,7 @@ void FilterEffectsDialog::duplicate_primitive()
         repr = SP_OBJECT_REPR(origprim)->duplicate(SP_OBJECT_REPR(origprim)->document());
         SP_OBJECT_REPR(filter)->appendChild(repr);
 
-        sp_document_done(filter->document, SP_VERB_DIALOG_FILTER_EFFECTS, _("Duplicate filter primitive"));
+        DocumentUndo::done(filter->document, SP_VERB_DIALOG_FILTER_EFFECTS, _("Duplicate filter primitive"));
 
         _primitive_list.update();
     }
@@ -2431,8 +2426,8 @@ void FilterEffectsDialog::set_attr(SPObject* o, const SPAttributeEnum attr, cons
 
             Glib::ustring undokey = "filtereffects:";
             undokey += name;
-            sp_document_maybe_done(filter->document, undokey.c_str(), SP_VERB_DIALOG_FILTER_EFFECTS,
-                                   _("Set filter primitive attribute"));
+            DocumentUndo::maybeDone(filter->document, undokey.c_str(), SP_VERB_DIALOG_FILTER_EFFECTS,
+                                    _("Set filter primitive attribute"));
         }
 
         _attr_lock = false;
@@ -2475,18 +2470,21 @@ void FilterEffectsDialog::update_settings_view()
     for(unsigned int i=0; i<vect1.size(); i++) vect1[i]->hide_all();
     _empty_settings.show();
 
-    if (prefs_get_int_attribute ("options.showfiltersinfobox", "value", 1)){
+    Inkscape::Preferences *prefs = Inkscape::Preferences::get();
+    if (prefs->getBool("/options/showfiltersinfobox/value", true)){
         _infobox_icon.show();
         _infobox_desc.show();
     } else {
         _infobox_icon.hide();
         _infobox_desc.hide();
     }
-    
+
     SPFilterPrimitive* prim = _primitive_list.get_selected();
 
     if(prim) {
-        _settings->show_and_update(FPConverter.get_id_from_key(prim->repr->name()), prim);
+
+        //XML Tree being used directly here while it shouldn't be.
+        _settings->show_and_update(FPConverter.get_id_from_key(prim->getRepr()->name()), prim);
         _empty_settings.hide();
     }
 
@@ -2549,4 +2547,4 @@ void FilterEffectsDialog::update_color_matrix()
   fill-column:99
   End:
 */
-// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 :
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :