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 * Abhishek Sharma
10 *
11 * Copyright (C) 1999-2005 authors
12 * Copyright (C) 2001-2002 Ximian, Inc.
13 * Copyright (C) 2010 Jon A. Cruz
14 *
15 * Released under GNU GPL, read the file 'COPYING' for more information
16 */
18 #define noSP_FS_VERBOSE
20 #ifdef HAVE_CONFIG_H
21 # include "config.h"
22 #endif
24 #include <glibmm/i18n.h>
25 #include <gtkmm/box.h>
26 #include <gtk/gtkvbox.h>
28 #include "desktop.h"
29 #include "selection.h"
30 #include "desktop-handles.h"
31 #include "desktop-style.h"
32 #include "display/sp-canvas.h"
33 #include "document-private.h"
34 #include "gradient-chemistry.h"
35 #include "inkscape.h"
36 #include "selection.h"
37 #include "sp-linear-gradient.h"
38 #include "sp-pattern.h"
39 #include "sp-radial-gradient.h"
40 #include "style.h"
41 #include "widgets/paint-selector.h"
42 #include "xml/repr.h"
44 #include "fill-style.h"
45 #include "fill-n-stroke-factory.h"
48 // These can be deleted once we sort out the libart dependence.
50 #define ART_WIND_RULE_NONZERO 0
52 /* Fill */
55 Gtk::Widget *sp_fill_style_widget_new(void)
56 {
57 return Inkscape::Widgets::createStyleWidget( FILL );
58 }
61 namespace Inkscape {
63 class FillNStroke : public Gtk::VBox
64 {
65 public:
66 FillNStroke( FillOrStroke kind );
67 ~FillNStroke();
69 void setFillrule( SPPaintSelector::FillRule mode );
71 void setDesktop(SPDesktop *desktop);
73 private:
74 static void paintModeChangeCB(SPPaintSelector *psel, SPPaintSelector::Mode mode, FillNStroke *self);
75 static void paintChangedCB(SPPaintSelector *psel, FillNStroke *self);
76 static void paintDraggedCB(SPPaintSelector *psel, FillNStroke *self);
77 static gboolean dragDelayCB(gpointer data);
79 static void fillruleChangedCB( SPPaintSelector *psel, SPPaintSelector::FillRule mode, FillNStroke *self );
81 void selectionModifiedCB(guint flags);
83 void dragFromPaint();
84 void updateFromPaint();
86 void performUpdate();
88 FillOrStroke kind;
89 SPDesktop *desktop;
90 SPPaintSelector *psel;
91 guint32 lastDrag;
92 guint dragId;
93 bool update;
94 sigc::connection selectChangedConn;
95 sigc::connection subselChangedConn;
96 sigc::connection selectModifiedConn;
97 };
99 } // namespace Inkscape
101 void sp_fill_style_widget_set_desktop(Gtk::Widget *widget, SPDesktop *desktop)
102 {
103 Inkscape::FillNStroke *fs = dynamic_cast<Inkscape::FillNStroke*>(widget);
104 if (fs) {
105 fs->setDesktop(desktop);
106 }
107 }
109 namespace Inkscape {
111 /**
112 * Create the fill or stroke style widget, and hook up all the signals.
113 */
114 Gtk::Widget *Inkscape::Widgets::createStyleWidget( FillOrStroke kind )
115 {
116 FillNStroke *filler = new FillNStroke(kind);
118 return filler;
119 }
121 FillNStroke::FillNStroke( FillOrStroke kind ) :
122 Gtk::VBox(),
123 kind(kind),
124 desktop(0),
125 psel(0),
126 lastDrag(0),
127 dragId(0),
128 update(false),
129 selectChangedConn(),
130 subselChangedConn(),
131 selectModifiedConn()
132 {
133 // Add and connect up the paint selector widget:
134 psel = sp_paint_selector_new(kind);
135 gtk_widget_show(GTK_WIDGET(psel));
136 gtk_container_add(GTK_CONTAINER(gobj()), GTK_WIDGET(psel));
137 g_signal_connect( G_OBJECT(psel), "mode_changed",
138 G_CALLBACK(paintModeChangeCB),
139 this );
141 g_signal_connect( G_OBJECT(psel), "dragged",
142 G_CALLBACK(paintDraggedCB),
143 this );
145 g_signal_connect( G_OBJECT(psel), "changed",
146 G_CALLBACK(paintChangedCB),
147 this );
148 if (kind == FILL) {
149 g_signal_connect( G_OBJECT(psel), "fillrule_changed",
150 G_CALLBACK(fillruleChangedCB),
151 this );
152 }
154 performUpdate();
155 }
157 FillNStroke::~FillNStroke()
158 {
159 if (dragId) {
160 g_source_remove(dragId);
161 dragId = 0;
162 }
163 psel = 0;
164 selectModifiedConn.disconnect();
165 subselChangedConn.disconnect();
166 selectChangedConn.disconnect();
167 }
169 /**
170 * On signal modified, invokes an update of the fill or stroke style paint object.
171 */
172 void FillNStroke::selectionModifiedCB( guint flags )
173 {
174 if (flags & ( SP_OBJECT_MODIFIED_FLAG |
175 SP_OBJECT_PARENT_MODIFIED_FLAG |
176 SP_OBJECT_STYLE_MODIFIED_FLAG) ) {
177 #ifdef SP_FS_VERBOSE
178 g_message("selectionModifiedCB(%d) on %p", flags, this);
179 #endif
180 performUpdate();
181 }
182 }
184 void FillNStroke::setDesktop(SPDesktop *desktop)
185 {
186 if (this->desktop != desktop) {
187 if (dragId) {
188 g_source_remove(dragId);
189 dragId = 0;
190 }
191 if (this->desktop) {
192 selectModifiedConn.disconnect();
193 subselChangedConn.disconnect();
194 selectChangedConn.disconnect();
195 }
196 this->desktop = desktop;
197 if (desktop && desktop->selection) {
198 selectChangedConn = desktop->selection->connectChanged(sigc::hide(sigc::mem_fun(*this, &FillNStroke::performUpdate)));
199 subselChangedConn = desktop->connectToolSubselectionChanged(sigc::hide(sigc::mem_fun(*this, &FillNStroke::performUpdate)));
201 // Must check flags, so can't call performUpdate() directly.
202 selectModifiedConn = desktop->selection->connectModified(sigc::hide<0>(sigc::mem_fun(*this, &FillNStroke::selectionModifiedCB)));
203 }
204 performUpdate();
205 }
206 }
208 /**
209 * Gets the active fill or stroke style property, then sets the appropriate
210 * color, alpha, gradient, pattern, etc. for the paint-selector.
211 *
212 * @param sel Selection to use, or NULL.
213 */
214 void FillNStroke::performUpdate()
215 {
216 if ( update || !desktop ) {
217 return;
218 }
220 if ( dragId ) {
221 // local change; do nothing, but reset the flag
222 g_source_remove(dragId);
223 dragId = 0;
224 return;
225 }
227 update = true;
229 // create temporary style
230 SPStyle *query = sp_style_new(desktop->doc());
232 // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection
233 int result = sp_desktop_query_style(desktop, query, (kind == FILL) ? QUERY_STYLE_PROPERTY_FILL : QUERY_STYLE_PROPERTY_STROKE);
235 SPIPaint &targPaint = (kind == FILL) ? query->fill : query->stroke;
236 SPIScale24 &targOpacity = (kind == FILL) ? query->fill_opacity : query->stroke_opacity;
238 switch (result) {
239 case QUERY_STYLE_NOTHING:
240 {
241 /* No paint at all */
242 psel->setMode(SPPaintSelector::MODE_EMPTY);
243 break;
244 }
246 case QUERY_STYLE_SINGLE:
247 case QUERY_STYLE_MULTIPLE_AVERAGED: // TODO: treat this slightly differently, e.g. display "averaged" somewhere in paint selector
248 case QUERY_STYLE_MULTIPLE_SAME:
249 {
250 SPPaintSelector::Mode pselmode = SPPaintSelector::getModeForStyle(*query, kind);
251 psel->setMode(pselmode);
253 if (kind == FILL) {
254 psel->setFillrule(query->fill_rule.computed == ART_WIND_RULE_NONZERO?
255 SPPaintSelector::FILLRULE_NONZERO : SPPaintSelector::FILLRULE_EVENODD);
256 }
258 if (targPaint.set && targPaint.isColor()) {
259 psel->setColorAlpha(targPaint.value.color, SP_SCALE24_TO_FLOAT(targOpacity.value));
260 } else if (targPaint.set && targPaint.isPaintserver()) {
262 SPPaintServer *server = (kind == FILL) ? query->getFillPaintServer() : query->getStrokePaintServer();
264 if (server && SP_IS_GRADIENT(server) && SP_GRADIENT(server)->getVector()->isSwatch()) {
265 SPGradient *vector = SP_GRADIENT(server)->getVector();
266 psel->setSwatch( vector );
267 } else if (SP_IS_LINEARGRADIENT(server)) {
268 SPGradient *vector = SP_GRADIENT(server)->getVector();
269 psel->setGradientLinear( vector );
271 SPLinearGradient *lg = SP_LINEARGRADIENT(server);
272 psel->setGradientProperties( lg->getUnits(),
273 lg->getSpread() );
274 } else if (SP_IS_RADIALGRADIENT(server)) {
275 SPGradient *vector = SP_GRADIENT(server)->getVector();
276 psel->setGradientRadial( vector );
278 SPRadialGradient *rg = SP_RADIALGRADIENT(server);
279 psel->setGradientProperties( rg->getUnits(),
280 rg->getSpread() );
281 } else if (SP_IS_PATTERN(server)) {
282 SPPattern *pat = pattern_getroot(SP_PATTERN(server));
283 psel->updatePatternList( pat );
284 }
285 }
286 break;
287 }
289 case QUERY_STYLE_MULTIPLE_DIFFERENT:
290 {
291 psel->setMode(SPPaintSelector::MODE_MULTIPLE);
292 break;
293 }
294 }
296 sp_style_unref(query);
298 update = false;
299 }
301 /**
302 * When the mode is changed, invoke a regular changed handler.
303 */
304 void FillNStroke::paintModeChangeCB( SPPaintSelector * /*psel*/,
305 SPPaintSelector::Mode /*mode*/,
306 FillNStroke *self )
307 {
308 #ifdef SP_FS_VERBOSE
309 g_message("paintModeChangeCB(psel, mode, self:%p)", self);
310 #endif
311 if (self && !self->update) {
312 self->updateFromPaint();
313 }
314 }
316 void FillNStroke::fillruleChangedCB( SPPaintSelector * /*psel*/,
317 SPPaintSelector::FillRule mode,
318 FillNStroke *self )
319 {
320 if (self) {
321 self->setFillrule(mode);
322 }
323 }
325 void FillNStroke::setFillrule( SPPaintSelector::FillRule mode )
326 {
327 if (!update && desktop) {
328 SPCSSAttr *css = sp_repr_css_attr_new();
329 sp_repr_css_set_property(css, "fill-rule", (mode == SPPaintSelector::FILLRULE_EVENODD) ? "evenodd":"nonzero");
331 sp_desktop_set_style(desktop, css);
333 sp_repr_css_attr_unref(css);
334 css = 0;
336 DocumentUndo::done(desktop->doc(), SP_VERB_DIALOG_FILL_STROKE,
337 _("Change fill rule"));
338 }
339 }
341 static gchar const *undo_F_label_1 = "fill:flatcolor:1";
342 static gchar const *undo_F_label_2 = "fill:flatcolor:2";
344 static gchar const *undo_S_label_1 = "stroke:flatcolor:1";
345 static gchar const *undo_S_label_2 = "stroke:flatcolor:2";
347 static gchar const *undo_F_label = undo_F_label_1;
348 static gchar const *undo_S_label = undo_S_label_1;
351 void FillNStroke::paintDraggedCB(SPPaintSelector * /*psel*/, FillNStroke *self)
352 {
353 #ifdef SP_FS_VERBOSE
354 g_message("paintDraggedCB(psel, spw:%p)", self);
355 #endif
356 if (self && !self->update) {
357 self->dragFromPaint();
358 }
359 }
362 gboolean FillNStroke::dragDelayCB(gpointer data)
363 {
364 gboolean keepGoing = TRUE;
365 if (data) {
366 FillNStroke *self = reinterpret_cast<FillNStroke*>(data);
367 if (!self->update) {
368 if (self->dragId) {
369 g_source_remove(self->dragId);
370 self->dragId = 0;
372 self->dragFromPaint();
373 self->performUpdate();
374 }
375 keepGoing = FALSE;
376 }
377 } else {
378 keepGoing = FALSE;
379 }
380 return keepGoing;
381 }
383 /**
384 * This is called repeatedly while you are dragging a color slider, only for flat color
385 * modes. Previously it set the color in style but did not update the repr for efficiency, however
386 * this was flakey and didn't buy us almost anything. So now it does the same as _changed, except
387 * lumps all its changes for undo.
388 */
389 void FillNStroke::dragFromPaint()
390 {
391 if (!desktop || update) {
392 return;
393 }
395 guint32 when = gtk_get_current_event_time();
397 // Don't attempt too many updates per second.
398 // Assume a base 15.625ms resolution on the timer.
399 if (!dragId && lastDrag && when && ((when - lastDrag) < 32)) {
400 // local change, do not update from selection
401 dragId = g_timeout_add_full(G_PRIORITY_DEFAULT, 33, dragDelayCB, this, 0);
402 }
404 if (dragId) {
405 // previous local flag not cleared yet;
406 // this means dragged events come too fast, so we better skip this one to speed up display
407 // (it's safe to do this in any case)
408 return;
409 }
410 lastDrag = when;
412 update = true;
414 switch (psel->mode) {
415 case SPPaintSelector::MODE_COLOR_RGB:
416 case SPPaintSelector::MODE_COLOR_CMYK:
417 {
418 // local change, do not update from selection
419 dragId = g_timeout_add_full(G_PRIORITY_DEFAULT, 100, dragDelayCB, this, 0);
420 psel->setFlatColor( desktop, (kind == FILL) ? "fill" : "stroke", (kind == FILL) ? "fill-opacity" : "stroke-opacity" );
421 DocumentUndo::maybeDone(desktop->doc(), (kind == FILL) ? undo_F_label : undo_S_label, SP_VERB_DIALOG_FILL_STROKE,
422 (kind == FILL) ? _("Set fill color") : _("Set stroke color"));
423 break;
424 }
426 default:
427 g_warning( "file %s: line %d: Paint %d should not emit 'dragged'",
428 __FILE__, __LINE__, psel->mode );
429 break;
430 }
431 update = false;
432 }
434 /**
435 This is called (at least) when:
436 1 paint selector mode is switched (e.g. flat color -> gradient)
437 2 you finished dragging a gradient node and released mouse
438 3 you changed a gradient selector parameter (e.g. spread)
439 Must update repr.
440 */
441 void FillNStroke::paintChangedCB( SPPaintSelector * /*psel*/, FillNStroke *self )
442 {
443 #ifdef SP_FS_VERBOSE
444 g_message("paintChangedCB(psel, spw:%p)", self);
445 #endif
446 if (self && !self->update) {
447 self->updateFromPaint();
448 }
449 }
451 void FillNStroke::updateFromPaint()
452 {
453 if (!desktop) {
454 return;
455 }
456 update = true;
458 SPDocument *document = sp_desktop_document(desktop);
459 Inkscape::Selection *selection = sp_desktop_selection(desktop);
461 GSList const *items = selection->itemList();
463 switch (psel->mode) {
464 case SPPaintSelector::MODE_EMPTY:
465 // This should not happen.
466 g_warning( "file %s: line %d: Paint %d should not emit 'changed'",
467 __FILE__, __LINE__, psel->mode);
468 break;
469 case SPPaintSelector::MODE_MULTIPLE:
470 // This happens when you switch multiple objects with different gradients to flat color;
471 // nothing to do here.
472 break;
474 case SPPaintSelector::MODE_NONE:
475 {
476 SPCSSAttr *css = sp_repr_css_attr_new();
477 sp_repr_css_set_property(css, (kind == FILL) ? "fill" : "stroke", "none");
479 sp_desktop_set_style(desktop, css);
481 sp_repr_css_attr_unref(css);
482 css = 0;
484 DocumentUndo::done(document, SP_VERB_DIALOG_FILL_STROKE,
485 (kind == FILL) ? _("Remove fill") : _("Remove stroke"));
486 break;
487 }
489 case SPPaintSelector::MODE_COLOR_RGB:
490 case SPPaintSelector::MODE_COLOR_CMYK:
491 {
492 if (kind == FILL) {
493 // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in losing release events
494 sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(desktop), 0);
495 }
497 psel->setFlatColor( desktop,
498 (kind == FILL) ? "fill" : "stroke",
499 (kind == FILL) ? "fill-opacity" : "stroke-opacity" );
500 DocumentUndo::maybeDone(sp_desktop_document(desktop), (kind == FILL) ? undo_F_label : undo_S_label, SP_VERB_DIALOG_FILL_STROKE,
501 (kind == FILL) ? _("Set fill color") : _("Set stroke color"));
503 if (kind == FILL) {
504 // resume interruptibility
505 sp_canvas_end_forced_full_redraws(sp_desktop_canvas(desktop));
506 }
508 // on release, toggle undo_label so that the next drag will not be lumped with this one
509 if (undo_F_label == undo_F_label_1) {
510 undo_F_label = undo_F_label_2;
511 undo_S_label = undo_S_label_2;
512 } else {
513 undo_F_label = undo_F_label_1;
514 undo_S_label = undo_S_label_1;
515 }
517 break;
518 }
520 case SPPaintSelector::MODE_GRADIENT_LINEAR:
521 case SPPaintSelector::MODE_GRADIENT_RADIAL:
522 case SPPaintSelector::MODE_SWATCH:
523 if (items) {
524 SPGradientType const gradient_type = ( psel->mode != SPPaintSelector::MODE_GRADIENT_RADIAL
525 ? SP_GRADIENT_TYPE_LINEAR
526 : SP_GRADIENT_TYPE_RADIAL );
527 bool createSwatch = (psel->mode == SPPaintSelector::MODE_SWATCH);
529 SPCSSAttr *css = 0;
530 if (kind == FILL) {
531 // HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs
532 css = sp_repr_css_attr_new();
533 sp_repr_css_set_property(css, "fill-opacity", "1.0");
534 }
536 SPGradient *vector = psel->getGradientVector();
537 if (!vector) {
538 /* No vector in paint selector should mean that we just changed mode */
540 SPStyle *query = sp_style_new(desktop->doc());
541 int result = objects_query_fillstroke(const_cast<GSList *>(items), query, kind == FILL);
542 if (result == QUERY_STYLE_MULTIPLE_SAME) {
543 SPIPaint &targPaint = (kind == FILL) ? query->fill : query->stroke;
544 SPColor common;
545 if (!targPaint.isColor()) {
546 common = sp_desktop_get_color(desktop, kind == FILL);
547 } else {
548 common = targPaint.value.color;
549 }
550 vector = sp_document_default_gradient_vector( document, common, createSwatch );
551 if ( vector && createSwatch ) {
552 vector->setSwatch();
553 }
554 }
555 sp_style_unref(query);
557 for (GSList const *i = items; i != NULL; i = i->next) {
558 //FIXME: see above
559 if (kind == FILL) {
560 sp_repr_css_change_recursive(reinterpret_cast<SPObject*>(i->data)->getRepr(), css, "style");
561 }
563 if (!vector) {
564 SPGradient *gr = sp_gradient_vector_for_object( document, desktop, reinterpret_cast<SPObject*>(i->data), kind == FILL, createSwatch );
565 if ( gr && createSwatch ) {
566 gr->setSwatch();
567 }
568 sp_item_set_gradient(SP_ITEM(i->data),
569 gr,
570 gradient_type, kind == FILL);
571 } else {
572 sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, kind == FILL);
573 }
574 }
575 } else {
576 // We have changed from another gradient type, or modified spread/units within
577 // this gradient type.
578 vector = sp_gradient_ensure_vector_normalized(vector);
579 for (GSList const *i = items; i != NULL; i = i->next) {
580 //FIXME: see above
581 if (kind == FILL) {
582 sp_repr_css_change_recursive(reinterpret_cast<SPObject*>(i->data)->getRepr(), css, "style");
583 }
585 SPGradient *gr = sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, kind == FILL);
586 psel->pushAttrsToGradient( gr );
587 }
588 }
590 if (css) {
591 sp_repr_css_attr_unref(css);
592 css = 0;
593 }
595 DocumentUndo::done(document, SP_VERB_DIALOG_FILL_STROKE,
596 (kind == FILL) ? _("Set gradient on fill") : _("Set gradient on stroke"));
597 }
598 break;
600 case SPPaintSelector::MODE_PATTERN:
602 if (items) {
604 SPPattern *pattern = psel->getPattern();
605 if (!pattern) {
607 /* No Pattern in paint selector should mean that we just
608 * changed mode - dont do jack.
609 */
611 } else {
612 Inkscape::XML::Node *patrepr = pattern->getRepr();
613 SPCSSAttr *css = sp_repr_css_attr_new();
614 gchar *urltext = g_strdup_printf("url(#%s)", patrepr->attribute("id"));
615 sp_repr_css_set_property(css, (kind == FILL) ? "fill" : "stroke", urltext);
617 // HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs
618 if (kind == FILL) {
619 sp_repr_css_set_property(css, "fill-opacity", "1.0");
620 }
622 // cannot just call sp_desktop_set_style, because we don't want to touch those
623 // objects who already have the same root pattern but through a different href
624 // chain. FIXME: move this to a sp_item_set_pattern
625 for (GSList const *i = items; i != NULL; i = i->next) {
626 Inkscape::XML::Node *selrepr = reinterpret_cast<SPObject*>(i->data)->getRepr();
627 if ( (kind == STROKE) && !selrepr) {
628 continue;
629 }
630 SPObject *selobj = reinterpret_cast<SPObject*>(i->data);
632 SPStyle *style = selobj->style;
633 if (style && ((kind == FILL) ? style->fill : style->stroke).isPaintserver()) {
634 SPPaintServer *server = (kind == FILL) ?
635 selobj->style->getFillPaintServer() :
636 selobj->style->getStrokePaintServer();
637 if (SP_IS_PATTERN(server) && pattern_getroot(SP_PATTERN(server)) == pattern)
638 // only if this object's pattern is not rooted in our selected pattern, apply
639 continue;
640 }
642 if (kind == FILL) {
643 sp_desktop_apply_css_recursive(selobj, css, true);
644 } else {
645 sp_repr_css_change_recursive(selrepr, css, "style");
646 }
647 }
649 sp_repr_css_attr_unref(css);
650 css = 0;
651 g_free(urltext);
653 } // end if
655 DocumentUndo::done(document, SP_VERB_DIALOG_FILL_STROKE,
656 (kind == FILL) ? _("Set pattern on fill") :
657 _("Set pattern on stroke"));
658 } // end if
660 break;
662 case SPPaintSelector::MODE_UNSET:
663 if (items) {
664 SPCSSAttr *css = sp_repr_css_attr_new();
665 if (kind == FILL) {
666 sp_repr_css_unset_property(css, "fill");
667 } else {
668 sp_repr_css_unset_property(css, "stroke");
669 sp_repr_css_unset_property(css, "stroke-opacity");
670 sp_repr_css_unset_property(css, "stroke-width");
671 sp_repr_css_unset_property(css, "stroke-miterlimit");
672 sp_repr_css_unset_property(css, "stroke-linejoin");
673 sp_repr_css_unset_property(css, "stroke-linecap");
674 sp_repr_css_unset_property(css, "stroke-dashoffset");
675 sp_repr_css_unset_property(css, "stroke-dasharray");
676 }
678 sp_desktop_set_style(desktop, css);
679 sp_repr_css_attr_unref(css);
680 css = 0;
682 DocumentUndo::done(document, SP_VERB_DIALOG_FILL_STROKE,
683 (kind == FILL) ? _("Unset fill") : _("Unset stroke"));
684 }
685 break;
687 default:
688 g_warning( "file %s: line %d: Paint selector should not be in "
689 "mode %d",
690 __FILE__, __LINE__,
691 psel->mode );
692 break;
693 }
695 update = false;
696 }
698 } // namespace Inkscape
700 /*
701 Local Variables:
702 mode:c++
703 c-file-style:"stroustrup"
704 c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
705 indent-tabs-mode:nil
706 fill-column:99
707 End:
708 */
709 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:fileencoding=utf-8:textwidth=99 :