19b8448c6043c00fd56aafe1988abf7c7a63c293
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)
101 {
102 Inkscape::FillNStroke *fs = dynamic_cast<Inkscape::FillNStroke*>(widget);
103 if (fs) {
104 fs->setDesktop(desktop);
105 }
106 }
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 )
114 {
115 FillNStroke *filler = new FillNStroke(kind);
117 return filler;
118 }
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()
131 {
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();
154 }
156 FillNStroke::~FillNStroke()
157 {
158 if (dragId) {
159 g_source_remove(dragId);
160 dragId = 0;
161 }
162 psel = 0;
163 selectModifiedConn.disconnect();
164 subselChangedConn.disconnect();
165 selectChangedConn.disconnect();
166 }
168 /**
169 * On signal modified, invokes an update of the fill or stroke style paint object.
170 */
171 void FillNStroke::selectionModifiedCB( guint flags )
172 {
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 }
181 }
183 void FillNStroke::setDesktop(SPDesktop *desktop)
184 {
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 }
205 }
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()
214 {
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;
298 }
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 )
306 {
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 }
313 }
315 void FillNStroke::fillruleChangedCB( SPPaintSelector * /*psel*/,
316 SPPaintSelector::FillRule mode,
317 FillNStroke *self )
318 {
319 if (self) {
320 self->setFillrule(mode);
321 }
322 }
324 void FillNStroke::setFillrule( SPPaintSelector::FillRule mode )
325 {
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 }
338 }
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)
351 {
352 #ifdef SP_FS_VERBOSE
353 g_message("paintDraggedCB(psel, spw:%p)", self);
354 #endif
355 if (self && !self->update) {
356 self->dragFromPaint();
357 }
358 }
361 gboolean FillNStroke::dragDelayCB(gpointer data)
362 {
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;
380 }
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()
389 {
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;
431 }
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 )
441 {
442 #ifdef SP_FS_VERBOSE
443 g_message("paintChangedCB(psel, spw:%p)", self);
444 #endif
445 if (self && !self->update) {
446 self->updateFromPaint();
447 }
448 }
450 void FillNStroke::updateFromPaint()
451 {
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(SP_OBJECT_REPR(i->data), css, "style");
560 }
562 if (!vector) {
563 SPGradient *gr = sp_gradient_vector_for_object( document, desktop, SP_OBJECT(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(SP_OBJECT_REPR(i->data), 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 = SP_OBJECT_REPR(pattern);
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 = SP_OBJECT_REPR(i->data);
626 if ( (kind == STROKE) && !selrepr) {
627 continue;
628 }
629 SPObject *selobj = SP_OBJECT(i->data);
631 SPStyle *style = SP_OBJECT_STYLE(selobj);
632 if (style && ((kind == FILL) ? style->fill : style->stroke).isPaintserver()) {
633 SPObject *server = (kind == FILL) ?
634 SP_OBJECT_STYLE_FILL_SERVER(selobj) :
635 SP_OBJECT_STYLE_STROKE_SERVER(selobj);
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;
695 }
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:encoding=utf-8:textwidth=99 :