Code

patch 1750206 by Bruno Dilly - bdilly
[inkscape.git] / src / ui / widget / registered-widget.cpp
index 918742e751f4e2d953e103cce70d28db93576c56..86c76b2361fd230ca6aa5635d05357b6d25602a0 100644 (file)
@@ -24,7 +24,7 @@
 
 #include "helper/units.h"
 #include "xml/repr.h"
-#include "svg/svg.h"
+#include "svg/svg-color.h"
 #include "svg/stringstream.h"
 
 #include "inkscape.h"
@@ -33,6 +33,7 @@
 #include "sp-namedview.h"
 
 #include "registered-widget.h"
+#include "verbs.h"
 
 namespace Inkscape {
 namespace UI {
@@ -58,15 +59,22 @@ RegisteredCheckButton::~RegisteredCheckButton()
 }
 
 void
-RegisteredCheckButton::init (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right)
+RegisteredCheckButton::init (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
 {
     _button = new Gtk::CheckButton;
     _tt.set_tip (*_button, tip);
-    _button->add (*manage (new Gtk::Label (label)));
+    Gtk::Label *l = new Gtk::Label (label);
+    l->set_use_underline (true);
+    _button->add (*manage (l));
     _button->set_alignment (right? 1.0 : 0.0, 0.5);
     _key = key;
     _wr = ≀
     _toggled_connection = _button->signal_toggled().connect (sigc::mem_fun (*this, &RegisteredCheckButton::on_toggled));
+
+    repr = repr_in;
+    doc = doc_in;
+    if (repr && !doc)  // doc cannot be NULL when repr is not NULL
+        g_error("Initialization of registered widget using defined repr but with doc==NULL");
 }
 
 void
@@ -81,23 +89,29 @@ RegisteredCheckButton::on_toggled()
     if (_wr->isUpdating())
         return;
 
-    SPDesktop *dt = SP_ACTIVE_DESKTOP;
-    if (!dt) {
-        return;
+    // Use local repr here. When repr is specified, use that one, but
+    // if repr==NULL, get the repr of namedview of active desktop.
+    Inkscape::XML::Node *local_repr = repr;
+    SPDocument *local_doc = doc;
+    if (!local_repr) {
+        // no repr specified, use active desktop's namedview's repr
+        SPDesktop *dt = SP_ACTIVE_DESKTOP;
+        if (!dt)
+            return;
+        local_repr = SP_OBJECT_REPR (sp_desktop_namedview(dt));
+        local_doc = sp_desktop_document(dt);
     }
 
-    SPDocument *doc = SP_DT_DOCUMENT(dt);
-
-    Inkscape::XML::Node *repr = SP_OBJECT_REPR (SP_DT_NAMEDVIEW(dt));
     _wr->setUpdating (true);
 
-    gboolean saved = sp_document_get_undo_sensitive (doc);
-    sp_document_set_undo_sensitive (doc, FALSE);
-    sp_repr_set_boolean(repr, _key.c_str(), _button->get_active());
-    doc->rroot->setAttribute("sodipodi:modified", "true");
-    sp_document_set_undo_sensitive (doc, saved);
-    sp_document_done (doc);
-    
+    bool saved = sp_document_get_undo_sensitive (local_doc);
+    sp_document_set_undo_sensitive (local_doc, false);
+    sp_repr_set_boolean(local_repr, _key.c_str(), _button->get_active());
+    local_doc->rroot->setAttribute("sodipodi:modified", "true");
+    sp_document_set_undo_sensitive (local_doc, saved);
+    sp_document_done (local_doc, SP_VERB_NONE,
+                      /* TODO: annotate */ "registered-widget.cpp: RegisteredCheckButton::on_toggled");
+
     _wr->setUpdating (false);
 }
 
@@ -114,17 +128,24 @@ RegisteredUnitMenu::~RegisteredUnitMenu()
 }
 
 void
-RegisteredUnitMenu::init (const Glib::ustring& label, const Glib::ustring& key, Registry& wr)
+RegisteredUnitMenu::init (const Glib::ustring& label, const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
 {
     _label = new Gtk::Label (label, 1.0, 0.5);
+    _label->set_use_underline (true);
     _sel = new UnitMenu ();
+    _label->set_mnemonic_widget (*_sel);
     _sel->setUnitType (UNIT_TYPE_LINEAR);
     _wr = ≀
     _key = key;
     _changed_connection = _sel->signal_changed().connect (sigc::mem_fun (*this, &RegisteredUnitMenu::on_changed));
+
+    repr = repr_in;
+    doc = doc_in;
+    if (repr && !doc)  // doc cannot be NULL when repr is not NULL
+        g_warning("Initialization of registered widget using defined repr but with doc==NULL");
 }
 
-void 
+void
 RegisteredUnitMenu::setUnit (const SPUnit* unit)
 {
     _sel->setUnit (sp_unit_get_abbreviation (unit));
@@ -136,24 +157,32 @@ RegisteredUnitMenu::on_changed()
     if (_wr->isUpdating())
         return;
 
-    SPDesktop *dt = SP_ACTIVE_DESKTOP;
-    if (!dt) 
-        return;
+    // Use local repr here. When repr is specified, use that one, but
+    // if repr==NULL, get the repr of namedview of active desktop.
+    Inkscape::XML::Node *local_repr = repr;
+    SPDocument *local_doc = doc;
+    if (!local_repr) {
+        // no repr specified, use active desktop's namedview's repr
+        SPDesktop *dt = SP_ACTIVE_DESKTOP;
+        if (!dt)
+            return;
+        local_repr = SP_OBJECT_REPR (sp_desktop_namedview(dt));
+        local_doc = sp_desktop_document(dt);
+    }
 
     Inkscape::SVGOStringStream os;
     os << _sel->getUnitAbbr();
 
     _wr->setUpdating (true);
 
-    SPDocument *doc = SP_DT_DOCUMENT(dt);
-    gboolean saved = sp_document_get_undo_sensitive (doc);
-    sp_document_set_undo_sensitive (doc, FALSE);
-    Inkscape::XML::Node *repr = SP_OBJECT_REPR (SP_DT_NAMEDVIEW(dt));
-    repr->setAttribute(_key.c_str(), os.str().c_str());
-    doc->rroot->setAttribute("sodipodi:modified", "true");
-    sp_document_set_undo_sensitive (doc, saved);
-    sp_document_done (doc);
-    
+    bool saved = sp_document_get_undo_sensitive (local_doc);
+    sp_document_set_undo_sensitive (local_doc, false);
+    local_repr->setAttribute(_key.c_str(), os.str().c_str());
+    local_doc->rroot->setAttribute("sodipodi:modified", "true");
+    sp_document_set_undo_sensitive (local_doc, saved);
+    sp_document_done (local_doc, SP_VERB_NONE,
+                      /* TODO: annotate */ "registered-widget.cpp: RegisteredUnitMenu::on_changed");
+
     _wr->setUpdating (false);
 }
 
@@ -170,7 +199,7 @@ RegisteredScalarUnit::~RegisteredScalarUnit()
 }
 
 void
-RegisteredScalarUnit::init (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, const RegisteredUnitMenu &rum, Registry& wr)
+RegisteredScalarUnit::init (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, const RegisteredUnitMenu &rum, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
 {
     _widget = new ScalarUnit (label, tip, UNIT_TYPE_LINEAR, "", "", rum._sel);
     _widget->initScalar (-1e6, 1e6);
@@ -180,6 +209,11 @@ RegisteredScalarUnit::init (const Glib::ustring& label, const Glib::ustring& tip
     _um = rum._sel;
     _value_changed_connection = _widget->signal_value_changed().connect (sigc::mem_fun (*this, &RegisteredScalarUnit::on_value_changed));
     _wr = &wr;
+
+    repr = repr_in;
+    doc = doc_in;
+    if (repr && !doc)  // doc cannot be NULL when repr is not NULL
+        g_warning("Initialization of registered widget using defined repr but with doc==NULL");
 }
 
 ScalarUnit*
@@ -188,7 +222,7 @@ RegisteredScalarUnit::getSU()
     return _widget;
 }
 
-void 
+void
 RegisteredScalarUnit::setValue (double val)
 {
     _widget->setValue (val);
@@ -201,9 +235,18 @@ RegisteredScalarUnit::on_value_changed()
     if (_wr->isUpdating())
         return;
 
-    SPDesktop *dt = SP_ACTIVE_DESKTOP;
-    if (!dt) 
-        return;
+    // Use local repr here. When repr is specified, use that one, but
+    // if repr==NULL, get the repr of namedview of active desktop.
+    Inkscape::XML::Node *local_repr = repr;
+    SPDocument *local_doc = doc;
+    if (!local_repr) {
+        // no repr specified, use active desktop's namedview's repr
+        SPDesktop *dt = SP_ACTIVE_DESKTOP;
+        if (!dt)
+            return;
+        local_repr = SP_OBJECT_REPR (sp_desktop_namedview(dt));
+        local_doc = sp_desktop_document(dt);
+    }
 
     Inkscape::SVGOStringStream os;
     os << _widget->getValue("");
@@ -212,15 +255,14 @@ RegisteredScalarUnit::on_value_changed()
 
     _wr->setUpdating (true);
 
-    SPDocument *doc = SP_DT_DOCUMENT(dt);
-    gboolean saved = sp_document_get_undo_sensitive (doc);
-    sp_document_set_undo_sensitive (doc, FALSE);
-    Inkscape::XML::Node *repr = SP_OBJECT_REPR (SP_DT_NAMEDVIEW(dt));
-    repr->setAttribute(_key.c_str(), os.str().c_str());
-    doc->rroot->setAttribute("sodipodi:modified", "true");
-    sp_document_set_undo_sensitive (doc, saved);
-    sp_document_done (doc);
-    
+    bool saved = sp_document_get_undo_sensitive (local_doc);
+    sp_document_set_undo_sensitive (local_doc, false);
+    local_repr->setAttribute(_key.c_str(), os.str().c_str());
+    local_doc->rroot->setAttribute("sodipodi:modified", "true");
+    sp_document_set_undo_sensitive (local_doc, saved);
+    sp_document_done (local_doc, SP_VERB_NONE,
+                      /* TODO: annotate */ "registered-widget.cpp: RegisteredScalarUnit::on_value_changed");
+
     _wr->setUpdating (false);
 }
 
@@ -237,17 +279,24 @@ RegisteredColorPicker::~RegisteredColorPicker()
 }
 
 void
-RegisteredColorPicker::init (const Glib::ustring& label, const Glib::ustring& title, const Glib::ustring& tip, const Glib::ustring& ckey, const Glib::ustring& akey, Registry& wr)
+RegisteredColorPicker::init (const Glib::ustring& label, const Glib::ustring& title, const Glib::ustring& tip, const Glib::ustring& ckey, const Glib::ustring& akey, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
 {
     _label = new Gtk::Label (label, 1.0, 0.5);
+    _label->set_use_underline (true);
     _cp = new ColorPicker (title,tip,0,true);
+    _label->set_mnemonic_widget (*_cp);
     _ckey = ckey;
     _akey = akey;
     _wr = &wr;
     _changed_connection = _cp->connectChanged (sigc::mem_fun (*this, &RegisteredColorPicker::on_changed));
+
+    repr = repr_in;
+    doc = doc_in;
+    if (repr && !doc)  // doc cannot be NULL when repr is not NULL
+        g_warning("Initialization of registered widget using defined repr but with doc==NULL");
 }
 
-void 
+void
 RegisteredColorPicker::setRgba32 (guint32 rgba)
 {
     _cp->setRgba32 (rgba);
@@ -262,21 +311,41 @@ RegisteredColorPicker::closeWindow()
 void
 RegisteredColorPicker::on_changed (guint32 rgba)
 {
-    if (_wr->isUpdating() || !SP_ACTIVE_DESKTOP)
+    if (_wr->isUpdating())
         return;
 
     _wr->setUpdating (true);
-    Inkscape::XML::Node *repr = SP_OBJECT_REPR(SP_DT_NAMEDVIEW(SP_ACTIVE_DESKTOP));
+
+    // Use local repr here. When repr is specified, use that one, but
+    // if repr==NULL, get the repr of namedview of active desktop.
+    Inkscape::XML::Node *local_repr = repr;
+    SPDocument *local_doc = doc;
+    if (!local_repr) {
+        // no repr specified, use active desktop's namedview's repr
+        SPDesktop *dt = SP_ACTIVE_DESKTOP;
+        if (!dt)
+            return;
+        local_repr = SP_OBJECT_REPR (sp_desktop_namedview(dt));
+        local_doc = sp_desktop_document(dt);
+    }
+
     gchar c[32];
     sp_svg_write_color(c, 32, rgba);
-    repr->setAttribute(_ckey.c_str(), c);
-    sp_repr_set_css_double(repr, _akey.c_str(), (rgba & 0xff) / 255.0);
+    bool saved = sp_document_get_undo_sensitive (local_doc);
+    sp_document_set_undo_sensitive (local_doc, false);
+    local_repr->setAttribute(_ckey.c_str(), c);
+    sp_repr_set_css_double(local_repr, _akey.c_str(), (rgba & 0xff) / 255.0);
+    local_doc->rroot->setAttribute("sodipodi:modified", "true");
+    sp_document_set_undo_sensitive (local_doc, saved);
+    sp_document_done (local_doc, SP_VERB_NONE,
+                      /* TODO: annotate */ "registered-widget.cpp: RegisteredColorPicker::on_changed");
+
     _wr->setUpdating (false);
 }
 
 RegisteredSuffixedInteger::RegisteredSuffixedInteger()
 : _label(0), _sb(0),
-  _adj(0.0,0.0,100.0,1.0,1.0,1.0), 
+  _adj(0.0,0.0,100.0,1.0,1.0,1.0),
   _suffix(0)
 {
 }
@@ -290,21 +359,28 @@ RegisteredSuffixedInteger::~RegisteredSuffixedInteger()
 }
 
 void
-RegisteredSuffixedInteger::init (const Glib::ustring& label, const Glib::ustring& suffix, const Glib::ustring& key, Registry& wr)
+RegisteredSuffixedInteger::init (const Glib::ustring& label, const Glib::ustring& suffix, const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
 {
     _key = key;
     _label = new Gtk::Label (label);
     _label->set_alignment (1.0, 0.5);
+    _label->set_use_underline();
     _sb = new Gtk::SpinButton (_adj, 1.0, 0);
+    _label->set_mnemonic_widget (*_sb);
     _suffix = new Gtk::Label (suffix);
     _hbox.pack_start (*_sb, true, true, 0);
     _hbox.pack_start (*_suffix, false, false, 0);
 
     _changed_connection = _adj.signal_value_changed().connect (sigc::mem_fun(*this, &RegisteredSuffixedInteger::on_value_changed));
     _wr = &wr;
+
+    repr = repr_in;
+    doc = doc_in;
+    if (repr && !doc)  // doc cannot be NULL when repr is not NULL
+        g_warning("Initialization of registered widget using defined repr but with doc==NULL");
 }
 
-void 
+void
 RegisteredSuffixedInteger::setValue (int i)
 {
     _adj.set_value (i);
@@ -313,20 +389,32 @@ RegisteredSuffixedInteger::setValue (int i)
 void
 RegisteredSuffixedInteger::on_value_changed()
 {
-    if (_wr->isUpdating() || !SP_ACTIVE_DESKTOP)
+    if (_wr->isUpdating())
         return;
 
     _wr->setUpdating (true);
-    
-    SPDesktop* dt = SP_ACTIVE_DESKTOP;
-    Inkscape::XML::Node *repr = SP_OBJECT_REPR(SP_DT_NAMEDVIEW(dt));
+
+    // Use local repr here. When repr is specified, use that one, but
+    // if repr==NULL, get the repr of namedview of active desktop.
+    Inkscape::XML::Node *local_repr = repr;
+    SPDocument *local_doc = doc;
+    if (!local_repr) {
+        // no repr specified, use active desktop's namedview's repr
+        SPDesktop *dt = SP_ACTIVE_DESKTOP;
+        if (!dt)
+            return;
+        local_repr = SP_OBJECT_REPR (sp_desktop_namedview(dt));
+        local_doc = sp_desktop_document(dt);
+    }
+
     Inkscape::SVGOStringStream os;
     int value = int(_adj.get_value());
     os << value;
 
-    repr->setAttribute(_key.c_str(), os.str().c_str());
-    sp_document_done(SP_DT_DOCUMENT(dt));
-    
+    local_repr->setAttribute(_key.c_str(), os.str().c_str());
+    sp_document_done(local_doc, SP_VERB_NONE,
+                     /* TODO: annotate */ "registered-widget.cpp: RegisteredSuffixedInteger::on_value_changed");
+
     _wr->setUpdating (false);
 }
 
@@ -341,17 +429,17 @@ RegisteredRadioButtonPair::~RegisteredRadioButtonPair()
 }
 
 void
-RegisteredRadioButtonPair::init (const Glib::ustring& label, 
-const Glib::ustring& label1, const Glib::ustring& label2, 
-const Glib::ustring& tip1, const Glib::ustring& tip2, 
-const Glib::ustring& key, Registry& wr)
+RegisteredRadioButtonPair::init (const Glib::ustring& label,
+const Glib::ustring& label1, const Glib::ustring& label2,
+const Glib::ustring& tip1, const Glib::ustring& tip2,
+const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
 {
     _hbox = new Gtk::HBox;
     _hbox->add (*manage (new Gtk::Label (label)));
-    _rb1 = manage (new Gtk::RadioButton (label1));
+    _rb1 = manage (new Gtk::RadioButton (label1, true));
     _hbox->add (*_rb1);
     Gtk::RadioButtonGroup group = _rb1->get_group();
-    _rb2 = manage (new Gtk::RadioButton (group, label2, false));
+    _rb2 = manage (new Gtk::RadioButton (group, label2, true));
     _hbox->add (*_rb2);
     _rb2->set_active();
     _tt.set_tip (*_rb1, tip1);
@@ -359,9 +447,14 @@ const Glib::ustring& key, Registry& wr)
     _key = key;
     _wr = &wr;
     _changed_connection = _rb1->signal_toggled().connect (sigc::mem_fun (*this, &RegisteredRadioButtonPair::on_value_changed));
+
+    repr = repr_in;
+    doc = doc_in;
+    if (repr && !doc)  // doc cannot be NULL when repr is not NULL
+        g_error("Initialization of registered widget using defined repr but with doc==NULL");
 }
 
-void 
+void
 RegisteredRadioButtonPair::setValue (bool second)
 {
     if (second) _rb2->set_active();
@@ -374,22 +467,30 @@ RegisteredRadioButtonPair::on_value_changed()
     if (_wr->isUpdating())
         return;
 
-    SPDesktop *dt = SP_ACTIVE_DESKTOP;
-    if (!dt) 
-        return;
+    // Use local repr here. When repr is specified, use that one, but
+    // if repr==NULL, get the repr of namedview of active desktop.
+    Inkscape::XML::Node *local_repr = repr;
+    SPDocument *local_doc = doc;
+    if (!local_repr) {
+        // no repr specified, use active desktop's namedview's repr
+        SPDesktop *dt = SP_ACTIVE_DESKTOP;
+        if (!dt)
+            return;
+        local_repr = SP_OBJECT_REPR (sp_desktop_namedview(dt));
+        local_doc = sp_desktop_document(dt);
+    }
 
     _wr->setUpdating (true);
-    
+
     bool second = _rb2->get_active();
-    SPDocument *doc = SP_DT_DOCUMENT(dt);
-    gboolean saved = sp_document_get_undo_sensitive (doc);
-    sp_document_set_undo_sensitive (doc, FALSE);
-    Inkscape::XML::Node *repr = SP_OBJECT_REPR (SP_DT_NAMEDVIEW(dt));
-    repr->setAttribute(_key.c_str(), second ? "true" : "false");
-    doc->rroot->setAttribute("sodipodi:modified", "true");
-    sp_document_set_undo_sensitive (doc, saved);
-    sp_document_done (doc);
-    
+    bool saved = sp_document_get_undo_sensitive (local_doc);
+    sp_document_set_undo_sensitive (local_doc, false);
+    local_repr->setAttribute(_key.c_str(), second ? "true" : "false");
+    local_doc->rroot->setAttribute("sodipodi:modified", "true");
+    sp_document_set_undo_sensitive (local_doc, saved);
+    sp_document_done (local_doc, SP_VERB_NONE,
+                      /* TODO: annotate */ "registered-widget.cpp: RegisteredRadioButtonPair::on_value_changed");
+
     _wr->setUpdating (false);
 }