Code

Fix #1740146.
[inkscape.git] / src / ui / widget / registered-widget.cpp
1 /** \file
2  *
3  *
4  * Authors:
5  *   bulia byak <buliabyak@users.sf.net>
6  *   Bryce W. Harrington <bryce@bryceharrington.org>
7  *   Lauris Kaplinski <lauris@kaplinski.com>
8  *   Jon Phillips <jon@rejon.org>
9  *   Ralf Stephan <ralf@ark.in-berlin.de> (Gtkmm)
10  *
11  * Copyright (C) 2000 - 2005 Authors
12  *
13  * Released under GNU GPL.  Read the file 'COPYING' for more information
14  */
16 #ifdef HAVE_CONFIG_H
17 # include <config.h>
18 #endif
21 #include "ui/widget/color-picker.h"
22 #include "ui/widget/registry.h"
23 #include "ui/widget/scalar-unit.h"
25 #include "helper/units.h"
26 #include "xml/repr.h"
27 #include "svg/svg-color.h"
28 #include "svg/stringstream.h"
30 #include "inkscape.h"
31 #include "document.h"
32 #include "desktop-handles.h"
33 #include "sp-namedview.h"
35 #include "registered-widget.h"
36 #include "verbs.h"
38 namespace Inkscape {
39 namespace UI {
40 namespace Widget {
42 //===================================================
44 //---------------------------------------------------
48 //====================================================
50 RegisteredCheckButton::RegisteredCheckButton()
51 : _button(0)
52 {
53 }
55 RegisteredCheckButton::~RegisteredCheckButton()
56 {
57     _toggled_connection.disconnect();
58     if (_button) delete _button;
59 }
61 void
62 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)
63 {
64     _button = new Gtk::CheckButton;
65     _tt.set_tip (*_button, tip);
66     Gtk::Label *l = new Gtk::Label (label);
67     l->set_use_underline (true);
68     _button->add (*manage (l));
69     _button->set_alignment (right? 1.0 : 0.0, 0.5);
70     _key = key;
71     _wr = &wr;
72     _toggled_connection = _button->signal_toggled().connect (sigc::mem_fun (*this, &RegisteredCheckButton::on_toggled));
74     repr = repr_in;
75     doc = doc_in;
76     if (repr && !doc)  // doc cannot be NULL when repr is not NULL
77         g_error("Initialization of registered widget using defined repr but with doc==NULL");
78 }
80 void
81 RegisteredCheckButton::setActive (bool b)
82 {
83     _button->set_active (b);
84 }
86 void
87 RegisteredCheckButton::on_toggled()
88 {
89     if (_wr->isUpdating())
90         return;
92     // Use local repr here. When repr is specified, use that one, but
93     // if repr==NULL, get the repr of namedview of active desktop.
94     Inkscape::XML::Node *local_repr = repr;
95     SPDocument *local_doc = doc;
96     if (!local_repr) {
97         // no repr specified, use active desktop's namedview's repr
98         SPDesktop *dt = SP_ACTIVE_DESKTOP;
99         if (!dt)
100             return;
101         local_repr = SP_OBJECT_REPR (sp_desktop_namedview(dt));
102         local_doc = sp_desktop_document(dt);
103     }
105     _wr->setUpdating (true);
107     bool saved = sp_document_get_undo_sensitive (local_doc);
108     sp_document_set_undo_sensitive (local_doc, false);
109     sp_repr_set_boolean(local_repr, _key.c_str(), _button->get_active());
110     local_doc->rroot->setAttribute("sodipodi:modified", "true");
111     sp_document_set_undo_sensitive (local_doc, saved);
112     sp_document_done (local_doc, SP_VERB_NONE,
113                       /* TODO: annotate */ "registered-widget.cpp: RegisteredCheckButton::on_toggled");
115     _wr->setUpdating (false);
118 RegisteredUnitMenu::RegisteredUnitMenu()
119 : _label(0), _sel(0)
123 RegisteredUnitMenu::~RegisteredUnitMenu()
125     _changed_connection.disconnect();
126     if (_label) delete _label;
127     if (_sel) delete _sel;
130 void
131 RegisteredUnitMenu::init (const Glib::ustring& label, const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
133     _label = new Gtk::Label (label, 1.0, 0.5);
134     _label->set_use_underline (true);
135     _sel = new UnitMenu ();
136     _label->set_mnemonic_widget (*_sel);
137     _sel->setUnitType (UNIT_TYPE_LINEAR);
138     _wr = &wr;
139     _key = key;
140     _changed_connection = _sel->signal_changed().connect (sigc::mem_fun (*this, &RegisteredUnitMenu::on_changed));
142     repr = repr_in;
143     doc = doc_in;
144     if (repr && !doc)  // doc cannot be NULL when repr is not NULL
145         g_warning("Initialization of registered widget using defined repr but with doc==NULL");
148 void
149 RegisteredUnitMenu::setUnit (const SPUnit* unit)
151     _sel->setUnit (sp_unit_get_abbreviation (unit));
154 void
155 RegisteredUnitMenu::on_changed()
157     if (_wr->isUpdating())
158         return;
160     // Use local repr here. When repr is specified, use that one, but
161     // if repr==NULL, get the repr of namedview of active desktop.
162     Inkscape::XML::Node *local_repr = repr;
163     SPDocument *local_doc = doc;
164     if (!local_repr) {
165         // no repr specified, use active desktop's namedview's repr
166         SPDesktop *dt = SP_ACTIVE_DESKTOP;
167         if (!dt)
168             return;
169         local_repr = SP_OBJECT_REPR (sp_desktop_namedview(dt));
170         local_doc = sp_desktop_document(dt);
171     }
173     Inkscape::SVGOStringStream os;
174     os << _sel->getUnitAbbr();
176     _wr->setUpdating (true);
178     bool saved = sp_document_get_undo_sensitive (local_doc);
179     sp_document_set_undo_sensitive (local_doc, false);
180     local_repr->setAttribute(_key.c_str(), os.str().c_str());
181     local_doc->rroot->setAttribute("sodipodi:modified", "true");
182     sp_document_set_undo_sensitive (local_doc, saved);
183     sp_document_done (local_doc, SP_VERB_NONE,
184                       /* TODO: annotate */ "registered-widget.cpp: RegisteredUnitMenu::on_changed");
186     _wr->setUpdating (false);
190 RegisteredScalarUnit::RegisteredScalarUnit()
191 : _widget(0), _um(0)
195 RegisteredScalarUnit::~RegisteredScalarUnit()
197     if (_widget) delete _widget;
198     _value_changed_connection.disconnect();
201 void
202 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)
204     _widget = new ScalarUnit (label, tip, UNIT_TYPE_LINEAR, "", "", rum._sel);
205     _widget->initScalar (-1e6, 1e6);
206     _widget->setUnit (rum._sel->getUnitAbbr());
207     _widget->setDigits (2);
208     _key = key;
209     _um = rum._sel;
210     _value_changed_connection = _widget->signal_value_changed().connect (sigc::mem_fun (*this, &RegisteredScalarUnit::on_value_changed));
211     _wr = &wr;
213     repr = repr_in;
214     doc = doc_in;
215     if (repr && !doc)  // doc cannot be NULL when repr is not NULL
216         g_warning("Initialization of registered widget using defined repr but with doc==NULL");
219 ScalarUnit*
220 RegisteredScalarUnit::getSU()
222     return _widget;
225 void
226 RegisteredScalarUnit::setValue (double val)
228     _widget->setValue (val);
229     on_value_changed();
232 void
233 RegisteredScalarUnit::on_value_changed()
235     if (_wr->isUpdating())
236         return;
238     // Use local repr here. When repr is specified, use that one, but
239     // if repr==NULL, get the repr of namedview of active desktop.
240     Inkscape::XML::Node *local_repr = repr;
241     SPDocument *local_doc = doc;
242     if (!local_repr) {
243         // no repr specified, use active desktop's namedview's repr
244         SPDesktop *dt = SP_ACTIVE_DESKTOP;
245         if (!dt)
246             return;
247         local_repr = SP_OBJECT_REPR (sp_desktop_namedview(dt));
248         local_doc = sp_desktop_document(dt);
249     }
251     Inkscape::SVGOStringStream os;
252     os << _widget->getValue("");
253     if (_um)
254         os << _um->getUnitAbbr();
256     _wr->setUpdating (true);
258     bool saved = sp_document_get_undo_sensitive (local_doc);
259     sp_document_set_undo_sensitive (local_doc, false);
260     local_repr->setAttribute(_key.c_str(), os.str().c_str());
261     local_doc->rroot->setAttribute("sodipodi:modified", "true");
262     sp_document_set_undo_sensitive (local_doc, saved);
263     sp_document_done (local_doc, SP_VERB_NONE,
264                       /* TODO: annotate */ "registered-widget.cpp: RegisteredScalarUnit::on_value_changed");
266     _wr->setUpdating (false);
269 RegisteredColorPicker::RegisteredColorPicker()
270 : _label(0), _cp(0)
274 RegisteredColorPicker::~RegisteredColorPicker()
276     _changed_connection.disconnect();
277     if (_cp) delete _cp;
278     if (_label) delete _label;
281 void
282 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)
284     _label = new Gtk::Label (label, 1.0, 0.5);
285     _label->set_use_underline (true);
286     _cp = new ColorPicker (title,tip,0,true);
287     _label->set_mnemonic_widget (*_cp);
288     _ckey = ckey;
289     _akey = akey;
290     _wr = &wr;
291     _changed_connection = _cp->connectChanged (sigc::mem_fun (*this, &RegisteredColorPicker::on_changed));
293     repr = repr_in;
294     doc = doc_in;
295     if (repr && !doc)  // doc cannot be NULL when repr is not NULL
296         g_warning("Initialization of registered widget using defined repr but with doc==NULL");
299 void
300 RegisteredColorPicker::setRgba32 (guint32 rgba)
302     _cp->setRgba32 (rgba);
305 void
306 RegisteredColorPicker::closeWindow()
308     _cp->closeWindow();
311 void
312 RegisteredColorPicker::on_changed (guint32 rgba)
314     if (_wr->isUpdating())
315         return;
317     _wr->setUpdating (true);
319     // Use local repr here. When repr is specified, use that one, but
320     // if repr==NULL, get the repr of namedview of active desktop.
321     Inkscape::XML::Node *local_repr = repr;
322     SPDocument *local_doc = doc;
323     if (!local_repr) {
324         // no repr specified, use active desktop's namedview's repr
325         SPDesktop *dt = SP_ACTIVE_DESKTOP;
326         if (!dt)
327             return;
328         local_repr = SP_OBJECT_REPR (sp_desktop_namedview(dt));
329         local_doc = sp_desktop_document(dt);
330     }
332     gchar c[32];
333     sp_svg_write_color(c, 32, rgba);
334     bool saved = sp_document_get_undo_sensitive (local_doc);
335     sp_document_set_undo_sensitive (local_doc, false);
336     local_repr->setAttribute(_ckey.c_str(), c);
337     sp_repr_set_css_double(local_repr, _akey.c_str(), (rgba & 0xff) / 255.0);
338     local_doc->rroot->setAttribute("sodipodi:modified", "true");
339     sp_document_set_undo_sensitive (local_doc, saved);
340     sp_document_done (local_doc, SP_VERB_NONE,
341                       /* TODO: annotate */ "registered-widget.cpp: RegisteredColorPicker::on_changed");
343     _wr->setUpdating (false);
346 RegisteredSuffixedInteger::RegisteredSuffixedInteger()
347 : _label(0), _sb(0),
348   _adj(0.0,0.0,100.0,1.0,1.0,1.0),
349   _suffix(0)
353 RegisteredSuffixedInteger::~RegisteredSuffixedInteger()
355     _changed_connection.disconnect();
356     if (_label) delete _label;
357     if (_suffix) delete _suffix;
358     if (_sb) delete _sb;
361 void
362 RegisteredSuffixedInteger::init (const Glib::ustring& label, const Glib::ustring& suffix, const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
364     _key = key;
365     _label = new Gtk::Label (label);
366     _label->set_alignment (1.0, 0.5);
367     _label->set_use_underline();
368     _sb = new Gtk::SpinButton (_adj, 1.0, 0);
369     _label->set_mnemonic_widget (*_sb);
370     _suffix = new Gtk::Label (suffix);
371     _hbox.pack_start (*_sb, true, true, 0);
372     _hbox.pack_start (*_suffix, false, false, 0);
374     _changed_connection = _adj.signal_value_changed().connect (sigc::mem_fun(*this, &RegisteredSuffixedInteger::on_value_changed));
375     _wr = &wr;
377     repr = repr_in;
378     doc = doc_in;
379     if (repr && !doc)  // doc cannot be NULL when repr is not NULL
380         g_warning("Initialization of registered widget using defined repr but with doc==NULL");
383 void
384 RegisteredSuffixedInteger::setValue (int i)
386     _adj.set_value (i);
389 void
390 RegisteredSuffixedInteger::on_value_changed()
392     if (_wr->isUpdating())
393         return;
395     _wr->setUpdating (true);
397     // Use local repr here. When repr is specified, use that one, but
398     // if repr==NULL, get the repr of namedview of active desktop.
399     Inkscape::XML::Node *local_repr = repr;
400     SPDocument *local_doc = doc;
401     if (!local_repr) {
402         // no repr specified, use active desktop's namedview's repr
403         SPDesktop *dt = SP_ACTIVE_DESKTOP;
404         if (!dt)
405             return;
406         local_repr = SP_OBJECT_REPR (sp_desktop_namedview(dt));
407         local_doc = sp_desktop_document(dt);
408     }
410     Inkscape::SVGOStringStream os;
411     int value = int(_adj.get_value());
412     os << value;
414     local_repr->setAttribute(_key.c_str(), os.str().c_str());
415     sp_document_done(local_doc, SP_VERB_NONE,
416                      /* TODO: annotate */ "registered-widget.cpp: RegisteredSuffixedInteger::on_value_changed");
418     _wr->setUpdating (false);
421 RegisteredRadioButtonPair::RegisteredRadioButtonPair()
422 : _hbox(0)
426 RegisteredRadioButtonPair::~RegisteredRadioButtonPair()
428     _changed_connection.disconnect();
431 void
432 RegisteredRadioButtonPair::init (const Glib::ustring& label,
433 const Glib::ustring& label1, const Glib::ustring& label2,
434 const Glib::ustring& tip1, const Glib::ustring& tip2,
435 const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
437     _hbox = new Gtk::HBox;
438     _hbox->add (*manage (new Gtk::Label (label)));
439     _rb1 = manage (new Gtk::RadioButton (label1, true));
440     _hbox->add (*_rb1);
441     Gtk::RadioButtonGroup group = _rb1->get_group();
442     _rb2 = manage (new Gtk::RadioButton (group, label2, true));
443     _hbox->add (*_rb2);
444     _rb2->set_active();
445     _tt.set_tip (*_rb1, tip1);
446     _tt.set_tip (*_rb2, tip2);
447     _key = key;
448     _wr = &wr;
449     _changed_connection = _rb1->signal_toggled().connect (sigc::mem_fun (*this, &RegisteredRadioButtonPair::on_value_changed));
451     repr = repr_in;
452     doc = doc_in;
453     if (repr && !doc)  // doc cannot be NULL when repr is not NULL
454         g_error("Initialization of registered widget using defined repr but with doc==NULL");
457 void
458 RegisteredRadioButtonPair::setValue (bool second)
460     if (second) _rb2->set_active();
461     else        _rb1->set_active();
464 void
465 RegisteredRadioButtonPair::on_value_changed()
467     if (_wr->isUpdating())
468         return;
470     // Use local repr here. When repr is specified, use that one, but
471     // if repr==NULL, get the repr of namedview of active desktop.
472     Inkscape::XML::Node *local_repr = repr;
473     SPDocument *local_doc = doc;
474     if (!local_repr) {
475         // no repr specified, use active desktop's namedview's repr
476         SPDesktop *dt = SP_ACTIVE_DESKTOP;
477         if (!dt)
478             return;
479         local_repr = SP_OBJECT_REPR (sp_desktop_namedview(dt));
480         local_doc = sp_desktop_document(dt);
481     }
483     _wr->setUpdating (true);
485     bool second = _rb2->get_active();
486     bool saved = sp_document_get_undo_sensitive (local_doc);
487     sp_document_set_undo_sensitive (local_doc, false);
488     local_repr->setAttribute(_key.c_str(), second ? "true" : "false");
489     local_doc->rroot->setAttribute("sodipodi:modified", "true");
490     sp_document_set_undo_sensitive (local_doc, saved);
491     sp_document_done (local_doc, SP_VERB_NONE,
492                       /* TODO: annotate */ "registered-widget.cpp: RegisteredRadioButtonPair::on_value_changed");
494     _wr->setUpdating (false);
497 } // namespace Dialog
498 } // namespace UI
499 } // namespace Inkscape
501 /*
502   Local Variables:
503   mode:c++
504   c-file-style:"stroustrup"
505   c-file-offsets:((innamespace . 0)(inline-open . 0))
506   indent-tabs-mode:nil
507   fill-column:99
508   End:
509 */
510 // vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :