~ubuntu-branches/ubuntu/natty/inkscape/natty

« back to all changes in this revision

Viewing changes to src/widgets/fill-style.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Alex Valavanis
  • Date: 2010-09-12 19:44:58 UTC
  • mfrom: (1.1.12 upstream) (45.1.3 maverick)
  • Revision ID: james.westby@ubuntu.com-20100912194458-4sjwmbl7dlsrk5dc
Tags: 0.48.0-1ubuntu1
* Merge with Debian unstable (LP: #628048, LP: #401567, LP: #456248, 
  LP: #463602, LP: #591986)
* debian/control: 
  - Ubuntu maintainers
  - Promote python-lxml, python-numpy, python-uniconvertor to Recommends.
  - Demote pstoedit to Suggests (universe package).
  - Suggests ttf-dejavu instead of ttf-bitstream-vera (LP: #513319)
* debian/rules:
  - Run intltool-update on build (Ubuntu-specific).
  - Add translation domain to .desktop files (Ubuntu-specific).
* debian/dirs:
  - Add usr/share/pixmaps.  Allow inkscape.xpm installation
* drop 50-poppler-API.dpatch (now upstream)
* drop 51-paste-in-unwritable-directory.dpatch (now upstream) 

Show diffs side-by-side

added added

removed removed

Lines of Context:
5
5
 *   Lauris Kaplinski <lauris@kaplinski.com>
6
6
 *   Frank Felfe <innerspace@iname.com>
7
7
 *   bulia byak <buliabyak@users.sf.net>
 
8
 *   Jon A. Cruz <jon@joncruz.org>
8
9
 *
9
10
 * Copyright (C) 1999-2005 authors
10
11
 * Copyright (C) 2001-2002 Ximian, Inc.
 
12
 * Copyright (C) 2010 Jon A. Cruz
11
13
 *
12
14
 * Released under GNU GPL, read the file 'COPYING' for more information
13
15
 */
19
21
#endif
20
22
 
21
23
#include <glibmm/i18n.h>
 
24
#include <gtkmm/box.h>
 
25
#include <gtk/gtkvbox.h>
22
26
 
 
27
#include "desktop.h"
 
28
#include "selection.h"
23
29
#include "desktop-handles.h"
24
30
#include "desktop-style.h"
25
31
#include "display/sp-canvas.h"
32
38
#include "sp-radial-gradient.h"
33
39
#include "style.h"
34
40
#include "widgets/paint-selector.h"
35
 
#include "widgets/sp-widget.h"
36
41
#include "xml/repr.h"
37
42
 
38
 
#include "widgets/fill-style.h"
 
43
#include "fill-style.h"
 
44
#include "fill-n-stroke-factory.h"
39
45
 
40
46
 
41
47
// These can be deleted once we sort out the libart dependence.
42
48
 
43
49
#define ART_WIND_RULE_NONZERO 0
44
50
 
45
 
static void sp_fill_style_widget_construct          ( SPWidget *spw,
46
 
                                                      SPPaintSelector *psel );
47
 
 
48
 
static void sp_fill_style_widget_modify_selection   ( SPWidget *spw,
49
 
                                                      Inkscape::Selection *selection,
50
 
                                                      guint flags,
51
 
                                                      SPPaintSelector *psel );
52
 
 
53
 
static void sp_fill_style_widget_change_subselection ( Inkscape::Application *inkscape, SPDesktop *desktop, SPWidget *spw );
54
 
 
55
 
static void sp_fill_style_widget_change_selection   ( SPWidget *spw,
56
 
                                                      Inkscape::Selection *selection,
57
 
                                                      SPPaintSelector *psel );
58
 
 
59
 
static void sp_fill_style_widget_update (SPWidget *spw);
60
 
 
61
 
static void sp_fill_style_widget_paint_mode_changed ( SPPaintSelector *psel,
62
 
                                                      SPPaintSelectorMode mode,
63
 
                                                      SPWidget *spw );
64
 
static void sp_fill_style_widget_fillrule_changed ( SPPaintSelector *psel,
65
 
                                          SPPaintSelectorFillRule mode,
66
 
                                                    SPWidget *spw );
67
 
 
68
 
static void sp_fill_style_widget_paint_dragged (SPPaintSelector *psel, SPWidget *spw );
69
 
static void sp_fill_style_widget_paint_changed (SPPaintSelector *psel, SPWidget *spw );
70
 
 
71
 
GtkWidget *
72
 
sp_fill_style_widget_new (void)
73
 
{
74
 
    GtkWidget *spw = sp_widget_new_global (INKSCAPE);
75
 
 
76
 
    GtkWidget *vb = gtk_vbox_new (FALSE, 0);
77
 
    gtk_widget_show (vb);
78
 
    gtk_container_add (GTK_CONTAINER (spw), vb);
79
 
 
80
 
    GtkWidget *psel = sp_paint_selector_new (true); // with fillrule selector
81
 
    gtk_widget_show (psel);
82
 
    gtk_box_pack_start (GTK_BOX (vb), psel, TRUE, TRUE, 0);
83
 
    g_object_set_data (G_OBJECT (spw), "paint-selector", psel);
84
 
 
85
 
    g_signal_connect ( G_OBJECT (psel), "mode_changed",
86
 
                       G_CALLBACK (sp_fill_style_widget_paint_mode_changed),
87
 
                       spw );
88
 
 
89
 
    g_signal_connect ( G_OBJECT (psel), "dragged",
90
 
                       G_CALLBACK (sp_fill_style_widget_paint_dragged),
91
 
                       spw );
92
 
 
93
 
    g_signal_connect ( G_OBJECT (psel), "changed",
94
 
                       G_CALLBACK (sp_fill_style_widget_paint_changed),
95
 
                       spw );
96
 
 
97
 
    g_signal_connect ( G_OBJECT (psel), "fillrule_changed",
98
 
                       G_CALLBACK (sp_fill_style_widget_fillrule_changed),
99
 
                       spw );
100
 
 
101
 
 
102
 
    g_signal_connect ( G_OBJECT (spw), "construct",
103
 
                       G_CALLBACK (sp_fill_style_widget_construct), psel);
104
 
 
105
 
//FIXME: switch these from spw signals to global inkscape object signals; spw just retranslates
106
 
//those anyway; then eliminate spw
107
 
    g_signal_connect ( G_OBJECT (spw), "modify_selection",
108
 
                       G_CALLBACK (sp_fill_style_widget_modify_selection), psel);
109
 
 
110
 
    g_signal_connect ( G_OBJECT (spw), "change_selection",
111
 
                       G_CALLBACK (sp_fill_style_widget_change_selection), psel);
112
 
 
113
 
    g_signal_connect (INKSCAPE, "change_subselection", G_CALLBACK (sp_fill_style_widget_change_subselection), spw);
114
 
 
115
 
    sp_fill_style_widget_update (SP_WIDGET (spw));
116
 
 
117
 
    return spw;
118
 
 
119
 
} // end of sp_fill_style_widget_new()
120
 
 
121
 
 
122
 
 
123
 
static void
124
 
sp_fill_style_widget_construct( SPWidget *spw, SPPaintSelector */*psel*/ )
125
 
{
126
 
#ifdef SP_FS_VERBOSE
127
 
    g_print ( "Fill style widget constructed: inkscape %p repr %p\n",
128
 
              spw->inkscape, spw->repr );
129
 
#endif
130
 
    if (spw->inkscape) {
131
 
        sp_fill_style_widget_update (spw);
132
 
    }
133
 
 
134
 
} // end of sp_fill_style_widget_construct()
135
 
 
136
 
static void
137
 
sp_fill_style_widget_modify_selection( SPWidget *spw,
138
 
                                       Inkscape::Selection */*selection*/,
139
 
                                       guint flags,
140
 
                                       SPPaintSelector */*psel*/ )
 
51
/* Fill */
 
52
 
 
53
 
 
54
Gtk::Widget *sp_fill_style_widget_new(void)
 
55
{
 
56
    return Inkscape::Widgets::createStyleWidget( FILL );
 
57
}
 
58
 
 
59
 
 
60
namespace Inkscape {
 
61
 
 
62
class FillNStroke : public Gtk::VBox
 
63
{
 
64
public:
 
65
    FillNStroke( FillOrStroke kind );
 
66
    ~FillNStroke();
 
67
 
 
68
    void setFillrule( SPPaintSelector::FillRule mode );
 
69
 
 
70
    void setDesktop(SPDesktop *desktop);
 
71
 
 
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);
 
77
 
 
78
    static void fillruleChangedCB( SPPaintSelector *psel, SPPaintSelector::FillRule mode, FillNStroke *self );
 
79
 
 
80
    void selectionModifiedCB(guint flags);
 
81
 
 
82
    void dragFromPaint();
 
83
    void updateFromPaint();
 
84
 
 
85
    void performUpdate();
 
86
 
 
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
};
 
97
 
 
98
} // namespace Inkscape
 
99
 
 
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
}
 
107
 
 
108
namespace Inkscape {
 
109
 
 
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);
 
116
 
 
117
    return filler;
 
118
}
 
119
 
 
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 );
 
139
 
 
140
    g_signal_connect( G_OBJECT(psel), "dragged",
 
141
                      G_CALLBACK(paintDraggedCB),
 
142
                      this );
 
143
 
 
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
    }
 
152
 
 
153
    performUpdate();
 
154
}
 
155
 
 
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
}
 
167
 
 
168
/**
 
169
 * On signal modified, invokes an update of the fill or stroke style paint object.
 
170
 */
 
171
void FillNStroke::selectionModifiedCB( guint flags )
141
172
{
142
173
    if (flags & ( SP_OBJECT_MODIFIED_FLAG |
143
 
                  SP_OBJECT_PARENT_MODIFIED_FLAG |
144
 
                  SP_OBJECT_STYLE_MODIFIED_FLAG) )
145
 
    {
146
 
        sp_fill_style_widget_update (spw);
147
 
    }
148
 
}
149
 
 
150
 
static void
151
 
sp_fill_style_widget_change_subselection( Inkscape::Application */*inkscape*/,
152
 
                                          SPDesktop */*desktop*/,
153
 
                                          SPWidget *spw )
154
 
{
155
 
    sp_fill_style_widget_update (spw);
156
 
}
157
 
 
158
 
static void
159
 
sp_fill_style_widget_change_selection( SPWidget *spw,
160
 
                                       Inkscape::Selection */*selection*/,
161
 
                                       SPPaintSelector */*psel*/ )
162
 
{
163
 
    sp_fill_style_widget_update (spw);
 
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
}
 
182
 
 
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)));
 
199
 
 
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
    }
164
205
}
165
206
 
166
207
/**
167
 
* \param sel Selection to use, or NULL.
168
 
*/
169
 
static void
170
 
sp_fill_style_widget_update (SPWidget *spw)
 
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()
171
214
{
172
 
    if (g_object_get_data (G_OBJECT (spw), "update"))
173
 
        return;
174
 
 
175
 
    if (g_object_get_data (G_OBJECT (spw), "local")) {
176
 
        g_object_set_data (G_OBJECT (spw), "local", GINT_TO_POINTER (FALSE)); // local change; do nothing, but reset the flag
177
 
        return;
178
 
    }
179
 
 
180
 
    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));
181
 
 
182
 
    SPPaintSelector *psel = SP_PAINT_SELECTOR (g_object_get_data (G_OBJECT (spw), "paint-selector"));
 
215
    if ( update || !desktop ) {
 
216
        return;
 
217
    }
 
218
 
 
219
    if ( dragId ) {
 
220
        // local change; do nothing, but reset the flag
 
221
        g_source_remove(dragId);
 
222
        dragId = 0;
 
223
        return;
 
224
    }
 
225
 
 
226
    update = true;
183
227
 
184
228
    // create temporary style
185
 
    SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
 
229
    SPStyle *query = sp_style_new(desktop->doc());
 
230
 
186
231
    // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection
187
 
    int result = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_FILL); 
 
232
    int result = sp_desktop_query_style(desktop, query, (kind == FILL) ? QUERY_STYLE_PROPERTY_FILL : QUERY_STYLE_PROPERTY_STROKE);
 
233
 
 
234
    SPIPaint &targPaint = (kind == FILL) ? query->fill : query->stroke;
 
235
    SPIScale24 &targOpacity = (kind == FILL) ? query->fill_opacity : query->stroke_opacity;
188
236
 
189
237
    switch (result) {
190
238
        case QUERY_STYLE_NOTHING:
191
239
        {
192
240
            /* No paint at all */
193
 
            sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_EMPTY);
 
241
            psel->setMode(SPPaintSelector::MODE_EMPTY);
194
242
            break;
195
243
        }
196
244
 
197
245
        case QUERY_STYLE_SINGLE:
198
246
        case QUERY_STYLE_MULTIPLE_AVERAGED: // TODO: treat this slightly differently, e.g. display "averaged" somewhere in paint selector
199
 
        case QUERY_STYLE_MULTIPLE_SAME: 
 
247
        case QUERY_STYLE_MULTIPLE_SAME:
200
248
        {
201
 
            SPPaintSelectorMode pselmode = sp_style_determine_paint_selector_mode (query, true);
202
 
            sp_paint_selector_set_mode (psel, pselmode);
203
 
 
204
 
            sp_paint_selector_set_fillrule (psel, query->fill_rule.computed == ART_WIND_RULE_NONZERO? 
205
 
                                     SP_PAINT_SELECTOR_FILLRULE_NONZERO : SP_PAINT_SELECTOR_FILLRULE_EVENODD);
206
 
 
207
 
            if (query->fill.set && query->fill.isColor()) {
208
 
                sp_paint_selector_set_color_alpha (psel, &query->fill.value.color, SP_SCALE24_TO_FLOAT (query->fill_opacity.value));
209
 
            } else if (query->fill.set && query->fill.isPaintserver()) {
210
 
 
211
 
                SPPaintServer *server = SP_STYLE_FILL_SERVER (query);
212
 
 
213
 
                if (SP_IS_LINEARGRADIENT (server)) {
214
 
                    SPGradient *vector = sp_gradient_get_vector (SP_GRADIENT (server), FALSE);
215
 
                    sp_paint_selector_set_gradient_linear (psel, vector);
216
 
 
217
 
                    SPLinearGradient *lg = SP_LINEARGRADIENT (server);
218
 
                    sp_paint_selector_set_gradient_properties (psel,
219
 
                                                       SP_GRADIENT_UNITS (lg),
220
 
                                                       SP_GRADIENT_SPREAD (lg));
221
 
                } else if (SP_IS_RADIALGRADIENT (server)) {
222
 
                    SPGradient *vector = sp_gradient_get_vector (SP_GRADIENT (server), FALSE);
223
 
                    sp_paint_selector_set_gradient_radial (psel, vector);
224
 
 
225
 
                    SPRadialGradient *rg = SP_RADIALGRADIENT (server);
226
 
                    sp_paint_selector_set_gradient_properties (psel,
227
 
                                                       SP_GRADIENT_UNITS (rg),
228
 
                                                       SP_GRADIENT_SPREAD (rg));
229
 
                } else if (SP_IS_PATTERN (server)) {
230
 
                    SPPattern *pat = pattern_getroot (SP_PATTERN (server));
231
 
                    sp_update_pattern_list (psel, pat);
 
249
            SPPaintSelector::Mode pselmode = SPPaintSelector::getModeForStyle(*query, kind);
 
250
            psel->setMode(pselmode);
 
251
 
 
252
            if (kind == FILL) {
 
253
                psel->setFillrule(query->fill_rule.computed == ART_WIND_RULE_NONZERO?
 
254
                                  SPPaintSelector::FILLRULE_NONZERO : SPPaintSelector::FILLRULE_EVENODD);
 
255
            }
 
256
 
 
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()) {
 
260
 
 
261
                SPPaintServer *server = (kind == FILL) ? query->getFillPaintServer() : query->getStrokePaintServer();
 
262
 
 
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 );
 
269
 
 
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 );
 
276
 
 
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 );
232
283
                }
233
284
            }
234
285
            break;
236
287
 
237
288
        case QUERY_STYLE_MULTIPLE_DIFFERENT:
238
289
        {
239
 
            sp_paint_selector_set_mode (psel, SP_PAINT_SELECTOR_MODE_MULTIPLE);
 
290
            psel->setMode(SPPaintSelector::MODE_MULTIPLE);
240
291
            break;
241
292
        }
242
293
    }
243
294
 
244
295
    sp_style_unref(query);
245
296
 
246
 
    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
247
 
 
248
 
}
249
 
 
250
 
 
251
 
static void
252
 
sp_fill_style_widget_paint_mode_changed ( SPPaintSelector *psel,
253
 
                                          SPPaintSelectorMode /*mode*/,
254
 
                                          SPWidget *spw )
255
 
{
256
 
    if (g_object_get_data (G_OBJECT (spw), "update"))
257
 
        return;
258
 
 
259
 
    /* TODO: Does this work? */
260
 
    /* TODO: Not really, here we have to get old color back from object */
261
 
    /* Instead of relying on paint widget having meaningful colors set */
262
 
    sp_fill_style_widget_paint_changed (psel, spw);
263
 
}
264
 
 
265
 
static void
266
 
sp_fill_style_widget_fillrule_changed ( SPPaintSelector */*psel*/,
267
 
                                          SPPaintSelectorFillRule mode,
268
 
                                          SPWidget *spw )
269
 
{
270
 
    if (g_object_get_data (G_OBJECT (spw), "update"))
271
 
        return;
272
 
 
273
 
    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
274
 
 
275
 
    SPCSSAttr *css = sp_repr_css_attr_new ();
276
 
    sp_repr_css_set_property (css, "fill-rule", mode == SP_PAINT_SELECTOR_FILLRULE_EVENODD? "evenodd":"nonzero");
277
 
 
278
 
    sp_desktop_set_style (desktop, css);
279
 
 
280
 
    sp_repr_css_attr_unref (css);
281
 
 
282
 
    sp_document_done (SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_FILL_STROKE, 
283
 
                      _("Change fill rule"));
284
 
}
285
 
 
286
 
static gchar const *undo_label_1 = "fill:flatcolor:1";
287
 
static gchar const *undo_label_2 = "fill:flatcolor:2";
288
 
static gchar const *undo_label = undo_label_1;
289
 
 
290
 
/**
291
 
This is called repeatedly while you are dragging a color slider, only for flat color
292
 
modes. Previously it set the color in style but did not update the repr for efficiency, however
293
 
this was flakey and didn't buy us almost anything. So now it does the same as _changed, except
294
 
lumps all its changes for undo.
295
 
 */
296
 
static void
297
 
sp_fill_style_widget_paint_dragged (SPPaintSelector *psel, SPWidget *spw)
298
 
{
299
 
    if (!spw->inkscape) {
300
 
        return;
301
 
    }
302
 
 
303
 
    if (g_object_get_data (G_OBJECT (spw), "update")) {
304
 
        return;
305
 
    }
306
 
 
307
 
    if (g_object_get_data (G_OBJECT (spw), "local")) {
308
 
        // previous local flag not cleared yet; 
309
 
        // this means dragged events come too fast, so we better skip this one to speed up display 
 
297
    update = false;
 
298
}
 
299
 
 
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
}
 
314
 
 
315
void FillNStroke::fillruleChangedCB( SPPaintSelector * /*psel*/,
 
316
                                     SPPaintSelector::FillRule mode,
 
317
                                     FillNStroke *self )
 
318
{
 
319
    if (self) {
 
320
        self->setFillrule(mode);
 
321
    }
 
322
}
 
323
 
 
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");
 
329
 
 
330
        sp_desktop_set_style(desktop, css);
 
331
 
 
332
        sp_repr_css_attr_unref(css);
 
333
        css = 0;
 
334
 
 
335
        sp_document_done(desktop->doc(), SP_VERB_DIALOG_FILL_STROKE,
 
336
                         _("Change fill rule"));
 
337
    }
 
338
}
 
339
 
 
340
static gchar const *undo_F_label_1 = "fill:flatcolor:1";
 
341
static gchar const *undo_F_label_2 = "fill:flatcolor:2";
 
342
 
 
343
static gchar const *undo_S_label_1 = "stroke:flatcolor:1";
 
344
static gchar const *undo_S_label_2 = "stroke:flatcolor:2";
 
345
 
 
346
static gchar const *undo_F_label = undo_F_label_1;
 
347
static gchar const *undo_S_label = undo_S_label_1;
 
348
 
 
349
 
 
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
}
 
359
 
 
360
 
 
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;
 
370
 
 
371
                self->dragFromPaint();
 
372
                self->performUpdate();
 
373
            }
 
374
            keepGoing = FALSE;
 
375
        }
 
376
    } else {
 
377
        keepGoing = FALSE;
 
378
    }
 
379
    return keepGoing;
 
380
}
 
381
 
 
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
    }
 
393
 
 
394
    guint32 when = gtk_get_current_event_time();
 
395
 
 
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
    }
 
402
 
 
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
310
406
        // (it's safe to do this in any case)
311
407
        return;
312
408
    }
 
409
    lastDrag = when;
313
410
 
314
 
    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));
 
411
    update = true;
315
412
 
316
413
    switch (psel->mode) {
317
 
 
318
 
        case SP_PAINT_SELECTOR_MODE_COLOR_RGB:
319
 
        case SP_PAINT_SELECTOR_MODE_COLOR_CMYK:
 
414
        case SPPaintSelector::MODE_COLOR_RGB:
 
415
        case SPPaintSelector::MODE_COLOR_CMYK:
320
416
        {
321
 
            sp_paint_selector_set_flat_color (psel, SP_ACTIVE_DESKTOP, "fill", "fill-opacity");
322
 
            sp_document_maybe_done (sp_desktop_document(SP_ACTIVE_DESKTOP), undo_label, SP_VERB_DIALOG_FILL_STROKE, 
323
 
                                    _("Set fill color"));
324
 
            g_object_set_data (G_OBJECT (spw), "local", GINT_TO_POINTER (TRUE)); // local change, do not update from selection
 
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"));
325
422
            break;
326
423
        }
327
424
 
328
425
        default:
329
 
            g_warning ( "file %s: line %d: Paint %d should not emit 'dragged'",
330
 
                        __FILE__, __LINE__, psel->mode );
 
426
            g_warning( "file %s: line %d: Paint %d should not emit 'dragged'",
 
427
                       __FILE__, __LINE__, psel->mode );
331
428
            break;
332
 
 
333
429
    }
334
 
    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
 
430
    update = false;
335
431
}
336
432
 
337
 
 
338
433
/**
339
434
This is called (at least) when:
340
435
1  paint selector mode is switched (e.g. flat color -> gradient)
342
437
3  you changed a gradient selector parameter (e.g. spread)
343
438
Must update repr.
344
439
 */
345
 
static void
346
 
sp_fill_style_widget_paint_changed ( SPPaintSelector *psel,
347
 
                                     SPWidget *spw )
 
440
void FillNStroke::paintChangedCB( SPPaintSelector * /*psel*/, FillNStroke *self )
348
441
{
349
 
    if (g_object_get_data (G_OBJECT (spw), "update")) {
350
 
        return;
 
442
#ifdef SP_FS_VERBOSE
 
443
    g_message("paintChangedCB(psel, spw:%p)", self);
 
444
#endif
 
445
    if (self && !self->update) {
 
446
        self->updateFromPaint();
351
447
    }
352
 
    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));
 
448
}
353
449
 
354
 
    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
 
450
void FillNStroke::updateFromPaint()
 
451
{
355
452
    if (!desktop) {
356
453
        return;
357
454
    }
358
 
    SPDocument *document = sp_desktop_document (desktop);
359
 
    Inkscape::Selection *selection = sp_desktop_selection (desktop);
 
455
    update = true;
 
456
 
 
457
    SPDocument *document = sp_desktop_document(desktop);
 
458
    Inkscape::Selection *selection = sp_desktop_selection(desktop);
360
459
 
361
460
    GSList const *items = selection->itemList();
362
461
 
363
462
    switch (psel->mode) {
364
 
 
365
 
        case SP_PAINT_SELECTOR_MODE_EMPTY:
 
463
        case SPPaintSelector::MODE_EMPTY:
366
464
            // This should not happen.
367
 
            g_warning ( "file %s: line %d: Paint %d should not emit 'changed'",
368
 
                        __FILE__, __LINE__, psel->mode);
 
465
            g_warning( "file %s: line %d: Paint %d should not emit 'changed'",
 
466
                       __FILE__, __LINE__, psel->mode);
369
467
            break;
370
 
        case SP_PAINT_SELECTOR_MODE_MULTIPLE:
 
468
        case SPPaintSelector::MODE_MULTIPLE:
371
469
            // This happens when you switch multiple objects with different gradients to flat color;
372
470
            // nothing to do here.
373
471
            break;
374
472
 
375
 
        case SP_PAINT_SELECTOR_MODE_NONE:
 
473
        case SPPaintSelector::MODE_NONE:
376
474
        {
377
 
            SPCSSAttr *css = sp_repr_css_attr_new ();
378
 
            sp_repr_css_set_property (css, "fill", "none");
379
 
 
380
 
            sp_desktop_set_style (desktop, css);
381
 
 
382
 
            sp_repr_css_attr_unref (css);
383
 
 
384
 
            sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE, 
385
 
                              _("Remove fill"));
 
475
            SPCSSAttr *css = sp_repr_css_attr_new();
 
476
            sp_repr_css_set_property(css, (kind == FILL) ? "fill" : "stroke", "none");
 
477
 
 
478
            sp_desktop_set_style(desktop, css);
 
479
 
 
480
            sp_repr_css_attr_unref(css);
 
481
            css = 0;
 
482
 
 
483
            sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
 
484
                             (kind == FILL) ? _("Remove fill") : _("Remove stroke"));
386
485
            break;
387
486
        }
388
487
 
389
 
        case SP_PAINT_SELECTOR_MODE_COLOR_RGB:
390
 
        case SP_PAINT_SELECTOR_MODE_COLOR_CMYK:
 
488
        case SPPaintSelector::MODE_COLOR_RGB:
 
489
        case SPPaintSelector::MODE_COLOR_CMYK:
391
490
        {
392
 
            // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in losing release events
393
 
            sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(desktop), 0);
394
 
 
395
 
            sp_paint_selector_set_flat_color (psel, desktop, "fill", "fill-opacity");
396
 
            sp_document_maybe_done (sp_desktop_document(desktop), undo_label, SP_VERB_DIALOG_FILL_STROKE,
397
 
                                    _("Set fill color"));
398
 
            // resume interruptibility
399
 
            sp_canvas_end_forced_full_redraws(sp_desktop_canvas(desktop));
 
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
            }
 
495
 
 
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"));
 
501
 
 
502
            if (kind == FILL) {
 
503
                // resume interruptibility
 
504
                sp_canvas_end_forced_full_redraws(sp_desktop_canvas(desktop));
 
505
            }
400
506
 
401
507
            // on release, toggle undo_label so that the next drag will not be lumped with this one
402
 
            if (undo_label == undo_label_1)
403
 
                undo_label = undo_label_2;
404
 
            else
405
 
                undo_label = undo_label_1;
 
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
            }
406
515
 
407
516
            break;
408
517
        }
409
518
 
410
 
        case SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR:
411
 
        case SP_PAINT_SELECTOR_MODE_GRADIENT_RADIAL:
 
519
        case SPPaintSelector::MODE_GRADIENT_LINEAR:
 
520
        case SPPaintSelector::MODE_GRADIENT_RADIAL:
 
521
        case SPPaintSelector::MODE_SWATCH:
412
522
            if (items) {
413
 
                SPGradientType const gradient_type = ( psel->mode == SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR
 
523
                SPGradientType const gradient_type = ( psel->mode != SPPaintSelector::MODE_GRADIENT_RADIAL
414
524
                                                       ? SP_GRADIENT_TYPE_LINEAR
415
525
                                                       : SP_GRADIENT_TYPE_RADIAL );
416
 
 
417
 
                // HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs
418
 
                SPCSSAttr *css = sp_repr_css_attr_new();
419
 
                sp_repr_css_set_property(css, "fill-opacity", "1.0");
420
 
 
421
 
                SPGradient *vector = sp_paint_selector_get_gradient_vector(psel);
 
526
                bool createSwatch = (psel->mode == SPPaintSelector::MODE_SWATCH);
 
527
 
 
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
                }
 
534
 
 
535
                SPGradient *vector = psel->getGradientVector();
422
536
                if (!vector) {
423
537
                    /* No vector in paint selector should mean that we just changed mode */
424
538
 
425
 
                    SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
426
 
                    int result = objects_query_fillstroke ((GSList *) items, query, true);
427
 
                    guint32 common_rgb = 0;
 
539
                    SPStyle *query = sp_style_new(desktop->doc());
 
540
                    int result = objects_query_fillstroke(const_cast<GSList *>(items), query, kind == FILL);
428
541
                    if (result == QUERY_STYLE_MULTIPLE_SAME) {
429
 
                        if (!query->fill.isColor()) {
430
 
                            common_rgb = sp_desktop_get_color(desktop, true);
 
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);
431
546
                        } else {
432
 
                            common_rgb = query->fill.value.color.toRGBA32( 0xff );
433
 
                        }
434
 
                        vector = sp_document_default_gradient_vector(document, common_rgb);
 
547
                            common = targPaint.value.color;
 
548
                        }
 
549
                        vector = sp_document_default_gradient_vector( document, common, createSwatch );
 
550
                        if ( vector && createSwatch ) {
 
551
                            vector->setSwatch();
 
552
                        }
435
553
                    }
436
554
                    sp_style_unref(query);
437
555
 
438
556
                    for (GSList const *i = items; i != NULL; i = i->next) {
439
557
                        //FIXME: see above
440
 
                        sp_repr_css_change_recursive(SP_OBJECT_REPR(i->data), css, "style");
 
558
                        if (kind == FILL) {
 
559
                            sp_repr_css_change_recursive(reinterpret_cast<SPObject*>(i->data)->repr, css, "style");
 
560
                        }
441
561
 
442
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
                            }
443
567
                            sp_item_set_gradient(SP_ITEM(i->data),
444
 
                                                 sp_gradient_vector_for_object(document, desktop, SP_OBJECT(i->data), true),
445
 
                                                 gradient_type, true);
 
568
                                                 gr,
 
569
                                                 gradient_type, kind == FILL);
446
570
                        } else {
447
 
                            sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, true);
 
571
                            sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, kind == FILL);
448
572
                        }
449
573
                    }
450
574
                } else {
451
 
                    /* We have changed from another gradient type, or modified spread/units within
452
 
                     * this gradient type. */
453
 
                    vector = sp_gradient_ensure_vector_normalized (vector);
 
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);
454
578
                    for (GSList const *i = items; i != NULL; i = i->next) {
455
579
                        //FIXME: see above
456
 
                        sp_repr_css_change_recursive (SP_OBJECT_REPR (i->data), css, "style");
 
580
                        if (kind == FILL) {
 
581
                            sp_repr_css_change_recursive(reinterpret_cast<SPObject*>(i->data)->repr, css, "style");
 
582
                        }
457
583
 
458
 
                        SPGradient *gr = sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, true);
459
 
                        sp_gradient_selector_attrs_to_gradient (gr, psel);
 
584
                        SPGradient *gr = sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, kind == FILL);
 
585
                        psel->pushAttrsToGradient( gr );
460
586
                    }
461
587
                }
462
588
 
463
 
                sp_repr_css_attr_unref (css);
 
589
                if (css) {
 
590
                    sp_repr_css_attr_unref(css);
 
591
                    css = 0;
 
592
                }
464
593
 
465
 
                sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE, 
466
 
                                  _("Set gradient on fill"));
 
594
                sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
 
595
                                 (kind == FILL) ? _("Set gradient on fill") : _("Set gradient on stroke"));
467
596
            }
468
597
            break;
469
598
 
470
 
        case SP_PAINT_SELECTOR_MODE_PATTERN:
 
599
        case SPPaintSelector::MODE_PATTERN:
471
600
 
472
601
            if (items) {
473
602
 
474
 
                SPPattern *pattern = sp_paint_selector_get_pattern (psel);
 
603
                SPPattern *pattern = psel->getPattern();
475
604
                if (!pattern) {
476
605
 
477
606
                    /* No Pattern in paint selector should mean that we just
479
608
                     */
480
609
 
481
610
                } else {
482
 
                    Inkscape::XML::Node *patrepr = SP_OBJECT_REPR(pattern);
483
 
                    SPCSSAttr *css = sp_repr_css_attr_new ();
484
 
                    gchar *urltext = g_strdup_printf ("url(#%s)", patrepr->attribute("id"));
485
 
                    sp_repr_css_set_property (css, "fill", urltext);
 
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);
486
615
 
487
616
                    // HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs
488
 
                    sp_repr_css_set_property(css, "fill-opacity", "1.0");
 
617
                    if (kind == FILL) {
 
618
                        sp_repr_css_set_property(css, "fill-opacity", "1.0");
 
619
                    }
489
620
 
490
621
                    // cannot just call sp_desktop_set_style, because we don't want to touch those
491
622
                    // objects who already have the same root pattern but through a different href
492
623
                    // chain. FIXME: move this to a sp_item_set_pattern
493
624
                    for (GSList const *i = items; i != NULL; i = i->next) {
494
 
                         SPObject *selobj = SP_OBJECT (i->data);
 
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);
495
630
 
496
 
                         SPStyle *style = SP_OBJECT_STYLE (selobj);
497
 
                         if (style && style->fill.isPaintserver()) {
498
 
                             SPObject *server = SP_OBJECT_STYLE_FILL_SERVER (selobj);
499
 
                             if (SP_IS_PATTERN (server) && pattern_getroot (SP_PATTERN(server)) == pattern)
 
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)
500
637
                                // only if this object's pattern is not rooted in our selected pattern, apply
501
 
                                 continue;
502
 
                         }
503
 
 
504
 
                         sp_desktop_apply_css_recursive (selobj, css, true);
505
 
                     }
506
 
 
507
 
                    sp_repr_css_attr_unref (css);
508
 
                    g_free (urltext);
 
638
                                continue;
 
639
                        }
 
640
 
 
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
                    }
 
647
 
 
648
                    sp_repr_css_attr_unref(css);
 
649
                    css = 0;
 
650
                    g_free(urltext);
509
651
 
510
652
                } // end if
511
653
 
512
 
                sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE, 
513
 
                                  _("Set pattern on fill"));
514
 
 
 
654
                sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
 
655
                                 (kind == FILL) ? _("Set pattern on fill") :
 
656
                                 _("Set pattern on stroke"));
515
657
            } // end if
516
658
 
517
659
            break;
518
660
 
519
 
        case SP_PAINT_SELECTOR_MODE_UNSET:
 
661
        case SPPaintSelector::MODE_UNSET:
520
662
            if (items) {
521
 
                    SPCSSAttr *css = sp_repr_css_attr_new ();
522
 
                    sp_repr_css_unset_property (css, "fill");
523
 
 
524
 
                    sp_desktop_set_style (desktop, css);
525
 
                    sp_repr_css_attr_unref (css);
526
 
 
527
 
                    sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE, 
528
 
                                      _("Unset fill"));
 
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
                }
 
676
 
 
677
                sp_desktop_set_style(desktop, css);
 
678
                sp_repr_css_attr_unref(css);
 
679
                css = 0;
 
680
 
 
681
                sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
 
682
                                 (kind == FILL) ? _("Unset fill") : _("Unset stroke"));
529
683
            }
530
684
            break;
531
685
 
532
686
        default:
533
 
            g_warning ( "file %s: line %d: Paint selector should not be in "
534
 
                        "mode %d",
535
 
                        __FILE__, __LINE__, psel->mode );
 
687
            g_warning( "file %s: line %d: Paint selector should not be in "
 
688
                       "mode %d",
 
689
                       __FILE__, __LINE__,
 
690
                       psel->mode );
536
691
            break;
537
692
    }
538
693
 
539
 
    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
 
694
    update = false;
540
695
}
541
696
 
 
697
} // namespace Inkscape
542
698
 
543
699
/*
544
700
  Local Variables: