Code

Pot and Dutch translation update
[inkscape.git] / src / ui / widget / registered-widget.cpp
1 /** \file
2  *
3  *
4  * Authors:
5  *   Johan Engelen <j.b.c.engelen@utwente.nl>
6  *   bulia byak <buliabyak@users.sf.net>
7  *   Bryce W. Harrington <bryce@bryceharrington.org>
8  *   Lauris Kaplinski <lauris@kaplinski.com>
9  *   Jon Phillips <jon@rejon.org>
10  *   Ralf Stephan <ralf@ark.in-berlin.de> (Gtkmm)
11  *
12  * Copyright (C) 2000 - 2007 Authors
13  *
14  * Released under GNU GPL.  Read the file 'COPYING' for more information
15  */
17 #ifdef HAVE_CONFIG_H
18 # include <config.h>
19 #endif
21 #include "registered-widget.h"
23 #include "ui/widget/color-picker.h"
24 #include "ui/widget/registry.h"
25 #include "ui/widget/scalar-unit.h"
26 #include "ui/widget/point.h"
27 #include "ui/widget/random.h"
28 #include "widgets/spinbutton-events.h"
30 #include "helper/units.h"
31 #include "xml/repr.h"
32 #include "svg/svg-color.h"
33 #include "svg/stringstream.h"
35 #include "verbs.h"
37 // for interruptability bug:
38 #include "display/sp-canvas.h"
40 namespace Inkscape {
41 namespace UI {
42 namespace Widget {
44 /*#########################################
45  * Registered CHECKBUTTON
46  */
48 RegisteredCheckButton::~RegisteredCheckButton()
49 {
50     _toggled_connection.disconnect();
51 }
53 RegisteredCheckButton::RegisteredCheckButton (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& key, Registry& wr, bool right, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
54     : RegisteredWidget<Gtk::CheckButton>()
55 {
56     init_parent(key, wr, repr_in, doc_in);
58     setProgrammatically = false;
60     _tt.set_tip (*this, tip);
61     Gtk::Label *l = new Gtk::Label (label);
62     l->set_use_underline (true);
63     add (*manage (l));
64     set_alignment (right? 1.0 : 0.0, 0.5);
65     _toggled_connection = signal_toggled().connect (sigc::mem_fun (*this, &RegisteredCheckButton::on_toggled));
66 }
68 void
69 RegisteredCheckButton::setActive (bool b)
70 {
71     setProgrammatically = true;
72     set_active (b);
73     //The slave button is greyed out if the master button is unchecked
74     for (std::list<Gtk::Widget*>::const_iterator i = _slavewidgets.begin(); i != _slavewidgets.end(); i++) {
75         (*i)->set_sensitive(b);
76     }
77     setProgrammatically = false;
78 }
80 void
81 RegisteredCheckButton::on_toggled()
82 {
83     if (setProgrammatically) {
84         setProgrammatically = false;
85         return;
86     }
88     if (_wr->isUpdating())
89         return;
90     _wr->setUpdating (true);
92     write_to_xml(get_active() ? "true" : "false");
93     //The slave button is greyed out if the master button is unchecked
94     for (std::list<Gtk::Widget*>::const_iterator i = _slavewidgets.begin(); i != _slavewidgets.end(); i++) {
95         (*i)->set_sensitive(get_active());
96     }
98     _wr->setUpdating (false);
99 }
102 /*#########################################
103  * Registered UNITMENU
104  */
106 RegisteredUnitMenu::~RegisteredUnitMenu()
108     _changed_connection.disconnect();
111 RegisteredUnitMenu::RegisteredUnitMenu (const Glib::ustring& label, const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
112     :  RegisteredWidget<Labelled> (label, "" /*tooltip*/, new UnitMenu())
114     init_parent(key, wr, repr_in, doc_in);
116     getUnitMenu()->setUnitType (UNIT_TYPE_LINEAR);
117     _changed_connection = getUnitMenu()->signal_changed().connect (sigc::mem_fun (*this, &RegisteredUnitMenu::on_changed));
120 void
121 RegisteredUnitMenu::setUnit (const SPUnit* unit)
123     getUnitMenu()->setUnit (sp_unit_get_abbreviation (unit));
126 void
127 RegisteredUnitMenu::on_changed()
129     if (_wr->isUpdating())
130         return;
132     Inkscape::SVGOStringStream os;
133     os << getUnitMenu()->getUnitAbbr();
135     _wr->setUpdating (true);
137     write_to_xml(os.str().c_str());
139     _wr->setUpdating (false);
143 /*#########################################
144  * Registered SCALARUNIT
145  */
147 RegisteredScalarUnit::~RegisteredScalarUnit()
149     _value_changed_connection.disconnect();
152 RegisteredScalarUnit::RegisteredScalarUnit (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)
153     : RegisteredWidget<ScalarUnit>(label, tip, UNIT_TYPE_LINEAR, "", "", rum.getUnitMenu()),
154       _um(0)
156     init_parent(key, wr, repr_in, doc_in);
158     setProgrammatically = false;
160     initScalar (-1e6, 1e6);
161     setUnit (rum.getUnitMenu()->getUnitAbbr());
162     setDigits (2);
163     _um = rum.getUnitMenu();
164     _value_changed_connection = signal_value_changed().connect (sigc::mem_fun (*this, &RegisteredScalarUnit::on_value_changed));
168 void
169 RegisteredScalarUnit::on_value_changed()
171     if (setProgrammatically) {
172         setProgrammatically = false;
173         return;
174     }
176     if (_wr->isUpdating())
177         return;
179     _wr->setUpdating (true);
181     Inkscape::SVGOStringStream os;
182     os << getValue("");
183     if (_um)
184         os << _um->getUnitAbbr();
186     write_to_xml(os.str().c_str());
188     _wr->setUpdating (false);
192 /*#########################################
193  * Registered SCALAR
194  */
196 RegisteredScalar::~RegisteredScalar()
198     _value_changed_connection.disconnect();
201 RegisteredScalar::RegisteredScalar ( const Glib::ustring& label, const Glib::ustring& tip,
202                          const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in,
203                          SPDocument * doc_in )
204     : RegisteredWidget<Scalar>(label, tip)
206     init_parent(key, wr, repr_in, doc_in);
208     setProgrammatically = false;
210     setRange (-1e6, 1e6);
211     setDigits (2);
212     setIncrements(0.1, 1.0);
213     _value_changed_connection = signal_value_changed().connect (sigc::mem_fun (*this, &RegisteredScalar::on_value_changed));
216 void
217 RegisteredScalar::on_value_changed()
219     if (setProgrammatically) {
220         setProgrammatically = false;
221         return;
222     }
224     if (_wr->isUpdating()) {
225         return;
226     }
227     _wr->setUpdating (true);
229     Inkscape::SVGOStringStream os;
230     os << getValue();
232     set_sensitive(false);
233     write_to_xml(os.str().c_str());
234     set_sensitive(true);
236     _wr->setUpdating (false);
240 /*#########################################
241  * Registered TEXT
242  */
244 RegisteredText::~RegisteredText()
246     _activate_connection.disconnect();
249 RegisteredText::RegisteredText ( const Glib::ustring& label, const Glib::ustring& tip,
250                          const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in,
251                          SPDocument * doc_in )
252     : RegisteredWidget<Text>(label, tip)
254     init_parent(key, wr, repr_in, doc_in);
256     setProgrammatically = false;
258     setText("");
259     _activate_connection = signal_activate().connect (sigc::mem_fun (*this, &RegisteredText::on_activate));
262 void
263 RegisteredText::on_activate()
265     if (setProgrammatically) {
266         setProgrammatically = false;
267         return;
268     }
270     if (_wr->isUpdating()) {
271         return;
272     }
273     _wr->setUpdating (true);
275     Inkscape::SVGOStringStream os;
276     os << getText();
278     set_sensitive(false);
279     write_to_xml(os.str().c_str());
280     set_sensitive(true);
282     setText(os.str().c_str());
284     _wr->setUpdating (false);
288 /*#########################################
289  * Registered COLORPICKER
290  */
292 RegisteredColorPicker::RegisteredColorPicker(const Glib::ustring& label,
293                                              const Glib::ustring& title,
294                                              const Glib::ustring& tip,
295                                              const Glib::ustring& ckey,
296                                              const Glib::ustring& akey,
297                                              Registry& wr,
298                                              Inkscape::XML::Node* repr_in,
299                                              SPDocument *doc_in)
300     : RegisteredWidget<ColorPicker> (title, tip, 0, true)
302     init_parent("", wr, repr_in, doc_in);
304     _label = new Gtk::Label (label, 1.0, 0.5);
305     _label->set_use_underline (true);
306     _label->set_mnemonic_widget (*this);
307     _ckey = ckey;
308     _akey = akey;
309     _changed_connection = connectChanged (sigc::mem_fun (*this, &RegisteredColorPicker::on_changed));
312 RegisteredColorPicker::~RegisteredColorPicker()
314     _changed_connection.disconnect();
317 void
318 RegisteredColorPicker::setRgba32 (guint32 rgba)
320     ColorPicker::setRgba32 (rgba);
323 void
324 RegisteredColorPicker::closeWindow()
326     ColorPicker::closeWindow();
329 void
330 RegisteredColorPicker::on_changed (guint32 rgba)
332     if (_wr->isUpdating())
333         return;
335     _wr->setUpdating (true);
337     // Use local repr here. When repr is specified, use that one, but
338     // if repr==NULL, get the repr of namedview of active desktop.
339     Inkscape::XML::Node *local_repr = repr;
340     SPDocument *local_doc = doc;
341     if (!local_repr) {
342         // no repr specified, use active desktop's namedview's repr
343         SPDesktop *dt = SP_ACTIVE_DESKTOP;
344         if (!dt)
345             return;
346         local_repr = SP_OBJECT_REPR (sp_desktop_namedview(dt));
347         local_doc = sp_desktop_document(dt);
348     }
350     gchar c[32];
351     sp_svg_write_color(c, sizeof(c), rgba);
352     bool saved = sp_document_get_undo_sensitive (local_doc);
353     sp_document_set_undo_sensitive (local_doc, false);
354     local_repr->setAttribute(_ckey.c_str(), c);
355     sp_repr_set_css_double(local_repr, _akey.c_str(), (rgba & 0xff) / 255.0);
356     sp_document_set_undo_sensitive (local_doc, saved);
358     local_doc->setModifiedSinceSave();
359     sp_document_done (local_doc, SP_VERB_NONE,
360                       /* TODO: annotate */ "registered-widget.cpp: RegisteredColorPicker::on_changed");
362     _wr->setUpdating (false);
366 /*#########################################
367  * Registered SUFFIXEDINTEGER
368  */
370 RegisteredSuffixedInteger::~RegisteredSuffixedInteger()
372     _changed_connection.disconnect();
375 RegisteredSuffixedInteger::RegisteredSuffixedInteger (const Glib::ustring& label, const Glib::ustring& tip, const Glib::ustring& suffix, const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
376     : RegisteredWidget<Scalar>(label, tip, 0, suffix),
377       setProgrammatically(false)
379     init_parent(key, wr, repr_in, doc_in);
381     setRange (0, 1e6);
382     setDigits (0);
383     setIncrements(1, 10);
385     _changed_connection = signal_value_changed().connect (sigc::mem_fun(*this, &RegisteredSuffixedInteger::on_value_changed));
388 void
389 RegisteredSuffixedInteger::on_value_changed()
391     if (setProgrammatically) {
392         setProgrammatically = false;
393         return;
394     }
396     if (_wr->isUpdating())
397         return;
399     _wr->setUpdating (true);
401     Inkscape::SVGOStringStream os;
402     os << getValue();
404     write_to_xml(os.str().c_str());
406     _wr->setUpdating (false);
410 /*#########################################
411  * Registered RADIOBUTTONPAIR
412  */
414 RegisteredRadioButtonPair::~RegisteredRadioButtonPair()
416     _changed_connection.disconnect();
419 RegisteredRadioButtonPair::RegisteredRadioButtonPair (const Glib::ustring& label,
420         const Glib::ustring& label1, const Glib::ustring& label2,
421         const Glib::ustring& tip1, const Glib::ustring& tip2,
422         const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in, SPDocument *doc_in)
423     : RegisteredWidget<Gtk::HBox>(),
424       _rb1(NULL),
425       _rb2(NULL)
427     init_parent(key, wr, repr_in, doc_in);
429     setProgrammatically = false;
431     add (*manage (new Gtk::Label (label)));
432     _rb1 = manage (new Gtk::RadioButton (label1, true));
433     add (*_rb1);
434     Gtk::RadioButtonGroup group = _rb1->get_group();
435     _rb2 = manage (new Gtk::RadioButton (group, label2, true));
436     add (*_rb2);
437     _rb2->set_active();
438     _tt.set_tip (*_rb1, tip1);
439     _tt.set_tip (*_rb2, tip2);
440     _changed_connection = _rb1->signal_toggled().connect (sigc::mem_fun (*this, &RegisteredRadioButtonPair::on_value_changed));
443 void
444 RegisteredRadioButtonPair::setValue (bool second)
446     if (!_rb1 || !_rb2)
447         return;
449     setProgrammatically = true;
450     if (second) {
451         _rb2->set_active();
452     } else {
453         _rb1->set_active();
454     }
457 void
458 RegisteredRadioButtonPair::on_value_changed()
460     if (setProgrammatically) {
461         setProgrammatically = false;
462         return;
463     }
465     if (_wr->isUpdating())
466         return;
468     _wr->setUpdating (true);
470     bool second = _rb2->get_active();
471     write_to_xml(second ? "true" : "false");
473     _wr->setUpdating (false);
477 /*#########################################
478  * Registered POINT
479  */
481 RegisteredPoint::~RegisteredPoint()
483     _value_x_changed_connection.disconnect();
484     _value_y_changed_connection.disconnect();
487 RegisteredPoint::RegisteredPoint ( const Glib::ustring& label, const Glib::ustring& tip,
488                         const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in,
489                         SPDocument* doc_in )
490     : RegisteredWidget<Point> (label, tip)
492     init_parent(key, wr, repr_in, doc_in);
494     setRange (-1e6, 1e6);
495     setDigits (2);
496     setIncrements(0.1, 1.0);
497     _value_x_changed_connection = signal_x_value_changed().connect (sigc::mem_fun (*this, &RegisteredPoint::on_value_changed));
498     _value_y_changed_connection = signal_y_value_changed().connect (sigc::mem_fun (*this, &RegisteredPoint::on_value_changed));
501 void
502 RegisteredPoint::on_value_changed()
504     if (setProgrammatically()) {
505         clearProgrammatically();
506         return;
507     }
509     if (_wr->isUpdating())
510         return;
512     _wr->setUpdating (true);
514     Inkscape::SVGOStringStream os;
515     os << getXValue() << "," << getYValue();
517     write_to_xml(os.str().c_str());
519     _wr->setUpdating (false);
522 /*#########################################
523  * Registered TRANSFORMEDPOINT
524  */
526 RegisteredTransformedPoint::~RegisteredTransformedPoint()
528     _value_x_changed_connection.disconnect();
529     _value_y_changed_connection.disconnect();
532 RegisteredTransformedPoint::RegisteredTransformedPoint ( const Glib::ustring& label, const Glib::ustring& tip,
533                         const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in,
534                         SPDocument* doc_in )
535     : RegisteredWidget<Point> (label, tip),
536       to_svg(Geom::identity())
538     init_parent(key, wr, repr_in, doc_in);
540     setRange (-1e6, 1e6);
541     setDigits (2);
542     setIncrements(0.1, 1.0);
543     _value_x_changed_connection = signal_x_value_changed().connect (sigc::mem_fun (*this, &RegisteredTransformedPoint::on_value_changed));
544     _value_y_changed_connection = signal_y_value_changed().connect (sigc::mem_fun (*this, &RegisteredTransformedPoint::on_value_changed));
547 void
548 RegisteredTransformedPoint::setValue(Geom::Point const & p)
550     Geom::Point new_p = p * to_svg.inverse();
551     Point::setValue(new_p);  // the Point widget should display things in canvas coordinates
554 void
555 RegisteredTransformedPoint::setTransform(Geom::Matrix const & canvas_to_svg)
557     // check if matrix is singular / has inverse
558     if ( ! canvas_to_svg.isSingular() ) {
559         to_svg = canvas_to_svg;
560     } else {
561         // set back to default
562         to_svg = Geom::identity();
563     }
566 void
567 RegisteredTransformedPoint::on_value_changed()
569     if (setProgrammatically()) {
570         clearProgrammatically();
571         return;
572     }
574     if (_wr->isUpdating())
575         return;
577     _wr->setUpdating (true);
579     Geom::Point pos = getValue() * to_svg;
581     Inkscape::SVGOStringStream os;
582     os << pos;
584     write_to_xml(os.str().c_str());
586     _wr->setUpdating (false);
589 /*#########################################
590  * Registered TRANSFORMEDPOINT
591  */
593 RegisteredVector::~RegisteredVector()
595     _value_x_changed_connection.disconnect();
596     _value_y_changed_connection.disconnect();
599 RegisteredVector::RegisteredVector ( const Glib::ustring& label, const Glib::ustring& tip,
600                         const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in,
601                         SPDocument* doc_in )
602     : RegisteredWidget<Point> (label, tip),
603       _polar_coords(false)
605     init_parent(key, wr, repr_in, doc_in);
607     setRange (-1e6, 1e6);
608     setDigits (2);
609     setIncrements(0.1, 1.0);
610     _value_x_changed_connection = signal_x_value_changed().connect (sigc::mem_fun (*this, &RegisteredVector::on_value_changed));
611     _value_y_changed_connection = signal_y_value_changed().connect (sigc::mem_fun (*this, &RegisteredVector::on_value_changed));
614 void
615 RegisteredVector::setValue(Geom::Point const & p)
617     if (!_polar_coords) {
618         Point::setValue(p);
619     } else {
620         Geom::Point polar;
621         polar[Geom::X] = atan2(p) *180/M_PI;
622         polar[Geom::Y] = p.length();
623         Point::setValue(polar);
624     }
627 void
628 RegisteredVector::setValue(Geom::Point const & p, Geom::Point const & origin)
630     RegisteredVector::setValue(p);
631     _origin = origin;
634 /**
635  * Changes the widgets text to polar coordinates. The SVG output will still be a normal carthesian vector.
636  * Careful: when calling getValue(), the return value's X-coord will be the angle, Y-value will be the distance/length. 
637  * After changing the coords type (polar/non-polar), the value has to be reset (setValue).
638  */
639 void
640 RegisteredVector::setPolarCoords(bool polar_coords)
642     _polar_coords = polar_coords;
643     if (polar_coords) {
644         xwidget.setLabelText("Angle:");
645         ywidget.setLabelText("Distance:");
646     } else {
647         xwidget.setLabelText("X:");
648         ywidget.setLabelText("Y:");
649     }
652 void
653 RegisteredVector::on_value_changed()
655     if (setProgrammatically()) {
656         clearProgrammatically();
657         return;
658     }
660     if (_wr->isUpdating())
661         return;
663     _wr->setUpdating (true);
665     Geom::Point origin = _origin;
666     Geom::Point vector = getValue();
667     if (_polar_coords) {
668         vector = Geom::Point::polar(vector[Geom::X]*M_PI/180, vector[Geom::Y]);
669     }
671     Inkscape::SVGOStringStream os;
672     os << origin << " , " << vector;
674     write_to_xml(os.str().c_str());
676     _wr->setUpdating (false);
679 /*#########################################
680  * Registered RANDOM
681  */
683 RegisteredRandom::~RegisteredRandom()
685     _value_changed_connection.disconnect();
686     _reseeded_connection.disconnect();
689 RegisteredRandom::RegisteredRandom ( const Glib::ustring& label, const Glib::ustring& tip,
690                          const Glib::ustring& key, Registry& wr, Inkscape::XML::Node* repr_in,
691                          SPDocument * doc_in )
692     : RegisteredWidget<Random> (label, tip)
694     init_parent(key, wr, repr_in, doc_in);
696     setProgrammatically = false;
698     setRange (-1e6, 1e6);
699     setDigits (2);
700     setIncrements(0.1, 1.0);
701     _value_changed_connection = signal_value_changed().connect (sigc::mem_fun (*this, &RegisteredRandom::on_value_changed));
702     _reseeded_connection = signal_reseeded.connect(sigc::mem_fun(*this, &RegisteredRandom::on_value_changed));
705 void
706 RegisteredRandom::setValue (double val, long startseed)
708     Scalar::setValue (val);
709     setStartSeed(startseed);
712 void
713 RegisteredRandom::on_value_changed()
715     if (setProgrammatically) {
716         setProgrammatically = false;
717         return;
718     }
720     if (_wr->isUpdating()) {
721         return;
722     }
723     _wr->setUpdating (true);
725     Inkscape::SVGOStringStream os;
726     os << getValue() << ';' << getStartSeed();
728     set_sensitive(false);
729     write_to_xml(os.str().c_str());
730     set_sensitive(true);
732     _wr->setUpdating (false);
735 } // namespace Dialog
736 } // namespace UI
737 } // namespace Inkscape
739 /*
740   Local Variables:
741   mode:c++
742   c-file-style:"stroustrup"
743   c-file-offsets:((innamespace . 0)(inline-open . 0))
744   indent-tabs-mode:nil
745   fill-column:99
746   End:
747 */
748 // vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :