Code

ad4c7a9cd6908409389570dc8e4ab72f305ff9c0
[inkscape.git] / src / ui / widget / selected-style.cpp
1 /**
2  * \brief Selected style indicator (fill, stroke, opacity)
3  *
4  * Author:
5  *   buliabyak@gmail.com
6  *
7  * Copyright (C) 2005 author
8  *
9  * Released under GNU GPL.  Read the file 'COPYING' for more information.
10  */
12 #ifdef HAVE_CONFIG_H
13 # include <config.h>
14 #endif
16 #include <gtk/gtkdnd.h>
18 #include "selected-style.h"
20 #include "widgets/spw-utilities.h"
21 #include "ui/widget/color-preview.h"
23 #include "selection.h"
24 #include "desktop-handles.h"
25 #include "style.h"
26 #include "desktop-style.h"
27 #include "sp-linear-gradient-fns.h"
28 #include "sp-radial-gradient-fns.h"
29 #include "sp-pattern.h"
30 #include "dialogs/object-properties.h"
31 #include "xml/repr.h"
32 #include "document.h"
33 #include "widgets/widget-sizes.h"
34 #include "widgets/spinbutton-events.h"
35 #include "svg/svg-color.h"
36 #include "svg/css-ostringstream.h"
37 #include "helper/units.h"
38 #include "verbs.h"
40 static gdouble const _sw_presets[]     = { 32 ,  16 ,  10 ,  8 ,  6 ,  4 ,  3 ,  2 ,  1.5 ,  1 ,  0.75 ,  0.5 ,  0.25 ,  0.1 };
41 static gchar* const _sw_presets_str[] = {"32", "16", "10", "8", "6", "4", "3", "2", "1.5", "1", "0.75", "0.5", "0.25", "0.1"};
43 static void 
44 ss_selection_changed (Inkscape::Selection *, gpointer data)
45 {
46     Inkscape::UI::Widget::SelectedStyle *ss = (Inkscape::UI::Widget::SelectedStyle *) data;
47     ss->update();
48 }
50 static void
51 ss_selection_modified (Inkscape::Selection *selection, guint flags, gpointer data)
52 {
53     ss_selection_changed (selection, data);
54 }
56 static void
57 ss_subselection_changed (gpointer dragger, gpointer data)
58 {
59     ss_selection_changed (NULL, data);
60 }
62 namespace Inkscape {
63 namespace UI {
64 namespace Widget {
67 typedef struct {
68     SelectedStyle* parent;
69     int item;
70 } DropTracker;
72 /* Drag and Drop */
73 typedef enum {
74     APP_X_COLOR
75 } ui_drop_target_info;
77 static GtkTargetEntry ui_drop_target_entries [] = {
78     {"application/x-color", 0, APP_X_COLOR}
79 };
81 #define ENTRIES_SIZE(n) sizeof(n)/sizeof(n[0])
82 static guint nui_drop_target_entries = ENTRIES_SIZE(ui_drop_target_entries);
85 SelectedStyle::SelectedStyle(bool layout)
86     : _desktop (NULL),
88       _table(2, 6),
89       _fill_label (_("F:")),
90       _stroke_label (_("S:")),
91       _opacity_label (_("O:")),
92       _fill_place (),
93       _stroke_place (),
95       _fill_flag_place (),
96       _stroke_flag_place (),
98       _opacity_place (),
99       _opacity_adjustment (1.0, 0.0, 1.0, 0.01, 0.1),
100       _opacity_sb (0.02, 2),
102       _stroke (),
103       _stroke_width (""),
105       _opacity_blocked (false),
107       _popup_px(_sw_group),
108       _popup_pt(_sw_group),
109       _popup_mm(_sw_group),
111       _sw_unit(NULL),
113       _tooltips ()
116     _drop[0] = _drop[1] = 0;
117     _dropEnabled[0] = _dropEnabled[1] = false;
118     
119     _fill_label.set_alignment(0.0, 0.5);
120     _fill_label.set_padding(0, 0);
121     _stroke_label.set_alignment(0.0, 0.5);
122     _stroke_label.set_padding(0, 0);
123     _opacity_label.set_alignment(0.0, 0.5);
124     _opacity_label.set_padding(0, 0);
126     _table.set_col_spacings (2);
127     _table.set_row_spacings (0);
129     for (int i = SS_FILL; i <= SS_STROKE; i++) {
131         _na[i].set_markup (_("N/A"));
132         sp_set_font_size_smaller (GTK_WIDGET(_na[i].gobj()));
133         _na[i].show_all();
134         __na[i] = (_("Nothing selected"));
136         _none[i].set_markup (_("None"));
137         sp_set_font_size_smaller (GTK_WIDGET(_none[i].gobj()));
138         _none[i].show_all();
139         __none[i] = (i == SS_FILL)? (_("No fill")) : (_("No stroke"));
141         _pattern[i].set_markup (_("Pattern"));
142         sp_set_font_size_smaller (GTK_WIDGET(_pattern[i].gobj()));
143         _pattern[i].show_all();
144         __pattern[i] = (i == SS_FILL)? (_("Pattern fill")) : (_("Pattern stroke"));
146         _lgradient[i].set_markup (_("L Gradient"));
147         sp_set_font_size_smaller (GTK_WIDGET(_lgradient[i].gobj()));
148         _lgradient[i].show_all();
149         __lgradient[i] = (i == SS_FILL)? (_("Linear gradient fill")) : (_("Linear gradient stroke"));
151         _rgradient[i].set_markup (_("R Gradient"));
152         sp_set_font_size_smaller (GTK_WIDGET(_rgradient[i].gobj()));
153         _rgradient[i].show_all();
154         __rgradient[i] = (i == SS_FILL)? (_("Radial gradient fill")) : (_("Radial gradient stroke"));
156         _many[i].set_markup (_("Different"));
157         sp_set_font_size_smaller (GTK_WIDGET(_many[i].gobj()));
158         _many[i].show_all();
159         __many[i] = (i == SS_FILL)? (_("Different fills")) : (_("Different strokes"));
161         _unset[i].set_markup (_("Unset"));
162         sp_set_font_size_smaller (GTK_WIDGET(_unset[i].gobj()));
163         _unset[i].show_all();
164         __unset[i] = (i == SS_FILL)? (_("Unset fill")) : (_("Unset stroke"));
166         _color_preview[i] = new Inkscape::UI::Widget::ColorPreview (0);
167         __color[i] = (i == SS_FILL)? (_("Flat color fill")) : (_("Flat color stroke"));
169         // TRANSLATOR COMMENT: A means "Averaged"
170         _averaged[i].set_markup (_("<b>a</b>"));
171         sp_set_font_size_smaller (GTK_WIDGET(_averaged[i].gobj()));
172         _averaged[i].show_all();
173         __averaged[i] = (i == SS_FILL)? (_("Fill is averaged over selected objects")) : (_("Stroke is averaged over selected objects"));
175         // TRANSLATOR COMMENT: M means "Multiple"
176         _multiple[i].set_markup (_("<b>m</b>"));
177         sp_set_font_size_smaller (GTK_WIDGET(_multiple[i].gobj()));
178         _multiple[i].show_all();
179         __multiple[i] = (i == SS_FILL)? (_("Multiple selected objects have the same fill")) : (_("Multiple selected objects have the same stroke"));
181         _popup_edit[i].add(*(new Gtk::Label((i == SS_FILL)? _("Edit fill...") : _("Edit stroke..."), 0.0, 0.5)));
182         _popup_edit[i].signal_activate().connect(sigc::mem_fun(*this, 
183                                (i == SS_FILL)? &SelectedStyle::on_fill_edit : &SelectedStyle::on_stroke_edit ));
185         _popup_lastused[i].add(*(new Gtk::Label(_("Last set color"), 0.0, 0.5)));
186         _popup_lastused[i].signal_activate().connect(sigc::mem_fun(*this, 
187                                (i == SS_FILL)? &SelectedStyle::on_fill_lastused : &SelectedStyle::on_stroke_lastused ));
189         _popup_lastselected[i].add(*(new Gtk::Label(_("Last selected color"), 0.0, 0.5)));
190         _popup_lastselected[i].signal_activate().connect(sigc::mem_fun(*this, 
191                                (i == SS_FILL)? &SelectedStyle::on_fill_lastselected : &SelectedStyle::on_stroke_lastselected ));
193         _popup_invert[i].add(*(new Gtk::Label(_("Invert"), 0.0, 0.5)));
194         _popup_invert[i].signal_activate().connect(sigc::mem_fun(*this, 
195                                (i == SS_FILL)? &SelectedStyle::on_fill_invert : &SelectedStyle::on_stroke_invert ));
197         _popup_white[i].add(*(new Gtk::Label(_("White"), 0.0, 0.5)));
198         _popup_white[i].signal_activate().connect(sigc::mem_fun(*this, 
199                                (i == SS_FILL)? &SelectedStyle::on_fill_white : &SelectedStyle::on_stroke_white ));
201         _popup_black[i].add(*(new Gtk::Label(_("Black"), 0.0, 0.5)));
202         _popup_black[i].signal_activate().connect(sigc::mem_fun(*this, 
203                                (i == SS_FILL)? &SelectedStyle::on_fill_black : &SelectedStyle::on_stroke_black ));
205         _popup_copy[i].add(*(new Gtk::Label(_("Copy color"), 0.0, 0.5)));
206         _popup_copy[i].signal_activate().connect(sigc::mem_fun(*this, 
207                                (i == SS_FILL)? &SelectedStyle::on_fill_copy : &SelectedStyle::on_stroke_copy ));
209         _popup_paste[i].add(*(new Gtk::Label(_("Paste color"), 0.0, 0.5)));
210         _popup_paste[i].signal_activate().connect(sigc::mem_fun(*this, 
211                                (i == SS_FILL)? &SelectedStyle::on_fill_paste : &SelectedStyle::on_stroke_paste ));
213         _popup_swap[i].add(*(new Gtk::Label(_("Swap fill and stroke"), 0.0, 0.5)));
214         _popup_swap[i].signal_activate().connect(sigc::mem_fun(*this, 
215                                &SelectedStyle::on_fillstroke_swap));
217         _popup_opaque[i].add(*(new Gtk::Label((i == SS_FILL)? _("Make fill opaque") : _("Make stroke opaque"), 0.0, 0.5)));
218         _popup_opaque[i].signal_activate().connect(sigc::mem_fun(*this, 
219                                (i == SS_FILL)? &SelectedStyle::on_fill_opaque : &SelectedStyle::on_stroke_opaque ));
221         //TRANSLATORS COMMENT: unset is a verb here
222         _popup_unset[i].add(*(new Gtk::Label((i == SS_FILL)? _("Unset fill") : _("Unset stroke"), 0.0, 0.5)));
223         _popup_unset[i].signal_activate().connect(sigc::mem_fun(*this, 
224                                (i == SS_FILL)? &SelectedStyle::on_fill_unset : &SelectedStyle::on_stroke_unset ));
226         _popup_remove[i].add(*(new Gtk::Label((i == SS_FILL)? _("Remove fill") : _("Remove stroke"), 0.0, 0.5)));
227         _popup_remove[i].signal_activate().connect(sigc::mem_fun(*this, 
228                                (i == SS_FILL)? &SelectedStyle::on_fill_remove : &SelectedStyle::on_stroke_remove ));
230         _popup[i].attach(_popup_edit[i], 0,1, 0,1);
231           _popup[i].attach(*(new Gtk::SeparatorMenuItem()), 0,1, 1,2);
232         _popup[i].attach(_popup_lastused[i], 0,1, 2,3);
233         _popup[i].attach(_popup_lastselected[i], 0,1, 3,4);
234           _popup[i].attach(*(new Gtk::SeparatorMenuItem()), 0,1, 4,5);
235         _popup[i].attach(_popup_invert[i], 0,1, 5,6);
236           _popup[i].attach(*(new Gtk::SeparatorMenuItem()), 0,1, 6,7);
237         _popup[i].attach(_popup_white[i], 0,1, 7,8);
238         _popup[i].attach(_popup_black[i], 0,1, 8,9);
239           _popup[i].attach(*(new Gtk::SeparatorMenuItem()), 0,1, 9,10);
240         _popup[i].attach(_popup_copy[i], 0,1, 10,11);
241         _popup_copy[i].set_sensitive(false);
242         _popup[i].attach(_popup_paste[i], 0,1, 11,12);
243         _popup[i].attach(_popup_swap[i], 0,1, 12,13);
244           _popup[i].attach(*(new Gtk::SeparatorMenuItem()), 0,1, 13,14); 
245         _popup[i].attach(_popup_opaque[i], 0,1, 14,15);
246         _popup[i].attach(_popup_unset[i], 0,1, 15,16);
247         _popup[i].attach(_popup_remove[i], 0,1, 16,17);
248         _popup[i].show_all();
250         _mode[i] = SS_NA;
251     }
253     {
254         _popup_px.add(*(new Gtk::Label(_("px"), 0.0, 0.5)));
255         _popup_px.signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::on_popup_px));
256         _popup_sw.attach(_popup_px, 0,1, 0,1);
258         _popup_pt.add(*(new Gtk::Label(_("pt"), 0.0, 0.5)));
259         _popup_pt.signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::on_popup_pt));
260         _popup_sw.attach(_popup_pt, 0,1, 1,2);
262         _popup_mm.add(*(new Gtk::Label(_("mm"), 0.0, 0.5)));
263         _popup_mm.signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::on_popup_mm));
264         _popup_sw.attach(_popup_mm, 0,1, 2,3);
266         _popup_sw.attach(*(new Gtk::SeparatorMenuItem()), 0,1, 3,4);
268         for (guint i = 0; i < G_N_ELEMENTS(_sw_presets_str); ++i) {
269             Gtk::MenuItem *mi = Gtk::manage(new Gtk::MenuItem());
270             mi->add(*(new Gtk::Label(_sw_presets_str[i], 0.0, 0.5)));
271             mi->signal_activate().connect(sigc::bind<int>(sigc::mem_fun(*this, &SelectedStyle::on_popup_preset), i));
272             _popup_sw.attach(*mi, 0,1, 4+i, 5+i);
273         }
275         guint i = G_N_ELEMENTS(_sw_presets_str) + 5;
277         _popup_sw.attach(*(new Gtk::SeparatorMenuItem()), 0,1, i,i+1);
279         _popup_sw_remove.add(*(new Gtk::Label(_("Remove"), 0.0, 0.5)));
280         _popup_sw_remove.signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::on_stroke_remove));
281         _popup_sw.attach(_popup_sw_remove, 0,1, i+1,i+2);
283         _popup_sw.show_all();
284     }
286     _fill_place.signal_button_press_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_fill_click));
287     _stroke_place.signal_button_press_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_stroke_click));
288     _opacity_place.signal_button_press_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_opacity_click));
289     _stroke_width_place.signal_button_press_event().connect(sigc::mem_fun(*this, &SelectedStyle::on_sw_click));
291     _opacity_sb.signal_populate_popup().connect(sigc::mem_fun(*this, &SelectedStyle::on_opacity_menu));
292     _opacity_sb.signal_value_changed().connect(sigc::mem_fun(*this, &SelectedStyle::on_opacity_changed));
294     _fill_place.add(_na[SS_FILL]);
295     _tooltips.set_tip(_fill_place, __na[SS_FILL]);
297     _stroke_place.add(_na[SS_STROKE]);
298     _tooltips.set_tip(_stroke_place, __na[SS_STROKE]);
300     _stroke.pack_start(_stroke_place);
301     _stroke_width_place.add(_stroke_width);
302     _stroke.pack_start(_stroke_width_place, Gtk::PACK_SHRINK);
304     _opacity_sb.set_adjustment(_opacity_adjustment);
305     sp_set_font_size_smaller (GTK_WIDGET(_opacity_sb.gobj()));
306     _opacity_sb.set_size_request (SELECTED_STYLE_SB_WIDTH, -1);
307     _opacity_sb.set_sensitive (false);
309     _table.attach(_fill_label, 0,1, 0,1, Gtk::SHRINK, Gtk::SHRINK);
310     _table.attach(_stroke_label, 0,1, 1,2, Gtk::SHRINK, Gtk::SHRINK);
312     _table.attach(_fill_flag_place, 1,2, 0,1, Gtk::SHRINK, Gtk::SHRINK);
313     _table.attach(_stroke_flag_place, 1,2, 1,2, Gtk::SHRINK, Gtk::SHRINK);
315     _table.attach(_fill_place, 2,3, 0,1);
316     _table.attach(_stroke, 2,3, 1,2);
318     _opacity_place.add(_opacity_label);
319     _table.attach(_opacity_place, 4,5, 0,2, Gtk::SHRINK, Gtk::SHRINK);
320     _table.attach(_opacity_sb, 5,6, 0,2, Gtk::SHRINK, Gtk::SHRINK);
322     pack_start(_table, true, true, 2);
324     set_size_request (SELECTED_STYLE_WIDTH, -1);
326     sp_set_font_size_smaller (GTK_WIDGET(_opacity_label.gobj()));
327     sp_set_font_size_smaller (GTK_WIDGET(_opacity_sb.gobj()));
328     sp_set_font_size_smaller (GTK_WIDGET(_fill_place.gobj()));
329     sp_set_font_size_smaller (GTK_WIDGET(_fill_flag_place.gobj()));
330     sp_set_font_size_smaller (GTK_WIDGET(_stroke_place.gobj()));
331     sp_set_font_size_smaller (GTK_WIDGET(_stroke_flag_place.gobj()));
332     sp_set_font_size_smaller (GTK_WIDGET(_stroke_width.gobj()));
333     sp_set_font_size_smaller (GTK_WIDGET(_fill_label.gobj()));
334     sp_set_font_size_smaller (GTK_WIDGET(_stroke_label.gobj()));
336     _drop[SS_FILL] = new DropTracker();
337     ((DropTracker*)_drop[SS_FILL])->parent = this;
338     ((DropTracker*)_drop[SS_FILL])->item = SS_FILL;
340     _drop[SS_STROKE] = new DropTracker();
341     ((DropTracker*)_drop[SS_STROKE])->parent = this;
342     ((DropTracker*)_drop[SS_STROKE])->item = SS_STROKE;
344     g_signal_connect(_stroke_place.gobj(),
345                      "drag_data_received",
346                      G_CALLBACK(dragDataReceived),
347                      _drop[SS_STROKE]);
349     g_signal_connect(_fill_place.gobj(),
350                      "drag_data_received",
351                      G_CALLBACK(dragDataReceived),
352                      _drop[SS_FILL]);
355 SelectedStyle::~SelectedStyle()
357     selection_changed_connection->disconnect();
358     delete selection_changed_connection;
359     selection_modified_connection->disconnect();
360     delete selection_modified_connection;
361     subselection_changed_connection->disconnect();
362     delete subselection_changed_connection;
364     for (int i = SS_FILL; i <= SS_STROKE; i++) {
365         delete _color_preview[i];
366     }
368     delete (DropTracker*)_drop[SS_FILL];
369     delete (DropTracker*)_drop[SS_STROKE];
372 void
373 SelectedStyle::setDesktop(SPDesktop *desktop)
375     _desktop = desktop;
376     gtk_object_set_data (GTK_OBJECT(_opacity_sb.gobj()), "dtw", _desktop->canvas);
378     Inkscape::Selection *selection = sp_desktop_selection (desktop);
380     selection_changed_connection = new sigc::connection (selection->connectChanged(
381         sigc::bind (
382             sigc::ptr_fun(&ss_selection_changed),
383             this )
384     ));
385     selection_modified_connection = new sigc::connection (selection->connectModified(
386         sigc::bind (
387             sigc::ptr_fun(&ss_selection_modified),
388             this )
389     ));
390     subselection_changed_connection = new sigc::connection (desktop->connectToolSubselectionChanged(
391         sigc::bind (
392             sigc::ptr_fun(&ss_subselection_changed),
393             this )
394     ));
396     //_sw_unit = (SPUnit *) sp_desktop_namedview(desktop)->doc_units;
399 void SelectedStyle::dragDataReceived( GtkWidget *widget,
400                                       GdkDragContext *drag_context,
401                                       gint x, gint y,
402                                       GtkSelectionData *data,
403                                       guint info,
404                                       guint event_time,
405                                       gpointer user_data )
407     DropTracker* tracker = (DropTracker*)user_data;
409     switch ( (int)tracker->item ) {
410         case SS_FILL:
411         case SS_STROKE:
412         {
413             if ( data->length == 8 ) {
414                 gchar c[64];
415                 // Careful about endian issues.
416                 guint16* dataVals = (guint16*)data->data;
417                 sp_svg_write_color( c, 64,
418                                     SP_RGBA32_U_COMPOSE(
419                                         0x0ff & (dataVals[0] >> 8),
420                                         0x0ff & (dataVals[1] >> 8),
421                                         0x0ff & (dataVals[2] >> 8),
422                                         0xff // can't have transparency in the color itself
423                                         //0x0ff & (data->data[3] >> 8),
424                                         ));
425                 SPCSSAttr *css = sp_repr_css_attr_new();
426                 sp_repr_css_set_property( css, (tracker->item == SS_FILL) ? "fill":"stroke", c );
427                 sp_desktop_set_style( tracker->parent->_desktop, css );
428                 sp_repr_css_attr_unref( css );
429                 sp_document_done( sp_desktop_document(tracker->parent->_desktop) , SP_VERB_NONE, 
430                                   /* TODO: annotate */ "selected-style.cpp:429");
431             }
432         }
433         break;
434     }
437 void SelectedStyle::on_fill_remove() {
438     SPCSSAttr *css = sp_repr_css_attr_new ();
439     sp_repr_css_set_property (css, "fill", "none");
440     sp_desktop_set_style (_desktop, css, true, true); 
441     sp_repr_css_attr_unref (css);
442     sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
443                       /* TODO: annotate */ "selected-style.cpp:442");
446 void SelectedStyle::on_stroke_remove() {
447     SPCSSAttr *css = sp_repr_css_attr_new ();
448     sp_repr_css_set_property (css, "stroke", "none");
449     sp_desktop_set_style (_desktop, css, true, true); 
450     sp_repr_css_attr_unref (css);
451     sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
452                       /* TODO: annotate */ "selected-style.cpp:451");
455 void SelectedStyle::on_fill_unset() {
456     SPCSSAttr *css = sp_repr_css_attr_new ();
457     sp_repr_css_unset_property (css, "fill");
458     sp_desktop_set_style (_desktop, css, true, true); 
459     sp_repr_css_attr_unref (css);
460     sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
461                       /* TODO: annotate */ "selected-style.cpp:460");
464 void SelectedStyle::on_stroke_unset() {
465     SPCSSAttr *css = sp_repr_css_attr_new ();
466     sp_repr_css_unset_property (css, "stroke");
467     sp_desktop_set_style (_desktop, css, true, true);
468     sp_repr_css_attr_unref (css);
469     sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
470                       /* TODO: annotate */ "selected-style.cpp:469");
473 void SelectedStyle::on_fill_opaque() {
474     SPCSSAttr *css = sp_repr_css_attr_new ();
475     sp_repr_css_set_property (css, "fill-opacity", "1");
476     sp_desktop_set_style (_desktop, css, true);
477     sp_repr_css_attr_unref (css);
478     sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
479                       /* TODO: annotate */ "selected-style.cpp:478");
482 void SelectedStyle::on_stroke_opaque() {
483     SPCSSAttr *css = sp_repr_css_attr_new ();
484     sp_repr_css_set_property (css, "stroke-opacity", "1");
485     sp_desktop_set_style (_desktop, css, true);
486     sp_repr_css_attr_unref (css);
487     sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
488                       /* TODO: annotate */ "selected-style.cpp:487");
491 void SelectedStyle::on_fill_lastused() {
492     SPCSSAttr *css = sp_repr_css_attr_new ();
493     guint32 color = sp_desktop_get_color(_desktop, true);
494     gchar c[64];
495     sp_svg_write_color (c, 64, color);
496     sp_repr_css_set_property (css, "fill", c);
497     sp_desktop_set_style (_desktop, css);
498     sp_repr_css_attr_unref (css);
499     sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, 
500                       /* TODO: annotate */ "selected-style.cpp:499");
503 void SelectedStyle::on_stroke_lastused() {
504     SPCSSAttr *css = sp_repr_css_attr_new ();
505     guint32 color = sp_desktop_get_color(_desktop, false);
506     gchar c[64];
507     sp_svg_write_color (c, 64, color);
508     sp_repr_css_set_property (css, "stroke", c);
509     sp_desktop_set_style (_desktop, css);
510     sp_repr_css_attr_unref (css);
511     sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, 
512                       /* TODO: annotate */ "selected-style.cpp:511");
515 void SelectedStyle::on_fill_lastselected() {
516     SPCSSAttr *css = sp_repr_css_attr_new ();
517     gchar c[64];
518     sp_svg_write_color (c, 64, _lastselected[SS_FILL]);
519     sp_repr_css_set_property (css, "fill", c);
520     sp_desktop_set_style (_desktop, css);
521     sp_repr_css_attr_unref (css);
522     sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
523                       /* TODO: annotate */ "selected-style.cpp:522");
526 void SelectedStyle::on_stroke_lastselected() {
527     SPCSSAttr *css = sp_repr_css_attr_new ();
528     gchar c[64];
529     sp_svg_write_color (c, 64, _lastselected[SS_STROKE]);
530     sp_repr_css_set_property (css, "stroke", c);
531     sp_desktop_set_style (_desktop, css);
532     sp_repr_css_attr_unref (css);
533     sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, 
534                       /* TODO: annotate */ "selected-style.cpp:533");
537 void SelectedStyle::on_fill_invert() {
538     SPCSSAttr *css = sp_repr_css_attr_new ();
539     guint32 color = _thisselected[SS_FILL];
540     gchar c[64];
541     if (_mode[SS_FILL] != SS_COLOR) return;
542     sp_svg_write_color (c, 64,
543         SP_RGBA32_U_COMPOSE(
544                 (255 - SP_RGBA32_R_U(color)),
545                 (255 - SP_RGBA32_G_U(color)),
546                 (255 - SP_RGBA32_B_U(color)),
547                 SP_RGBA32_A_U(color)
548         )
549     );
550     sp_repr_css_set_property (css, "fill", c);
551     sp_desktop_set_style (_desktop, css);
552     sp_repr_css_attr_unref (css);
553     sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
554                       /* TODO: annotate */ "selected-style.cpp:553");
557 void SelectedStyle::on_stroke_invert() {
558     SPCSSAttr *css = sp_repr_css_attr_new ();
559     guint32 color = _thisselected[SS_STROKE];
560     gchar c[64];
561     if (_mode[SS_STROKE] != SS_COLOR) return;
562     sp_svg_write_color (c, 64,
563         SP_RGBA32_U_COMPOSE(
564                 (255 - SP_RGBA32_R_U(color)),
565                 (255 - SP_RGBA32_G_U(color)),
566                 (255 - SP_RGBA32_B_U(color)),
567                 SP_RGBA32_A_U(color)
568         )
569     );
570     sp_repr_css_set_property (css, "stroke", c);
571     sp_desktop_set_style (_desktop, css);
572     sp_repr_css_attr_unref (css);
573     sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
574                       /* TODO: annotate */ "selected-style.cpp:573");
575
577 void SelectedStyle::on_fill_white() {
578     SPCSSAttr *css = sp_repr_css_attr_new ();
579     gchar c[64];
580     sp_svg_write_color (c, 64, 0xffffffff);
581     sp_repr_css_set_property (css, "fill", c);
582     sp_repr_css_set_property (css, "fill-opacity", "1");
583     sp_desktop_set_style (_desktop, css);
584     sp_repr_css_attr_unref (css);
585     sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
586                       /* TODO: annotate */ "selected-style.cpp:585");
589 void SelectedStyle::on_stroke_white() {
590     SPCSSAttr *css = sp_repr_css_attr_new ();
591     gchar c[64];
592     sp_svg_write_color (c, 64, 0xffffffff);
593     sp_repr_css_set_property (css, "stroke", c);
594     sp_repr_css_set_property (css, "stroke-opacity", "1");
595     sp_desktop_set_style (_desktop, css);
596     sp_repr_css_attr_unref (css);
597     sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, 
598                       /* TODO: annotate */ "selected-style.cpp:597");
601 void SelectedStyle::on_fill_black() {
602     SPCSSAttr *css = sp_repr_css_attr_new ();
603     gchar c[64];
604     sp_svg_write_color (c, 64, 0x000000ff);
605     sp_repr_css_set_property (css, "fill", c);
606     sp_repr_css_set_property (css, "fill-opacity", "1.0");
607     sp_desktop_set_style (_desktop, css);
608     sp_repr_css_attr_unref (css);
609     sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, 
610                       /* TODO: annotate */ "selected-style.cpp:609");
613 void SelectedStyle::on_stroke_black() {
614     SPCSSAttr *css = sp_repr_css_attr_new ();
615     gchar c[64];
616     sp_svg_write_color (c, 64, 0x000000ff);
617     sp_repr_css_set_property (css, "stroke", c);
618     sp_repr_css_set_property (css, "stroke-opacity", "1.0");
619     sp_desktop_set_style (_desktop, css);
620     sp_repr_css_attr_unref (css);
621     sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, 
622                       /* TODO: annotate */ "selected-style.cpp:621");
625 void SelectedStyle::on_fill_copy() {
626     if (_mode[SS_FILL] == SS_COLOR) {
627         gchar c[64];
628         sp_svg_write_color (c, 64, _thisselected[SS_FILL]);
629         Glib::ustring text;
630         text += c;
631         if (!text.empty()) {
632             Glib::RefPtr<Gtk::Clipboard> refClipboard = Gtk::Clipboard::get();
633             refClipboard->set_text(text);
634         }
635     }
638 void SelectedStyle::on_stroke_copy() {
639     if (_mode[SS_STROKE] == SS_COLOR) {
640         gchar c[64];
641         sp_svg_write_color (c, 64, _thisselected[SS_STROKE]);
642         Glib::ustring text;
643         text += c;
644         if (!text.empty()) {
645             Glib::RefPtr<Gtk::Clipboard> refClipboard = Gtk::Clipboard::get();
646             refClipboard->set_text(text);
647         }
648     }
651 void SelectedStyle::on_fill_paste() {
652     Glib::RefPtr<Gtk::Clipboard> refClipboard = Gtk::Clipboard::get();
653     Glib::ustring const text = refClipboard->wait_for_text();
655     if (!text.empty()) {
656         guint32 color = sp_svg_read_color(text.c_str(), 0x000000ff); // impossible value, as SVG color cannot have opacity
657         if (color == 0x000000ff) // failed to parse color string
658             return;
660         SPCSSAttr *css = sp_repr_css_attr_new ();
661         sp_repr_css_set_property (css, "fill", text.c_str());
662         sp_desktop_set_style (_desktop, css);
663         sp_repr_css_attr_unref (css);
664         sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, 
665                           /* TODO: annotate */ "selected-style.cpp:664");
666     }
669 void SelectedStyle::on_stroke_paste() {
670     Glib::RefPtr<Gtk::Clipboard> refClipboard = Gtk::Clipboard::get();
671     Glib::ustring const text = refClipboard->wait_for_text();
673     if (!text.empty()) {
674         guint32 color = sp_svg_read_color(text.c_str(), 0x000000ff); // impossible value, as SVG color cannot have opacity
675         if (color == 0x000000ff) // failed to parse color string
676             return;
678         SPCSSAttr *css = sp_repr_css_attr_new ();
679         sp_repr_css_set_property (css, "stroke", text.c_str());
680         sp_desktop_set_style (_desktop, css);
681         sp_repr_css_attr_unref (css);
682         sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE,
683                           /* TODO: annotate */ "selected-style.cpp:682");
684     }
687 void SelectedStyle::on_fillstroke_swap() {
688     SPCSSAttr *css = sp_repr_css_attr_new ();
690     g_message("on_fillstroke_swap()");
692     switch (_mode[SS_FILL]) {
693     case SS_NA:
694     case SS_MANY:
695         break;
696     case SS_NONE:
697         sp_repr_css_set_property (css, "stroke", "none");
698         break;
699     case SS_UNSET:
700         sp_repr_css_unset_property (css, "stroke");
701         break;
702     case SS_COLOR:
703         gchar c[64];
704         sp_svg_write_color (c, 64, _thisselected[SS_FILL]);
705         sp_repr_css_set_property (css, "stroke", c);
706         break;
707     case SS_LGRADIENT:
708     case SS_RGRADIENT:
709     case SS_PATTERN:
710         sp_repr_css_set_property (css, "stroke", _paintserver_id[SS_FILL].c_str());
711         break;
712     }
714     switch (_mode[SS_STROKE]) {
715     case SS_NA:
716     case SS_MANY:
717         break;
718     case SS_NONE:
719         sp_repr_css_set_property (css, "fill", "none");
720         break;
721     case SS_UNSET:
722         sp_repr_css_unset_property (css, "fill");
723         break;
724     case SS_COLOR:
725         gchar c[64];
726         sp_svg_write_color (c, 64, _thisselected[SS_STROKE]);
727         sp_repr_css_set_property (css, "fill", c);
728         break;
729     case SS_LGRADIENT:
730     case SS_RGRADIENT:
731     case SS_PATTERN:
732         sp_repr_css_set_property (css, "fill", _paintserver_id[SS_STROKE].c_str());
733         break;
734     }
736     sp_desktop_set_style (_desktop, css);
737     sp_repr_css_attr_unref (css);
738     sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_FILL_STROKE, 
739                       /* TODO: annotate */ "selected-style.cpp:738");
742 void SelectedStyle::on_fill_edit() {
743     sp_object_properties_fill();
746 void SelectedStyle::on_stroke_edit() {
747     sp_object_properties_stroke();
750 bool 
751 SelectedStyle::on_fill_click(GdkEventButton *event)
753     if (event->button == 1) { // click, open fill&stroke
754         sp_object_properties_fill();
755     } else if (event->button == 3) { // right-click, popup menu
756         _popup[SS_FILL].popup(event->button, event->time);
757     } else if (event->button == 2) { // middle click, toggle none/lastcolor
758         if (_mode[SS_FILL] == SS_NONE) {
759             on_fill_lastused();
760         } else {
761             on_fill_remove();
762         }
763     }
764     return true;
767 bool 
768 SelectedStyle::on_stroke_click(GdkEventButton *event)
770     if (event->button == 1) { // click, open fill&stroke
771         sp_object_properties_stroke();
772     } else if (event->button == 3) { // right-click, popup menu
773         _popup[SS_STROKE].popup(event->button, event->time);
774     } else if (event->button == 2) { // middle click, toggle none/lastcolor
775         if (_mode[SS_STROKE] == SS_NONE) {
776             on_stroke_lastused();
777         } else {
778             on_stroke_remove();
779         }
780     }
781     return true;
784 bool 
785 SelectedStyle::on_sw_click(GdkEventButton *event)
787     if (event->button == 1) { // click, open fill&stroke
788         sp_object_properties_stroke_style ();
789     } else if (event->button == 3) { // right-click, popup menu
790         _popup_sw.popup(event->button, event->time);
791     } else if (event->button == 2) { // middle click, toggle none/lastwidth?
792         //
793     }
794     return true;
797 bool 
798 SelectedStyle::on_opacity_click(GdkEventButton *event)
800     if (event->button == 2) { // middle click
801         const char* opacity = _opacity_sb.get_value() < 0.5? "0.5" : (_opacity_sb.get_value() == 1? "0" : "1");
802         SPCSSAttr *css = sp_repr_css_attr_new ();
803         sp_repr_css_set_property (css, "opacity", opacity);
804         sp_desktop_set_style (_desktop, css);
805         sp_repr_css_attr_unref (css);
806         sp_document_done (sp_desktop_document (_desktop), SP_VERB_DIALOG_FILL_STROKE,
807                           /* TODO: annotate */ "selected-style.cpp:806");
808         return true;
809     }
811     return false;
814 void SelectedStyle::on_popup_px() {
815     _sw_unit = (SPUnit *) &(sp_unit_get_by_id(SP_UNIT_PX));
816     update();
818 void SelectedStyle::on_popup_pt() {
819     _sw_unit = (SPUnit *) &(sp_unit_get_by_id(SP_UNIT_PT));
820     update();
822 void SelectedStyle::on_popup_mm() {
823     _sw_unit = (SPUnit *) &(sp_unit_get_by_id(SP_UNIT_MM));
824     update();
827 void SelectedStyle::on_popup_preset(int i) {
828     SPCSSAttr *css = sp_repr_css_attr_new ();
829     gdouble w;
830     if (_sw_unit) {
831         w = sp_units_get_pixels (_sw_presets[i], *_sw_unit);
832     } else {
833         w = _sw_presets[i];
834     }
835     Inkscape::CSSOStringStream os;
836     os << w;
837     sp_repr_css_set_property (css, "stroke-width", os.str().c_str());
838     sp_desktop_set_style (_desktop, css, true);
839     sp_repr_css_attr_unref (css);
840     sp_document_done (sp_desktop_document(_desktop), SP_VERB_DIALOG_SWATCHES,
841                       /* TODO: annotate */ "selected-style.cpp:840");
844 void
845 SelectedStyle::update()
847     if (_desktop == NULL)
848         return;
850     // create temporary style
851     SPStyle *query = sp_style_new ();
853     for (int i = SS_FILL; i <= SS_STROKE; i++) {
854         Gtk::EventBox *place = (i == SS_FILL)? &_fill_place : &_stroke_place;
855         Gtk::EventBox *flag_place = (i == SS_FILL)? &_fill_flag_place : &_stroke_flag_place;
857         place->remove();
858         flag_place->remove();
860         _tooltips.unset_tip(*place);
861         _tooltips.unset_tip(*flag_place);
863         _mode[i] = SS_NA;
864         _paintserver_id[i].clear();
866         _popup_copy[i].set_sensitive(false);
868         // query style from desktop. This returns a result flag and fills query with the style of subselection, if any, or selection
869         int result = sp_desktop_query_style (_desktop, query, 
870                                              (i == SS_FILL)? QUERY_STYLE_PROPERTY_FILL : QUERY_STYLE_PROPERTY_STROKE);
871         switch (result) {
872         case QUERY_STYLE_NOTHING:
873             place->add(_na[i]);
874             _tooltips.set_tip(*place, __na[i]);
875             _mode[i] = SS_NA;
876             if ( _dropEnabled[i] ) {
877                 gtk_drag_dest_unset( GTK_WIDGET((i==SS_FILL) ? _fill_place.gobj():_stroke_place.gobj()) );
878                 _dropEnabled[i] = false;
879             }
880             break;
881         case QUERY_STYLE_SINGLE:
882         case QUERY_STYLE_MULTIPLE_AVERAGED:
883         case QUERY_STYLE_MULTIPLE_SAME: 
884             if ( !_dropEnabled[i] ) {
885                 gtk_drag_dest_set( GTK_WIDGET( (i==SS_FILL) ? _fill_place.gobj():_stroke_place.gobj()),
886                                    GTK_DEST_DEFAULT_ALL,
887                                    ui_drop_target_entries,
888                                    nui_drop_target_entries,
889                                    GdkDragAction(GDK_ACTION_COPY | GDK_ACTION_MOVE) );
890                 _dropEnabled[i] = true;
891             }
892             SPIPaint *paint;
893             if (i == SS_FILL) {
894                 paint = &(query->fill);
895             } else {
896                 paint = &(query->stroke);
897             }
898             if (paint->set && paint->type == SP_PAINT_TYPE_COLOR) {
899                 guint32 color = sp_color_get_rgba32_falpha (&(paint->value.color), 
900                                      SP_SCALE24_TO_FLOAT ((i == SS_FILL)? query->fill_opacity.value : query->stroke_opacity.value));
901                 _lastselected[i] = _thisselected[i];
902                 _thisselected[i] = color | 0xff; // only color, opacity === 1
903                 ((Inkscape::UI::Widget::ColorPreview*)_color_preview[i])->setRgba32 (color);
904                 _color_preview[i]->show_all();
905                 place->add(*_color_preview[i]);
906                 gchar c_string[64];
907                 g_snprintf (c_string, 64, "%06x/%.3g", color >> 8, SP_RGBA32_A_F(color));
908                 _tooltips.set_tip(*place, __color[i] + ": " + c_string);
909                 _mode[i] = SS_COLOR;
910                 _popup_copy[i].set_sensitive(true);
912             } else if (paint->set && paint->type == SP_PAINT_TYPE_PAINTSERVER) {
913                 SPPaintServer *server = (i == SS_FILL)? SP_STYLE_FILL_SERVER (query) : SP_STYLE_STROKE_SERVER (query);
914                 if ( server ) {
915                     Inkscape::XML::Node *srepr = SP_OBJECT_REPR(server);
916                     _paintserver_id[i] += "url(#";
917                     _paintserver_id[i] += srepr->attribute("id");
918                     _paintserver_id[i] += ")";
920                     if (SP_IS_LINEARGRADIENT (server)) {
921                         place->add(_lgradient[i]);
922                         _tooltips.set_tip(*place, __lgradient[i]);
923                         _mode[i] = SS_LGRADIENT;
924                     } else if (SP_IS_RADIALGRADIENT (server)) {
925                         place->add(_rgradient[i]);
926                         _tooltips.set_tip(*place, __rgradient[i]);
927                         _mode[i] = SS_RGRADIENT;
928                     } else if (SP_IS_PATTERN (server)) {
929                         place->add(_pattern[i]);
930                         _tooltips.set_tip(*place, __pattern[i]);
931                         _mode[i] = SS_PATTERN;
932                     }
933                 } else {
934                     g_warning ("file %s: line %d: Unknown paint server", __FILE__, __LINE__);
935                 }
937             } else if (paint->set && paint->type == SP_PAINT_TYPE_NONE) {
938                 place->add(_none[i]);
939                 _tooltips.set_tip(*place, __none[i]);
940                 _mode[i] = SS_NONE;
941             } else if (!paint->set) {
942                 place->add(_unset[i]);
943                 _tooltips.set_tip(*place, __unset[i]);
944                 _mode[i] = SS_UNSET;
945             }
946             if (result == QUERY_STYLE_MULTIPLE_AVERAGED) {
947                 flag_place->add(_averaged[i]);
948                 _tooltips.set_tip(*flag_place, __averaged[i]);
949             } else if (result == QUERY_STYLE_MULTIPLE_SAME) {
950                 flag_place->add(_multiple[i]);
951                 _tooltips.set_tip(*flag_place, __multiple[i]);
952             }
953             break;
954         case QUERY_STYLE_MULTIPLE_DIFFERENT:
955             place->add(_many[i]);
956             _tooltips.set_tip(*place, __many[i]);
957             _mode[i] = SS_MANY;
958             break;
959         default:
960             break;
961         }
962     }
964 // Now query opacity
965     _tooltips.unset_tip(_opacity_place);
967     int result = sp_desktop_query_style (_desktop, query, QUERY_STYLE_PROPERTY_MASTEROPACITY);
969     switch (result) {
970     case QUERY_STYLE_NOTHING:
971         _tooltips.set_tip(_opacity_place, _("Nothing selected"));
972         _opacity_sb.set_sensitive(false);
973         break;
974     case QUERY_STYLE_SINGLE:
975     case QUERY_STYLE_MULTIPLE_AVERAGED:
976     case QUERY_STYLE_MULTIPLE_SAME:
977         _tooltips.set_tip(_opacity_place, _("Master opacity"));
978         _opacity_blocked = true;
979         _opacity_sb.set_sensitive(true);
980         _opacity_adjustment.set_value(SP_SCALE24_TO_FLOAT(query->opacity.value));
981         _opacity_blocked = false;
982         break;
983     }
985 // Now query stroke_width
986     int result_sw = sp_desktop_query_style (_desktop, query, QUERY_STYLE_PROPERTY_STROKEWIDTH);
987     switch (result_sw) {
988     case QUERY_STYLE_NOTHING:
989         _stroke_width.set_markup("");
990         break;
991     case QUERY_STYLE_SINGLE:
992     case QUERY_STYLE_MULTIPLE_AVERAGED:
993     case QUERY_STYLE_MULTIPLE_SAME: 
994     {
995         double w;
996         if (_sw_unit) {
997             w = sp_pixels_get_units(query->stroke_width.computed, *_sw_unit);
998         } else {
999             w = query->stroke_width.computed;
1000         }
1001         {
1002             gchar *str = g_strdup_printf(" %.3g", w);
1003             _stroke_width.set_markup(str);
1004             g_free (str);
1005         }
1006         {
1007             gchar *str = g_strdup_printf(_("Stroke width: %.5g%s%s"), 
1008                                          w, 
1009                                          _sw_unit? sp_unit_get_abbreviation(_sw_unit) : "px", 
1010                                          (result_sw == QUERY_STYLE_MULTIPLE_AVERAGED)?
1011                                          _(" (averaged)") : "");
1012             _tooltips.set_tip(_stroke_width_place, str);
1013             g_free (str);
1014         }
1015         break;
1016     }
1017     default:
1018         break;
1019     }
1021     g_free (query);
1024 void SelectedStyle::opacity_0(void) {_opacity_sb.set_value(0);}
1025 void SelectedStyle::opacity_025(void) {_opacity_sb.set_value(0.25);}
1026 void SelectedStyle::opacity_05(void) {_opacity_sb.set_value(0.5);}
1027 void SelectedStyle::opacity_075(void) {_opacity_sb.set_value(0.75);}
1028 void SelectedStyle::opacity_1(void) {_opacity_sb.set_value(1.0);}
1030 void SelectedStyle::on_opacity_menu (Gtk::Menu *menu) {
1032     Glib::ListHandle<Gtk::Widget *> children = menu->get_children();
1033     for (Glib::ListHandle<Gtk::Widget *>::iterator iter = children.begin(); iter != children.end(); iter++) {
1034         menu->remove(*(*iter));
1035     }
1037     {
1038         Gtk::MenuItem *item = new Gtk::MenuItem;
1039         item->add(*(new Gtk::Label(_("0 (transparent)"), 0, 0)));
1040         item->signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::opacity_0 ));
1041         menu->add(*item);
1042     }
1043     {
1044         Gtk::MenuItem *item = new Gtk::MenuItem;
1045         item->add(*(new Gtk::Label("0.25", 0, 0)));
1046         item->signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::opacity_025 ));
1047         menu->add(*item);
1048     }
1049     {
1050         Gtk::MenuItem *item = new Gtk::MenuItem;
1051         item->add(*(new Gtk::Label("0.5", 0, 0)));
1052         item->signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::opacity_05 ));
1053         menu->add(*item);
1054     }
1055     {
1056         Gtk::MenuItem *item = new Gtk::MenuItem;
1057         item->add(*(new Gtk::Label("0.75", 0, 0)));
1058         item->signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::opacity_075 ));
1059         menu->add(*item);
1060     }
1061     {
1062         Gtk::MenuItem *item = new Gtk::MenuItem;
1063         item->add(*(new Gtk::Label(_("1.0 (opaque)"), 0, 0)));
1064         item->signal_activate().connect(sigc::mem_fun(*this, &SelectedStyle::opacity_1 ));
1065         menu->add(*item);
1066     }
1068     menu->show_all();
1071 void SelectedStyle::on_opacity_changed () {
1072     if (_opacity_blocked)
1073         return;
1074     _opacity_blocked = true;
1075     SPCSSAttr *css = sp_repr_css_attr_new ();
1076     Inkscape::CSSOStringStream os;
1077     os << CLAMP (_opacity_adjustment.get_value(), 0.0, 1.0);
1078     sp_repr_css_set_property (css, "opacity", os.str().c_str());
1079     sp_desktop_set_style (_desktop, css);
1080     sp_repr_css_attr_unref (css);
1081     sp_document_maybe_done (sp_desktop_document (_desktop), "fillstroke:opacity", SP_VERB_DIALOG_FILL_STROKE,
1082                             /* TODO: annotate */ "selected-style.cpp:1082");
1083     spinbutton_defocus(GTK_OBJECT(_opacity_sb.gobj()));
1084     _opacity_blocked = false;
1087 } // namespace Widget
1088 } // namespace UI
1089 } // namespace Inkscape
1091 /* 
1092   Local Variables:
1093   mode:c++
1094   c-file-style:"stroustrup"
1095   c-file-offsets:((innamespace . 0)(inline-open . 0))
1096   indent-tabs-mode:nil
1097   fill-column:99
1098   End:
1099 */
1100 // vim: filetype=c++:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :