Code

Pot and Dutch translation update
[inkscape.git] / src / widgets / fill-style.cpp
1 /** @file
2  * @brief  Fill style widget
3  */
4 /* Authors:
5  *   Lauris Kaplinski <lauris@kaplinski.com>
6  *   Frank Felfe <innerspace@iname.com>
7  *   bulia byak <buliabyak@users.sf.net>
8  *   Jon A. Cruz <jon@joncruz.org>
9  *
10  * Copyright (C) 1999-2005 authors
11  * Copyright (C) 2001-2002 Ximian, Inc.
12  * Copyright (C) 2010 Jon A. Cruz
13  *
14  * Released under GNU GPL, read the file 'COPYING' for more information
15  */
17 #define noSP_FS_VERBOSE
19 #ifdef HAVE_CONFIG_H
20 # include "config.h"
21 #endif
23 #include <glibmm/i18n.h>
24 #include <gtkmm/box.h>
25 #include <gtk/gtkvbox.h>
27 #include "desktop.h"
28 #include "selection.h"
29 #include "desktop-handles.h"
30 #include "desktop-style.h"
31 #include "display/sp-canvas.h"
32 #include "document-private.h"
33 #include "gradient-chemistry.h"
34 #include "inkscape.h"
35 #include "selection.h"
36 #include "sp-linear-gradient.h"
37 #include "sp-pattern.h"
38 #include "sp-radial-gradient.h"
39 #include "style.h"
40 #include "widgets/paint-selector.h"
41 #include "xml/repr.h"
43 #include "fill-style.h"
44 #include "fill-n-stroke-factory.h"
47 // These can be deleted once we sort out the libart dependence.
49 #define ART_WIND_RULE_NONZERO 0
51 /* Fill */
54 Gtk::Widget *sp_fill_style_widget_new(void)
55 {
56     return Inkscape::Widgets::createStyleWidget( FILL );
57 }
60 namespace Inkscape {
62 class FillNStroke : public Gtk::VBox
63 {
64 public:
65     FillNStroke( FillOrStroke kind );
66     ~FillNStroke();
68     void setFillrule( SPPaintSelector::FillRule mode );
70     void setDesktop(SPDesktop *desktop);
72 private:
73     static void paintModeChangeCB(SPPaintSelector *psel, SPPaintSelector::Mode mode, FillNStroke *self);
74     static void paintChangedCB(SPPaintSelector *psel, FillNStroke *self);
75     static void paintDraggedCB(SPPaintSelector *psel, FillNStroke *self);
76     static gboolean dragDelayCB(gpointer data);
78     static void fillruleChangedCB( SPPaintSelector *psel, SPPaintSelector::FillRule mode, FillNStroke *self );
80     void selectionModifiedCB(guint flags);
82     void dragFromPaint();
83     void updateFromPaint();
85     void performUpdate();
87     FillOrStroke kind;
88     SPDesktop *desktop;
89     SPPaintSelector *psel;
90     guint32 lastDrag;
91     guint dragId;
92     bool update;
93     sigc::connection selectChangedConn;
94     sigc::connection subselChangedConn;
95     sigc::connection selectModifiedConn;
96 };
98 } // namespace Inkscape
100 void sp_fill_style_widget_set_desktop(Gtk::Widget *widget, SPDesktop *desktop)
102     Inkscape::FillNStroke *fs = dynamic_cast<Inkscape::FillNStroke*>(widget);
103     if (fs) {
104         fs->setDesktop(desktop);
105     }
108 namespace Inkscape {
110 /**
111  * Create the fill or stroke style widget, and hook up all the signals.
112  */
113 Gtk::Widget *Inkscape::Widgets::createStyleWidget( FillOrStroke kind )
115     FillNStroke *filler = new FillNStroke(kind);
117     return filler;
120 FillNStroke::FillNStroke( FillOrStroke kind ) :
121     Gtk::VBox(),
122     kind(kind),
123     desktop(0),
124     psel(0),
125     lastDrag(0),
126     dragId(0),
127     update(false),
128     selectChangedConn(),
129     subselChangedConn(),
130     selectModifiedConn()
132     // Add and connect up the paint selector widget:
133     psel = sp_paint_selector_new(kind);
134     gtk_widget_show(GTK_WIDGET(psel));
135     gtk_container_add(GTK_CONTAINER(gobj()), GTK_WIDGET(psel));
136     g_signal_connect( G_OBJECT(psel), "mode_changed",
137                       G_CALLBACK(paintModeChangeCB),
138                       this );
140     g_signal_connect( G_OBJECT(psel), "dragged",
141                       G_CALLBACK(paintDraggedCB),
142                       this );
144     g_signal_connect( G_OBJECT(psel), "changed",
145                       G_CALLBACK(paintChangedCB),
146                       this );
147     if (kind == FILL) {
148         g_signal_connect( G_OBJECT(psel), "fillrule_changed",
149                           G_CALLBACK(fillruleChangedCB),
150                           this );
151     }
153     performUpdate();
156 FillNStroke::~FillNStroke()
158     if (dragId) {
159         g_source_remove(dragId);
160         dragId = 0;
161     }
162     psel = 0;
163     selectModifiedConn.disconnect();
164     subselChangedConn.disconnect();
165     selectChangedConn.disconnect();
168 /**
169  * On signal modified, invokes an update of the fill or stroke style paint object.
170  */
171 void FillNStroke::selectionModifiedCB( guint flags )
173     if (flags & ( SP_OBJECT_MODIFIED_FLAG |
174                    SP_OBJECT_PARENT_MODIFIED_FLAG |
175                    SP_OBJECT_STYLE_MODIFIED_FLAG) ) {
176 #ifdef SP_FS_VERBOSE
177         g_message("selectionModifiedCB(%d) on %p", flags, this);
178 #endif
179         performUpdate();
180     }
183 void FillNStroke::setDesktop(SPDesktop *desktop)
185     if (this->desktop != desktop) {
186         if (dragId) {
187             g_source_remove(dragId);
188             dragId = 0;
189         }
190         if (this->desktop) {
191             selectModifiedConn.disconnect();
192             subselChangedConn.disconnect();
193             selectChangedConn.disconnect();
194         }
195         this->desktop = desktop;
196         if (desktop && desktop->selection) {
197             selectChangedConn = desktop->selection->connectChanged(sigc::hide(sigc::mem_fun(*this, &FillNStroke::performUpdate)));
198             subselChangedConn = desktop->connectToolSubselectionChanged(sigc::hide(sigc::mem_fun(*this, &FillNStroke::performUpdate)));
200             // Must check flags, so can't call performUpdate() directly.
201             selectModifiedConn = desktop->selection->connectModified(sigc::hide<0>(sigc::mem_fun(*this, &FillNStroke::selectionModifiedCB)));
202         }
203         performUpdate();
204     }
207 /**
208  * Gets the active fill or stroke style property, then sets the appropriate
209  * color, alpha, gradient, pattern, etc. for the paint-selector.
210  *
211  * @param sel Selection to use, or NULL.
212  */
213 void FillNStroke::performUpdate()
215     if ( update || !desktop ) {
216         return;
217     }
219     if ( dragId ) {
220         // local change; do nothing, but reset the flag
221         g_source_remove(dragId);
222         dragId = 0;
223         return;
224     }
226     update = true;
228     // create temporary style
229     SPStyle *query = sp_style_new(desktop->doc());
231     // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection
232     int result = sp_desktop_query_style(desktop, query, (kind == FILL) ? QUERY_STYLE_PROPERTY_FILL : QUERY_STYLE_PROPERTY_STROKE);
234     SPIPaint &targPaint = (kind == FILL) ? query->fill : query->stroke;
235     SPIScale24 &targOpacity = (kind == FILL) ? query->fill_opacity : query->stroke_opacity;
237     switch (result) {
238         case QUERY_STYLE_NOTHING:
239         {
240             /* No paint at all */
241             psel->setMode(SPPaintSelector::MODE_EMPTY);
242             break;
243         }
245         case QUERY_STYLE_SINGLE:
246         case QUERY_STYLE_MULTIPLE_AVERAGED: // TODO: treat this slightly differently, e.g. display "averaged" somewhere in paint selector
247         case QUERY_STYLE_MULTIPLE_SAME:
248         {
249             SPPaintSelector::Mode pselmode = SPPaintSelector::getModeForStyle(*query, kind);
250             psel->setMode(pselmode);
252             if (kind == FILL) {
253                 psel->setFillrule(query->fill_rule.computed == ART_WIND_RULE_NONZERO?
254                                   SPPaintSelector::FILLRULE_NONZERO : SPPaintSelector::FILLRULE_EVENODD);
255             }
257             if (targPaint.set && targPaint.isColor()) {
258                 psel->setColorAlpha(targPaint.value.color, SP_SCALE24_TO_FLOAT(targOpacity.value));
259             } else if (targPaint.set && targPaint.isPaintserver()) {
261                 SPPaintServer *server = (kind == FILL) ? query->getFillPaintServer() : query->getStrokePaintServer();
263                 if (server && SP_IS_GRADIENT(server) && SP_GRADIENT(server)->getVector()->isSwatch()) {
264                     SPGradient *vector = SP_GRADIENT(server)->getVector();
265                     psel->setSwatch( vector );
266                 } else if (SP_IS_LINEARGRADIENT(server)) {
267                     SPGradient *vector = SP_GRADIENT(server)->getVector();
268                     psel->setGradientLinear( vector );
270                     SPLinearGradient *lg = SP_LINEARGRADIENT(server);
271                     psel->setGradientProperties( lg->getUnits(),
272                                                  lg->getSpread() );
273                 } else if (SP_IS_RADIALGRADIENT(server)) {
274                     SPGradient *vector = SP_GRADIENT(server)->getVector();
275                     psel->setGradientRadial( vector );
277                     SPRadialGradient *rg = SP_RADIALGRADIENT(server);
278                     psel->setGradientProperties( rg->getUnits(),
279                                                  rg->getSpread() );
280                 } else if (SP_IS_PATTERN(server)) {
281                     SPPattern *pat = pattern_getroot(SP_PATTERN(server));
282                     psel->updatePatternList( pat );
283                 }
284             }
285             break;
286         }
288         case QUERY_STYLE_MULTIPLE_DIFFERENT:
289         {
290             psel->setMode(SPPaintSelector::MODE_MULTIPLE);
291             break;
292         }
293     }
295     sp_style_unref(query);
297     update = false;
300 /**
301  * When the mode is changed, invoke a regular changed handler.
302  */
303 void FillNStroke::paintModeChangeCB( SPPaintSelector * /*psel*/,
304                                      SPPaintSelector::Mode /*mode*/,
305                                      FillNStroke *self )
307 #ifdef SP_FS_VERBOSE
308     g_message("paintModeChangeCB(psel, mode, self:%p)", self);
309 #endif
310     if (self && !self->update) {
311         self->updateFromPaint();
312     }
315 void FillNStroke::fillruleChangedCB( SPPaintSelector * /*psel*/,
316                                      SPPaintSelector::FillRule mode,
317                                      FillNStroke *self )
319     if (self) {
320         self->setFillrule(mode);
321     }
324 void FillNStroke::setFillrule( SPPaintSelector::FillRule mode )
326     if (!update && desktop) {
327         SPCSSAttr *css = sp_repr_css_attr_new();
328         sp_repr_css_set_property(css, "fill-rule", (mode == SPPaintSelector::FILLRULE_EVENODD) ? "evenodd":"nonzero");
330         sp_desktop_set_style(desktop, css);
332         sp_repr_css_attr_unref(css);
333         css = 0;
335         sp_document_done(desktop->doc(), SP_VERB_DIALOG_FILL_STROKE,
336                          _("Change fill rule"));
337     }
340 static gchar const *undo_F_label_1 = "fill:flatcolor:1";
341 static gchar const *undo_F_label_2 = "fill:flatcolor:2";
343 static gchar const *undo_S_label_1 = "stroke:flatcolor:1";
344 static gchar const *undo_S_label_2 = "stroke:flatcolor:2";
346 static gchar const *undo_F_label = undo_F_label_1;
347 static gchar const *undo_S_label = undo_S_label_1;
350 void FillNStroke::paintDraggedCB(SPPaintSelector * /*psel*/, FillNStroke *self)
352 #ifdef SP_FS_VERBOSE
353     g_message("paintDraggedCB(psel, spw:%p)", self);
354 #endif
355     if (self && !self->update) {
356         self->dragFromPaint();
357     }
361 gboolean FillNStroke::dragDelayCB(gpointer data)
363     gboolean keepGoing = TRUE;
364     if (data) {
365         FillNStroke *self = reinterpret_cast<FillNStroke*>(data);
366         if (!self->update) {
367             if (self->dragId) {
368                 g_source_remove(self->dragId);
369                 self->dragId = 0;
371                 self->dragFromPaint();
372                 self->performUpdate();
373             }
374             keepGoing = FALSE;
375         }
376     } else {
377         keepGoing = FALSE;
378     }
379     return keepGoing;
382 /**
383  * This is called repeatedly while you are dragging a color slider, only for flat color
384  * modes. Previously it set the color in style but did not update the repr for efficiency, however
385  * this was flakey and didn't buy us almost anything. So now it does the same as _changed, except
386  * lumps all its changes for undo.
387  */
388 void FillNStroke::dragFromPaint()
390     if (!desktop || update) {
391         return;
392     }
394     guint32 when = gtk_get_current_event_time();
396     // Don't attempt too many updates per second.
397     // Assume a base 15.625ms resolution on the timer.
398     if (!dragId && lastDrag && when && ((when - lastDrag) < 32)) {
399         // local change, do not update from selection
400         dragId = g_timeout_add_full(G_PRIORITY_DEFAULT, 33, dragDelayCB, this, 0);
401     }
403     if (dragId) {
404         // previous local flag not cleared yet;
405         // this means dragged events come too fast, so we better skip this one to speed up display
406         // (it's safe to do this in any case)
407         return;
408     }
409     lastDrag = when;
411     update = true;
413     switch (psel->mode) {
414         case SPPaintSelector::MODE_COLOR_RGB:
415         case SPPaintSelector::MODE_COLOR_CMYK:
416         {
417             // local change, do not update from selection
418             dragId = g_timeout_add_full(G_PRIORITY_DEFAULT, 100, dragDelayCB, this, 0);
419             psel->setFlatColor( desktop, (kind == FILL) ? "fill" : "stroke", (kind == FILL) ? "fill-opacity" : "stroke-opacity" );
420             sp_document_maybe_done(desktop->doc(), (kind == FILL) ? undo_F_label : undo_S_label, SP_VERB_DIALOG_FILL_STROKE,
421                                    (kind == FILL) ? _("Set fill color") : _("Set stroke color"));
422             break;
423         }
425         default:
426             g_warning( "file %s: line %d: Paint %d should not emit 'dragged'",
427                        __FILE__, __LINE__, psel->mode );
428             break;
429     }
430     update = false;
433 /**
434 This is called (at least) when:
435 1  paint selector mode is switched (e.g. flat color -> gradient)
436 2  you finished dragging a gradient node and released mouse
437 3  you changed a gradient selector parameter (e.g. spread)
438 Must update repr.
439  */
440 void FillNStroke::paintChangedCB( SPPaintSelector * /*psel*/, FillNStroke *self )
442 #ifdef SP_FS_VERBOSE
443     g_message("paintChangedCB(psel, spw:%p)", self);
444 #endif
445     if (self && !self->update) {
446         self->updateFromPaint();
447     }
450 void FillNStroke::updateFromPaint()
452     if (!desktop) {
453         return;
454     }
455     update = true;
457     SPDocument *document = sp_desktop_document(desktop);
458     Inkscape::Selection *selection = sp_desktop_selection(desktop);
460     GSList const *items = selection->itemList();
462     switch (psel->mode) {
463         case SPPaintSelector::MODE_EMPTY:
464             // This should not happen.
465             g_warning( "file %s: line %d: Paint %d should not emit 'changed'",
466                        __FILE__, __LINE__, psel->mode);
467             break;
468         case SPPaintSelector::MODE_MULTIPLE:
469             // This happens when you switch multiple objects with different gradients to flat color;
470             // nothing to do here.
471             break;
473         case SPPaintSelector::MODE_NONE:
474         {
475             SPCSSAttr *css = sp_repr_css_attr_new();
476             sp_repr_css_set_property(css, (kind == FILL) ? "fill" : "stroke", "none");
478             sp_desktop_set_style(desktop, css);
480             sp_repr_css_attr_unref(css);
481             css = 0;
483             sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
484                              (kind == FILL) ? _("Remove fill") : _("Remove stroke"));
485             break;
486         }
488         case SPPaintSelector::MODE_COLOR_RGB:
489         case SPPaintSelector::MODE_COLOR_CMYK:
490         {
491             if (kind == FILL) {
492                 // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in losing release events
493                 sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(desktop), 0);
494             }
496             psel->setFlatColor( desktop,
497                                 (kind == FILL) ? "fill" : "stroke",
498                                 (kind == FILL) ? "fill-opacity" : "stroke-opacity" );
499             sp_document_maybe_done(sp_desktop_document(desktop), (kind == FILL) ? undo_F_label : undo_S_label, SP_VERB_DIALOG_FILL_STROKE,
500                                    (kind == FILL) ? _("Set fill color") : _("Set stroke color"));
502             if (kind == FILL) {
503                 // resume interruptibility
504                 sp_canvas_end_forced_full_redraws(sp_desktop_canvas(desktop));
505             }
507             // on release, toggle undo_label so that the next drag will not be lumped with this one
508             if (undo_F_label == undo_F_label_1) {
509                 undo_F_label = undo_F_label_2;
510                 undo_S_label = undo_S_label_2;
511             } else {
512                 undo_F_label = undo_F_label_1;
513                 undo_S_label = undo_S_label_1;
514             }
516             break;
517         }
519         case SPPaintSelector::MODE_GRADIENT_LINEAR:
520         case SPPaintSelector::MODE_GRADIENT_RADIAL:
521         case SPPaintSelector::MODE_SWATCH:
522             if (items) {
523                 SPGradientType const gradient_type = ( psel->mode != SPPaintSelector::MODE_GRADIENT_RADIAL
524                                                        ? SP_GRADIENT_TYPE_LINEAR
525                                                        : SP_GRADIENT_TYPE_RADIAL );
526                 bool createSwatch = (psel->mode == SPPaintSelector::MODE_SWATCH);
528                 SPCSSAttr *css = 0;
529                 if (kind == FILL) {
530                     // HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs
531                     css = sp_repr_css_attr_new();
532                     sp_repr_css_set_property(css, "fill-opacity", "1.0");
533                 }
535                 SPGradient *vector = psel->getGradientVector();
536                 if (!vector) {
537                     /* No vector in paint selector should mean that we just changed mode */
539                     SPStyle *query = sp_style_new(desktop->doc());
540                     int result = objects_query_fillstroke(const_cast<GSList *>(items), query, kind == FILL);
541                     if (result == QUERY_STYLE_MULTIPLE_SAME) {
542                         SPIPaint &targPaint = (kind == FILL) ? query->fill : query->stroke;
543                         SPColor common;
544                         if (!targPaint.isColor()) {
545                             common = sp_desktop_get_color(desktop, kind == FILL);
546                         } else {
547                             common = targPaint.value.color;
548                         }
549                         vector = sp_document_default_gradient_vector( document, common, createSwatch );
550                         if ( vector && createSwatch ) {
551                             vector->setSwatch();
552                         }
553                     }
554                     sp_style_unref(query);
556                     for (GSList const *i = items; i != NULL; i = i->next) {
557                         //FIXME: see above
558                         if (kind == FILL) {
559                             sp_repr_css_change_recursive(reinterpret_cast<SPObject*>(i->data)->repr, css, "style");
560                         }
562                         if (!vector) {
563                             SPGradient *gr = sp_gradient_vector_for_object( document, desktop, reinterpret_cast<SPObject*>(i->data), kind == FILL, createSwatch );
564                             if ( gr && createSwatch ) {
565                                 gr->setSwatch();
566                             }
567                             sp_item_set_gradient(SP_ITEM(i->data),
568                                                  gr,
569                                                  gradient_type, kind == FILL);
570                         } else {
571                             sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, kind == FILL);
572                         }
573                     }
574                 } else {
575                     // We have changed from another gradient type, or modified spread/units within
576                     // this gradient type.
577                     vector = sp_gradient_ensure_vector_normalized(vector);
578                     for (GSList const *i = items; i != NULL; i = i->next) {
579                         //FIXME: see above
580                         if (kind == FILL) {
581                             sp_repr_css_change_recursive(reinterpret_cast<SPObject*>(i->data)->repr, css, "style");
582                         }
584                         SPGradient *gr = sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, kind == FILL);
585                         psel->pushAttrsToGradient( gr );
586                     }
587                 }
589                 if (css) {
590                     sp_repr_css_attr_unref(css);
591                     css = 0;
592                 }
594                 sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
595                                  (kind == FILL) ? _("Set gradient on fill") : _("Set gradient on stroke"));
596             }
597             break;
599         case SPPaintSelector::MODE_PATTERN:
601             if (items) {
603                 SPPattern *pattern = psel->getPattern();
604                 if (!pattern) {
606                     /* No Pattern in paint selector should mean that we just
607                      * changed mode - dont do jack.
608                      */
610                 } else {
611                     Inkscape::XML::Node *patrepr = pattern->repr;
612                     SPCSSAttr *css = sp_repr_css_attr_new();
613                     gchar *urltext = g_strdup_printf("url(#%s)", patrepr->attribute("id"));
614                     sp_repr_css_set_property(css, (kind == FILL) ? "fill" : "stroke", urltext);
616                     // HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs
617                     if (kind == FILL) {
618                         sp_repr_css_set_property(css, "fill-opacity", "1.0");
619                     }
621                     // cannot just call sp_desktop_set_style, because we don't want to touch those
622                     // objects who already have the same root pattern but through a different href
623                     // chain. FIXME: move this to a sp_item_set_pattern
624                     for (GSList const *i = items; i != NULL; i = i->next) {
625                         Inkscape::XML::Node *selrepr = reinterpret_cast<SPObject*>(i->data)->repr;
626                         if ( (kind == STROKE) && !selrepr) {
627                             continue;
628                         }
629                         SPObject *selobj = reinterpret_cast<SPObject*>(i->data);
631                         SPStyle *style = selobj->style;
632                         if (style && ((kind == FILL) ? style->fill : style->stroke).isPaintserver()) {
633                             SPPaintServer *server = (kind == FILL) ?
634                                 selobj->style->getFillPaintServer() :
635                                 selobj->style->getStrokePaintServer();
636                             if (SP_IS_PATTERN(server) && pattern_getroot(SP_PATTERN(server)) == pattern)
637                                 // only if this object's pattern is not rooted in our selected pattern, apply
638                                 continue;
639                         }
641                         if (kind == FILL) {
642                             sp_desktop_apply_css_recursive(selobj, css, true);
643                         } else {
644                             sp_repr_css_change_recursive(selrepr, css, "style");
645                         }
646                     }
648                     sp_repr_css_attr_unref(css);
649                     css = 0;
650                     g_free(urltext);
652                 } // end if
654                 sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
655                                  (kind == FILL) ? _("Set pattern on fill") :
656                                  _("Set pattern on stroke"));
657             } // end if
659             break;
661         case SPPaintSelector::MODE_UNSET:
662             if (items) {
663                 SPCSSAttr *css = sp_repr_css_attr_new();
664                 if (kind == FILL) {
665                     sp_repr_css_unset_property(css, "fill");
666                 } else {
667                     sp_repr_css_unset_property(css, "stroke");
668                     sp_repr_css_unset_property(css, "stroke-opacity");
669                     sp_repr_css_unset_property(css, "stroke-width");
670                     sp_repr_css_unset_property(css, "stroke-miterlimit");
671                     sp_repr_css_unset_property(css, "stroke-linejoin");
672                     sp_repr_css_unset_property(css, "stroke-linecap");
673                     sp_repr_css_unset_property(css, "stroke-dashoffset");
674                     sp_repr_css_unset_property(css, "stroke-dasharray");
675                 }
677                 sp_desktop_set_style(desktop, css);
678                 sp_repr_css_attr_unref(css);
679                 css = 0;
681                 sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
682                                  (kind == FILL) ? _("Unset fill") : _("Unset stroke"));
683             }
684             break;
686         default:
687             g_warning( "file %s: line %d: Paint selector should not be in "
688                        "mode %d",
689                        __FILE__, __LINE__,
690                        psel->mode );
691             break;
692     }
694     update = false;
697 } // namespace Inkscape
699 /*
700   Local Variables:
701   mode:c++
702   c-file-style:"stroustrup"
703   c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
704   indent-tabs-mode:nil
705   fill-column:99
706   End:
707 */
708 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :