~centralelyon2010/inkscape/imagelinks2

« back to all changes in this revision

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

  • Committer: Jon A. Cruz
  • Date: 2010-03-27 07:50:41 UTC
  • mto: (9012.1.276 trunk)
  • mto: This revision was merged to the branch mainline in revision 9013.
  • Revision ID: jon@joncruz.org-20100327075041-xregd9fll06edey5
Phase 1 - unify/reconcile copy-n-paste edit madness of Fill and Stroke edit panes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
#include "desktop-handles.h"
26
26
#include "desktop-style.h"
27
27
#include "dialogs/dialog-events.h"
 
28
#include "display/canvas-bpath.h" // for SP_STROKE_LINEJOIN_*
28
29
#include "display/nr-arena.h"
29
30
#include "display/nr-arena-item.h"
30
31
#include "document-private.h"
54
55
#include "widgets/spw-utilities.h"
55
56
#include "xml/repr.h"
56
57
 
57
 
#include "widgets/stroke-style.h"
58
 
 
 
58
#include "stroke-style.h"
 
59
#include "fill-n-stroke-factory.h"
 
60
 
 
61
namespace Inkscape {
 
62
namespace Widgets {
 
63
GtkWidget *createStyleWidgetS( FillOrStroke kind );
 
64
}
 
65
}
 
66
 
 
67
 
 
68
// These can be deleted once we sort out the libart dependence.
 
69
 
 
70
#define ART_WIND_RULE_NONZERO 0
59
71
 
60
72
/* Paint */
61
73
 
62
 
static void sp_stroke_style_paint_selection_modified (SPWidget *spw, Inkscape::Selection *selection, guint flags, SPPaintSelector *psel);
63
 
static void sp_stroke_style_paint_selection_changed (SPWidget *spw, Inkscape::Selection *selection, SPPaintSelector *psel);
64
 
static void sp_stroke_style_paint_update(SPWidget *spw);
65
 
 
66
 
static void sp_stroke_style_paint_mode_changed(SPPaintSelector *psel, SPPaintSelector::Mode mode, SPWidget *spw);
67
 
static void sp_stroke_style_paint_dragged(SPPaintSelector *psel, SPWidget *spw);
68
 
static void sp_stroke_style_paint_changed(SPPaintSelector *psel, SPWidget *spw);
69
 
 
70
 
static void sp_stroke_style_widget_change_subselection ( Inkscape::Application *inkscape, SPDesktop *desktop, SPWidget *spw );
71
 
static void sp_stroke_style_widget_transientize_callback(Inkscape::Application *inkscape,
72
 
                                                         SPDesktop *desktop,
73
 
                                                         SPWidget *spw );
 
74
static void fillnstroke_constructed(SPWidget *spw, SPPaintSelector *psel);
 
75
static void fillnstroke_fillrule_changed(SPPaintSelector *psel, SPPaintSelector::FillRule mode, SPWidget *spw);
 
76
 
 
77
static void fillnstroke_selection_modified(SPWidget *spw, Inkscape::Selection *selection, guint flags, SPPaintSelector *psel);
 
78
static void fillnstroke_selection_changed(SPWidget *spw, Inkscape::Selection *selection, SPPaintSelector *psel);
 
79
static void fillnstroke_subselection_changed(Inkscape::Application *inkscape, SPDesktop *desktop, SPWidget *spw);
 
80
 
 
81
static void fillnstroke_paint_mode_changed(SPPaintSelector *psel, SPPaintSelector::Mode mode, SPWidget *spw);
 
82
static void fillnstroke_paint_dragged(SPPaintSelector *psel, SPWidget *spw);
 
83
static void fillnstroke_paint_changed(SPPaintSelector *psel, SPWidget *spw);
 
84
 
 
85
static void fillnstroke_transientize_called(Inkscape::Application *inkscape, SPDesktop *desktop, SPWidget *spw);
 
86
 
 
87
static void fillnstroke_performUpdate(SPWidget *spw);
74
88
 
75
89
/** Marker selection option menus */
76
90
static Gtk::OptionMenu * marker_start_menu = NULL;
86
100
 
87
101
static Inkscape::UI::Cache::SvgPreview svg_preview_cache;
88
102
 
 
103
GtkWidget *sp_stroke_style_paint_widget_new(void)
 
104
{
 
105
    return Inkscape::Widgets::createStyleWidgetS( STROKE );
 
106
}
 
107
 
89
108
/**
90
 
 * Create the stroke style widget, and hook up all the signals.
 
109
 * Create the fill or stroke style widget, and hook up all the signals.
91
110
 */
92
 
GtkWidget *
93
 
sp_stroke_style_paint_widget_new(void)
 
111
GtkWidget *Inkscape::Widgets::createStyleWidgetS( FillOrStroke kind )
94
112
{
95
 
    GtkWidget *spw, *psel;
96
 
 
97
 
    spw = sp_widget_new_global(INKSCAPE);
98
 
 
99
 
    psel = sp_paint_selector_new(false); // without fillrule selector
 
113
    GtkWidget *spw = sp_widget_new_global(INKSCAPE);
 
114
 
 
115
    // with or without fillrule selector
 
116
    GtkWidget *psel = sp_paint_selector_new(kind == FILL);
100
117
    gtk_widget_show(psel);
101
118
    gtk_container_add(GTK_CONTAINER(spw), psel);
102
 
    gtk_object_set_data(GTK_OBJECT(spw), "paint-selector", psel);
103
 
 
104
 
    gtk_signal_connect(GTK_OBJECT(spw), "modify_selection",
105
 
                       GTK_SIGNAL_FUNC(sp_stroke_style_paint_selection_modified),
106
 
                       psel);
107
 
    gtk_signal_connect(GTK_OBJECT(spw), "change_selection",
108
 
                       GTK_SIGNAL_FUNC(sp_stroke_style_paint_selection_changed),
109
 
                       psel);
110
 
 
111
 
    g_signal_connect (INKSCAPE, "change_subselection", G_CALLBACK (sp_stroke_style_widget_change_subselection), spw);
112
 
 
113
 
    g_signal_connect (G_OBJECT(INKSCAPE), "activate_desktop", G_CALLBACK (sp_stroke_style_widget_transientize_callback), spw );
114
 
 
115
 
    gtk_signal_connect(GTK_OBJECT(psel), "mode_changed",
116
 
                       GTK_SIGNAL_FUNC(sp_stroke_style_paint_mode_changed),
117
 
                       spw);
118
 
    gtk_signal_connect(GTK_OBJECT(psel), "dragged",
119
 
                       GTK_SIGNAL_FUNC(sp_stroke_style_paint_dragged),
120
 
                       spw);
121
 
    gtk_signal_connect(GTK_OBJECT(psel), "changed",
122
 
                       GTK_SIGNAL_FUNC(sp_stroke_style_paint_changed),
123
 
                       spw);
124
 
 
125
 
    sp_stroke_style_paint_update (SP_WIDGET(spw));
 
119
    g_object_set_data(G_OBJECT(spw), "paint-selector", psel);
 
120
    g_object_set_data(G_OBJECT(spw), "kind", GINT_TO_POINTER(kind));
 
121
 
 
122
    if (kind == FILL) {
 
123
        g_signal_connect( G_OBJECT(spw), "construct",
 
124
                          G_CALLBACK(fillnstroke_constructed),
 
125
                          psel );
 
126
    }
 
127
 
 
128
//FIXME: switch these from spw signals to global inkscape object signals; spw just retranslates
 
129
//those anyway; then eliminate spw
 
130
    g_signal_connect( G_OBJECT(spw), "modify_selection",
 
131
                      G_CALLBACK(fillnstroke_selection_modified),
 
132
                      psel );
 
133
 
 
134
    g_signal_connect( G_OBJECT(spw), "change_selection",
 
135
                      G_CALLBACK(fillnstroke_selection_changed),
 
136
                      psel );
 
137
 
 
138
    g_signal_connect( INKSCAPE, "change_subselection",
 
139
                      G_CALLBACK(fillnstroke_subselection_changed),
 
140
                      spw );
 
141
 
 
142
    if (kind == STROKE) {
 
143
        g_signal_connect( G_OBJECT(INKSCAPE), "activate_desktop",
 
144
                          G_CALLBACK(fillnstroke_transientize_called),
 
145
                          spw );
 
146
    }
 
147
 
 
148
    g_signal_connect( G_OBJECT(psel), "mode_changed",
 
149
                      G_CALLBACK(fillnstroke_paint_mode_changed),
 
150
                      spw );
 
151
 
 
152
    g_signal_connect( G_OBJECT(psel), "dragged",
 
153
                      G_CALLBACK(fillnstroke_paint_dragged),
 
154
                      spw );
 
155
 
 
156
    g_signal_connect( G_OBJECT(psel), "changed",
 
157
                      G_CALLBACK(fillnstroke_paint_changed),
 
158
                      spw );
 
159
 
 
160
    if (kind == FILL) {
 
161
        g_signal_connect( G_OBJECT(psel), "fillrule_changed",
 
162
                          G_CALLBACK(fillnstroke_fillrule_changed),
 
163
                          spw );
 
164
    }
 
165
 
 
166
    fillnstroke_performUpdate(SP_WIDGET(spw));
 
167
 
126
168
    return spw;
127
169
}
128
170
 
 
171
static void fillnstroke_constructed( SPWidget *spw, SPPaintSelector * /*psel*/ )
 
172
{
 
173
#ifdef SP_FS_VERBOSE
 
174
    FillOrStroke kind = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(spw), "kind")) ? FILL : STROKE;
 
175
    g_print( "[%s] style widget constructed: inkscape %p\n",
 
176
             (kind == FILL) ? "fill" : "style",
 
177
              spw->inkscape );
 
178
#endif
 
179
    if (spw->inkscape) {
 
180
        fillnstroke_performUpdate(spw);
 
181
    }
 
182
 
 
183
}
 
184
 
129
185
/**
130
 
 * On signal modified, invokes an update of the stroke style paint object.
 
186
 * On signal modified, invokes an update of the fill or stroke style paint object.
131
187
 */
132
 
static void
133
 
sp_stroke_style_paint_selection_modified( SPWidget *spw,
134
 
                                          Inkscape::Selection */*selection*/,
135
 
                                          guint flags,
136
 
                                          SPPaintSelector */*psel*/ )
 
188
static void fillnstroke_selection_modified( SPWidget *spw,
 
189
                                    Inkscape::Selection * /*selection*/,
 
190
                                    guint flags,
 
191
                                    SPPaintSelector * /*psel*/ )
137
192
{
138
 
    if (flags & ( SP_OBJECT_MODIFIED_FLAG | SP_OBJECT_PARENT_MODIFIED_FLAG |
 
193
    if (flags & ( SP_OBJECT_MODIFIED_FLAG |
 
194
                  SP_OBJECT_PARENT_MODIFIED_FLAG |
139
195
                  SP_OBJECT_STYLE_MODIFIED_FLAG) ) {
140
 
        sp_stroke_style_paint_update(spw);
 
196
#ifdef SP_FS_VERBOSE
 
197
        g_message("fillnstroke_selection_modified()");
 
198
#endif
 
199
        fillnstroke_performUpdate(spw);
141
200
    }
142
201
}
143
202
 
144
 
 
145
 
/**
146
 
 * On signal selection changed, invokes an update of the stroke style paint object.
147
 
 */
148
 
static void
149
 
sp_stroke_style_paint_selection_changed( SPWidget *spw,
150
 
                                         Inkscape::Selection */*selection*/,
151
 
                                         SPPaintSelector */*psel*/ )
152
 
{
153
 
    sp_stroke_style_paint_update (spw);
154
 
}
155
 
 
156
 
 
157
 
/**
158
 
 * On signal change subselection, invoke an update of the stroke style widget.
159
 
 */
160
 
static void
161
 
sp_stroke_style_widget_change_subselection( Inkscape::Application */*inkscape*/,
162
 
                                            SPDesktop */*desktop*/,
163
 
                                            SPWidget *spw )
164
 
{
165
 
    sp_stroke_style_paint_update (spw);
166
 
}
167
 
 
168
 
/**
169
 
 * Gets the active stroke style property, then sets the appropriate color, alpha, gradient,
170
 
 * pattern, etc. for the paint-selector.
171
 
 */
172
 
static void
173
 
sp_stroke_style_paint_update (SPWidget *spw)
174
 
{
175
 
    if (gtk_object_get_data(GTK_OBJECT(spw), "update")) {
 
203
/**
 
204
 * On signal selection changed, invokes an update of the fill or stroke style paint object.
 
205
 */
 
206
static void fillnstroke_selection_changed( SPWidget *spw,
 
207
                                   Inkscape::Selection * /*selection*/,
 
208
                                   SPPaintSelector * /*psel*/ )
 
209
{
 
210
    fillnstroke_performUpdate(spw);
 
211
}
 
212
 
 
213
/**
 
214
 * On signal change subselection, invoke an update of the fill or stroke style widget.
 
215
 */
 
216
static void fillnstroke_subselection_changed( Inkscape::Application * /*inkscape*/,
 
217
                                      SPDesktop * /*desktop*/,
 
218
                                      SPWidget *spw )
 
219
{
 
220
    fillnstroke_performUpdate(spw);
 
221
}
 
222
 
 
223
/**
 
224
 * Gets the active fill or stroke style property, then sets the appropriate
 
225
 * color, alpha, gradient, pattern, etc. for the paint-selector.
 
226
 *
 
227
 * @param sel Selection to use, or NULL.
 
228
 */
 
229
static void fillnstroke_performUpdate( SPWidget *spw )
 
230
{
 
231
    if ( g_object_get_data(G_OBJECT(spw), "update") ) {
176
232
        return;
177
233
    }
178
234
 
179
 
    gtk_object_set_data(GTK_OBJECT(spw), "update", GINT_TO_POINTER(TRUE));
180
 
 
181
 
    SPPaintSelector *psel = SP_PAINT_SELECTOR(gtk_object_get_data(GTK_OBJECT(spw), "paint-selector"));
 
235
    FillOrStroke kind = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(spw), "kind")) ? FILL : STROKE;
 
236
 
 
237
    if (kind == FILL) {
 
238
        if ( g_object_get_data(G_OBJECT(spw), "local") ) {
 
239
            g_object_set_data(G_OBJECT(spw), "local", GINT_TO_POINTER(FALSE)); // local change; do nothing, but reset the flag
 
240
            return;
 
241
        }
 
242
    }
 
243
 
 
244
    g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(TRUE));
 
245
 
 
246
    SPPaintSelector *psel = SP_PAINT_SELECTOR(g_object_get_data(G_OBJECT(spw), "paint-selector"));
182
247
 
183
248
    // create temporary style
184
 
    SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
185
 
    // query into it
186
 
    int result = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKE);
 
249
    SPStyle *query = sp_style_new(SP_ACTIVE_DOCUMENT);
 
250
 
 
251
    // query style from desktop into it. This returns a result flag and fills query with the style of subselection, if any, or selection
 
252
    int result = sp_desktop_query_style(SP_ACTIVE_DESKTOP, query, (kind == FILL) ? QUERY_STYLE_PROPERTY_FILL : QUERY_STYLE_PROPERTY_STROKE);
 
253
 
 
254
    SPIPaint &targPaint = (kind == FILL) ? query->fill : query->stroke;
 
255
    SPIScale24 &targOpacity = (kind == FILL) ? query->fill_opacity : query->stroke_opacity;
187
256
 
188
257
    switch (result) {
189
258
        case QUERY_STYLE_NOTHING:
197
266
        case QUERY_STYLE_MULTIPLE_AVERAGED: // TODO: treat this slightly differently, e.g. display "averaged" somewhere in paint selector
198
267
        case QUERY_STYLE_MULTIPLE_SAME:
199
268
        {
200
 
            SPPaintSelector::Mode pselmode = SPPaintSelector::getModeForStyle(*query, false);
 
269
            SPPaintSelector::Mode pselmode = SPPaintSelector::getModeForStyle(*query, kind == FILL);
201
270
            psel->setMode(pselmode);
202
271
 
203
 
            if (query->stroke.set && query->stroke.isPaintserver()) {
204
 
 
205
 
                SPPaintServer *server = SP_STYLE_STROKE_SERVER (query);
206
 
 
207
 
                if (server && server->isSwatch()) {
 
272
            if (kind == FILL) {
 
273
                psel->setFillrule(query->fill_rule.computed == ART_WIND_RULE_NONZERO?
 
274
                                  SPPaintSelector::FILLRULE_NONZERO : SPPaintSelector::FILLRULE_EVENODD);
 
275
            }
 
276
 
 
277
            if (targPaint.set && targPaint.isColor()) {
 
278
                psel->setColorAlpha(targPaint.value.color, SP_SCALE24_TO_FLOAT(targOpacity.value));
 
279
            } else if (targPaint.set && targPaint.isPaintserver()) {
 
280
 
 
281
                SPPaintServer *server = (kind == FILL) ? query->getFillPaintServer() : query->getStrokePaintServer();
 
282
 
 
283
                if (server && SP_IS_GRADIENT(server) && SP_GRADIENT(server)->getVector()->isSwatch()) {
208
284
                    SPGradient *vector = SP_GRADIENT(server)->getVector();
209
285
                    psel->setSwatch( vector );
210
 
                } else if (SP_IS_LINEARGRADIENT (server)) {
 
286
                } else if (SP_IS_LINEARGRADIENT(server)) {
211
287
                    SPGradient *vector = SP_GRADIENT(server)->getVector();
212
288
                    psel->setGradientLinear( vector );
213
289
 
214
 
                    SPLinearGradient *lg = SP_LINEARGRADIENT (server);
 
290
                    SPLinearGradient *lg = SP_LINEARGRADIENT(server);
215
291
                    psel->setGradientProperties( SP_GRADIENT_UNITS(lg),
216
292
                                                 SP_GRADIENT_SPREAD(lg) );
217
 
                } else if (SP_IS_RADIALGRADIENT (server)) {
 
293
                } else if (SP_IS_RADIALGRADIENT(server)) {
218
294
                    SPGradient *vector = SP_GRADIENT(server)->getVector();
219
295
                    psel->setGradientRadial( vector );
220
296
 
221
 
                    SPRadialGradient *rg = SP_RADIALGRADIENT (server);
 
297
                    SPRadialGradient *rg = SP_RADIALGRADIENT(server);
222
298
                    psel->setGradientProperties( SP_GRADIENT_UNITS(rg),
223
299
                                                 SP_GRADIENT_SPREAD(rg) );
224
 
                } else if (SP_IS_PATTERN (server)) {
225
 
                    SPPattern *pat = pattern_getroot (SP_PATTERN (server));
 
300
                } else if (SP_IS_PATTERN(server)) {
 
301
                    SPPattern *pat = pattern_getroot(SP_PATTERN(server));
226
302
                    psel->updatePatternList( pat );
227
303
                }
228
 
            } else if (query->stroke.set && query->stroke.isColor()) {
229
 
                psel->setColorAlpha(query->stroke.value.color, SP_SCALE24_TO_FLOAT(query->stroke_opacity.value));
230
304
            }
231
305
            break;
232
306
        }
240
314
 
241
315
    sp_style_unref(query);
242
316
 
243
 
    gtk_object_set_data(GTK_OBJECT(spw), "update", GINT_TO_POINTER(FALSE));
 
317
    g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE));
244
318
}
245
319
 
246
320
/**
247
321
 * When the mode is changed, invoke a regular changed handler.
248
322
 */
249
 
static void
250
 
sp_stroke_style_paint_mode_changed( SPPaintSelector *psel,
 
323
static void fillnstroke_paint_mode_changed( SPPaintSelector *psel,
251
324
                                    SPPaintSelector::Mode /*mode*/,
252
325
                                    SPWidget *spw )
253
326
{
254
 
    if (gtk_object_get_data(GTK_OBJECT(spw), "update")) {
 
327
    if (g_object_get_data(G_OBJECT(spw), "update")) {
255
328
        return;
256
329
    }
257
330
 
 
331
#ifdef SP_FS_VERBOSE
 
332
    g_message("fillnstroke_paint_mode_changed(psel:%p, mode, spw:%p)", psel, spw);
 
333
#endif
 
334
 
258
335
    /* TODO: Does this work?
259
336
     * Not really, here we have to get old color back from object
260
337
     * Instead of relying on paint widget having meaningful colors set
261
338
     */
262
 
    sp_stroke_style_paint_changed(psel, spw);
263
 
}
264
 
 
265
 
static gchar const *const undo_label_1 = "stroke:flatcolor:1";
266
 
static gchar const *const undo_label_2 = "stroke:flatcolor:2";
267
 
static gchar const *undo_label = undo_label_1;
 
339
    fillnstroke_paint_changed(psel, spw);
 
340
}
 
341
 
 
342
static void fillnstroke_fillrule_changed( SPPaintSelector * /*psel*/,
 
343
                                  SPPaintSelector::FillRule mode,
 
344
                                  SPWidget *spw )
 
345
{
 
346
    if (g_object_get_data(G_OBJECT(spw), "update")) {
 
347
        return;
 
348
    }
 
349
 
 
350
    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
 
351
 
 
352
    SPCSSAttr *css = sp_repr_css_attr_new();
 
353
    sp_repr_css_set_property(css, "fill-rule", mode == SPPaintSelector::FILLRULE_EVENODD? "evenodd":"nonzero");
 
354
 
 
355
    sp_desktop_set_style(desktop, css);
 
356
 
 
357
    sp_repr_css_attr_unref(css);
 
358
    css = 0;
 
359
 
 
360
    sp_document_done(SP_ACTIVE_DOCUMENT, SP_VERB_DIALOG_FILL_STROKE,
 
361
                     _("Change fill rule"));
 
362
}
 
363
 
 
364
static gchar const *undo_F_label_1 = "fill:flatcolor:1";
 
365
static gchar const *undo_F_label_2 = "fill:flatcolor:2";
 
366
 
 
367
static gchar const *undo_S_label_1 = "stroke:flatcolor:1";
 
368
static gchar const *undo_S_label_2 = "stroke:flatcolor:2";
 
369
 
 
370
static gchar const *undo_F_label = undo_F_label_1;
 
371
static gchar const *undo_S_label = undo_S_label_1;
268
372
 
269
373
/**
270
 
 * When a drag callback occurs on a paint selector object, if it is a RGB or CMYK
271
 
 * color mode, then set the stroke opacity to psel's flat color.
 
374
 * This is called repeatedly while you are dragging a color slider, only for flat color
 
375
 * modes. Previously it set the color in style but did not update the repr for efficiency, however
 
376
 * this was flakey and didn't buy us almost anything. So now it does the same as _changed, except
 
377
 * lumps all its changes for undo.
272
378
 */
273
 
static void
274
 
sp_stroke_style_paint_dragged(SPPaintSelector *psel, SPWidget *spw)
 
379
static void fillnstroke_paint_dragged(SPPaintSelector *psel, SPWidget *spw)
275
380
{
276
 
    if (gtk_object_get_data(GTK_OBJECT(spw), "update")) {
277
 
        return;
278
 
    }
 
381
    if (!spw->inkscape) {
 
382
        return;
 
383
    }
 
384
 
 
385
    if (g_object_get_data(G_OBJECT(spw), "update")) {
 
386
        return;
 
387
    }
 
388
 
 
389
    FillOrStroke kind = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(spw), "kind")) ? FILL : STROKE;
 
390
 
 
391
    if (kind == FILL) {
 
392
        if (g_object_get_data(G_OBJECT(spw), "local")) {
 
393
            // previous local flag not cleared yet;
 
394
            // this means dragged events come too fast, so we better skip this one to speed up display
 
395
            // (it's safe to do this in any case)
 
396
            return;
 
397
        }
 
398
    }
 
399
 
 
400
    g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(TRUE));
279
401
 
280
402
    switch (psel->mode) {
281
403
        case SPPaintSelector::MODE_COLOR_RGB:
282
404
        case SPPaintSelector::MODE_COLOR_CMYK:
283
405
        {
284
 
            psel->setFlatColor( SP_ACTIVE_DESKTOP, "stroke", "stroke-opacity" );
285
 
            sp_document_maybe_done (sp_desktop_document(SP_ACTIVE_DESKTOP), undo_label, SP_VERB_DIALOG_FILL_STROKE,
286
 
                                    _("Set stroke color"));
 
406
            psel->setFlatColor( SP_ACTIVE_DESKTOP, (kind == FILL) ? "fill" : "stroke", (kind == FILL) ? "fill-opacity" : "stroke-opacity" );
 
407
            sp_document_maybe_done(sp_desktop_document(SP_ACTIVE_DESKTOP), (kind == FILL) ? undo_F_label : undo_S_label, SP_VERB_DIALOG_FILL_STROKE,
 
408
                                   (kind == FILL) ? _("Set fill color") : _("Set stroke color"));
 
409
            if (kind == FILL) {
 
410
                g_object_set_data(G_OBJECT(spw), "local", GINT_TO_POINTER(TRUE)); // local change, do not update from selection
 
411
            }
287
412
            break;
288
413
        }
289
414
 
290
415
        default:
291
416
            g_warning( "file %s: line %d: Paint %d should not emit 'dragged'",
292
 
                       __FILE__, __LINE__, psel->mode);
 
417
                       __FILE__, __LINE__, psel->mode );
293
418
            break;
294
419
    }
 
420
    g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE));
295
421
}
296
422
 
297
423
/**
298
 
 * When the stroke style's paint settings change, this handler updates the
299
 
 * repr's stroke css style and applies the style to relevant drawing items.
 
424
This is called (at least) when:
 
425
1  paint selector mode is switched (e.g. flat color -> gradient)
 
426
2  you finished dragging a gradient node and released mouse
 
427
3  you changed a gradient selector parameter (e.g. spread)
 
428
Must update repr.
300
429
 */
301
 
static void
302
 
sp_stroke_style_paint_changed(SPPaintSelector *psel, SPWidget *spw)
 
430
static void fillnstroke_paint_changed( SPPaintSelector *psel, SPWidget *spw )
303
431
{
304
 
    if (gtk_object_get_data(GTK_OBJECT(spw), "update")) {
 
432
#ifdef SP_FS_VERBOSE
 
433
    g_message("fillnstroke_paint_changed(psel:%p, spw:%p)", psel, spw);
 
434
#endif
 
435
    if (g_object_get_data(G_OBJECT(spw), "update")) {
305
436
        return;
306
437
    }
307
 
    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE));
 
438
    g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(TRUE));
 
439
 
 
440
    FillOrStroke kind = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(spw), "kind")) ? FILL : STROKE;
308
441
 
309
442
    SPDesktop *desktop = SP_ACTIVE_DESKTOP;
310
 
    SPDocument *document = sp_desktop_document (desktop);
311
 
    Inkscape::Selection *selection = sp_desktop_selection (desktop);
 
443
    if (!desktop) {
 
444
        return;
 
445
    }
 
446
    SPDocument *document = sp_desktop_document(desktop);
 
447
    Inkscape::Selection *selection = sp_desktop_selection(desktop);
312
448
 
313
449
    GSList const *items = selection->itemList();
314
450
 
315
451
    switch (psel->mode) {
316
452
        case SPPaintSelector::MODE_EMPTY:
317
453
            // This should not happen.
318
 
            g_warning ( "file %s: line %d: Paint %d should not emit 'changed'",
319
 
                        __FILE__, __LINE__, psel->mode);
 
454
            g_warning( "file %s: line %d: Paint %d should not emit 'changed'",
 
455
                       __FILE__, __LINE__, psel->mode);
320
456
            break;
321
457
        case SPPaintSelector::MODE_MULTIPLE:
322
458
            // This happens when you switch multiple objects with different gradients to flat color;
326
462
        case SPPaintSelector::MODE_NONE:
327
463
        {
328
464
            SPCSSAttr *css = sp_repr_css_attr_new();
329
 
            sp_repr_css_set_property(css, "stroke", "none");
 
465
            sp_repr_css_set_property(css, (kind == FILL) ? "fill" : "stroke", "none");
330
466
 
331
 
            sp_desktop_set_style (desktop, css);
 
467
            sp_desktop_set_style(desktop, css);
332
468
 
333
469
            sp_repr_css_attr_unref(css);
 
470
            css = 0;
334
471
 
335
472
            sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
336
 
                             _("Remove stroke"));
 
473
                             (kind == FILL) ? _("Remove fill") : _("Remove stroke"));
337
474
            break;
338
475
        }
339
476
 
340
477
        case SPPaintSelector::MODE_COLOR_RGB:
341
478
        case SPPaintSelector::MODE_COLOR_CMYK:
342
479
        {
343
 
            psel->setFlatColor(desktop, "stroke", "stroke-opacity");
344
 
            sp_document_maybe_done (sp_desktop_document(desktop), undo_label, SP_VERB_DIALOG_FILL_STROKE,
345
 
                                    _("Set stroke color"));
 
480
            if (kind == FILL) {
 
481
                // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in losing release events
 
482
                sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(desktop), 0);
 
483
            }
 
484
 
 
485
            psel->setFlatColor( desktop,
 
486
                                (kind == FILL) ? "fill" : "stroke",
 
487
                                (kind == FILL) ? "fill-opacity" : "stroke-opacity" );
 
488
            sp_document_maybe_done(sp_desktop_document(desktop), (kind == FILL) ? undo_F_label : undo_S_label, SP_VERB_DIALOG_FILL_STROKE,
 
489
                                   (kind == FILL) ? _("Set fill color") : _("Set stroke color"));
 
490
 
 
491
            if (kind == FILL) {
 
492
                // resume interruptibility
 
493
                sp_canvas_end_forced_full_redraws(sp_desktop_canvas(desktop));
 
494
            }
346
495
 
347
496
            // on release, toggle undo_label so that the next drag will not be lumped with this one
348
 
            if (undo_label == undo_label_1)
349
 
                undo_label = undo_label_2;
350
 
            else
351
 
                undo_label = undo_label_1;
 
497
            if (undo_F_label == undo_F_label_1) {
 
498
                undo_F_label = undo_F_label_2;
 
499
                undo_S_label = undo_S_label_2;
 
500
            } else {
 
501
                undo_F_label = undo_F_label_1;
 
502
                undo_S_label = undo_S_label_1;
 
503
            }
352
504
 
353
505
            break;
354
506
        }
355
507
 
356
508
        case SPPaintSelector::MODE_GRADIENT_LINEAR:
357
509
        case SPPaintSelector::MODE_GRADIENT_RADIAL:
 
510
        case SPPaintSelector::MODE_SWATCH:
358
511
            if (items) {
359
 
                SPGradientType const gradient_type = ( psel->mode == SPPaintSelector::MODE_GRADIENT_LINEAR
 
512
                SPGradientType const gradient_type = ( psel->mode != SPPaintSelector::MODE_GRADIENT_RADIAL
360
513
                                                       ? SP_GRADIENT_TYPE_LINEAR
361
514
                                                       : SP_GRADIENT_TYPE_RADIAL );
 
515
 
 
516
                SPCSSAttr *css = 0;
 
517
                if (kind == FILL) {
 
518
                    // HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs
 
519
                    css = sp_repr_css_attr_new();
 
520
                    sp_repr_css_set_property(css, "fill-opacity", "1.0");
 
521
                }
 
522
 
362
523
                SPGradient *vector = psel->getGradientVector();
363
524
                if (!vector) {
364
525
                    /* No vector in paint selector should mean that we just changed mode */
365
526
 
366
 
                    SPStyle *query = sp_style_new (SP_ACTIVE_DOCUMENT);
367
 
                    int result = objects_query_fillstroke ((GSList *) items, query, false);
 
527
                    SPStyle *query = sp_style_new(SP_ACTIVE_DOCUMENT);
 
528
                    int result = objects_query_fillstroke(const_cast<GSList *>(items), query, kind == FILL);
 
529
                    SPIPaint &targPaint = (kind == FILL) ? query->fill : query->stroke;
368
530
                    guint32 common_rgb = 0;
369
531
                    if (result == QUERY_STYLE_MULTIPLE_SAME) {
370
 
                        if (!query->fill.isColor()) {
371
 
                            common_rgb = sp_desktop_get_color(desktop, false);
 
532
                        if (!targPaint.isColor()) {
 
533
                            common_rgb = sp_desktop_get_color(desktop, kind == FILL);
372
534
                        } else {
373
 
                            common_rgb = query->stroke.value.color.toRGBA32( 0xff );
 
535
                            common_rgb = targPaint.value.color.toRGBA32( 0xff );
374
536
                        }
375
537
                        vector = sp_document_default_gradient_vector(document, common_rgb);
376
538
                    }
377
539
                    sp_style_unref(query);
378
540
 
379
541
                    for (GSList const *i = items; i != NULL; i = i->next) {
 
542
                        //FIXME: see above
 
543
                        if (kind == FILL) {
 
544
                            sp_repr_css_change_recursive(SP_OBJECT_REPR(i->data), css, "style");
 
545
                        }
 
546
 
380
547
                        if (!vector) {
381
548
                            sp_item_set_gradient(SP_ITEM(i->data),
382
 
                                                 sp_gradient_vector_for_object(document, desktop, SP_OBJECT(i->data), false),
383
 
                                                 gradient_type, false);
 
549
                                                 sp_gradient_vector_for_object(document, desktop, SP_OBJECT(i->data), kind == FILL),
 
550
                                                 gradient_type, kind == FILL);
384
551
                        } else {
385
 
                            sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, false);
 
552
                            sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, kind == FILL);
386
553
                        }
387
554
                    }
388
555
                } else {
 
556
                    // We have changed from another gradient type, or modified spread/units within
 
557
                    // this gradient type.
389
558
                    vector = sp_gradient_ensure_vector_normalized(vector);
390
559
                    for (GSList const *i = items; i != NULL; i = i->next) {
391
 
                        SPGradient *gr = sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, false);
 
560
                        //FIXME: see above
 
561
                        if (kind == FILL) {
 
562
                            sp_repr_css_change_recursive(SP_OBJECT_REPR(i->data), css, "style");
 
563
                        }
 
564
 
 
565
                        SPGradient *gr = sp_item_set_gradient(SP_ITEM(i->data), vector, gradient_type, kind == FILL);
392
566
                        psel->pushAttrsToGradient( gr );
393
567
                    }
394
568
                }
395
569
 
 
570
                if (css) {
 
571
                    sp_repr_css_attr_unref(css);
 
572
                    css = 0;
 
573
                }
 
574
 
396
575
                sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
397
 
                                 _("Set gradient on stroke"));
 
576
                                 (kind == FILL) ? _("Set gradient on fill") : _("Set gradient on stroke"));
398
577
            }
399
578
            break;
400
579
 
411
590
 
412
591
                } else {
413
592
                    Inkscape::XML::Node *patrepr = SP_OBJECT_REPR(pattern);
414
 
                    SPCSSAttr *css = sp_repr_css_attr_new ();
415
 
                    gchar *urltext = g_strdup_printf ("url(#%s)", patrepr->attribute("id"));
416
 
                    sp_repr_css_set_property (css, "stroke", urltext);
417
 
 
 
593
                    SPCSSAttr *css = sp_repr_css_attr_new();
 
594
                    gchar *urltext = g_strdup_printf("url(#%s)", patrepr->attribute("id"));
 
595
                    sp_repr_css_set_property(css, (kind == FILL) ? "fill" : "stroke", urltext);
 
596
 
 
597
                    // HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs
 
598
                    if (kind == FILL) {
 
599
                        sp_repr_css_set_property(css, "fill-opacity", "1.0");
 
600
                    }
 
601
 
 
602
                    // cannot just call sp_desktop_set_style, because we don't want to touch those
 
603
                    // objects who already have the same root pattern but through a different href
 
604
                    // chain. FIXME: move this to a sp_item_set_pattern
418
605
                    for (GSList const *i = items; i != NULL; i = i->next) {
419
 
                         Inkscape::XML::Node *selrepr = SP_OBJECT_REPR (i->data);
420
 
                         SPObject *selobj = SP_OBJECT (i->data);
421
 
                         if (!selrepr)
422
 
                             continue;
423
 
 
424
 
                         SPStyle *style = SP_OBJECT_STYLE (selobj);
425
 
                         if (style && style->stroke.isPaintserver()) {
426
 
                             SPObject *server = SP_OBJECT_STYLE_STROKE_SERVER (selobj);
427
 
                             if (SP_IS_PATTERN (server) && pattern_getroot (SP_PATTERN(server)) == pattern)
428
 
                                 // only if this object's pattern is not rooted in our selected pattern, apply
429
 
                                 continue;
430
 
                         }
431
 
 
432
 
                         sp_repr_css_change_recursive (selrepr, css, "style");
433
 
                     }
434
 
 
435
 
                    sp_repr_css_attr_unref (css);
436
 
                    g_free (urltext);
 
606
                        Inkscape::XML::Node *selrepr = SP_OBJECT_REPR(i->data);
 
607
                        if ( (kind == STROKE) && !selrepr) {
 
608
                            continue;
 
609
                        }
 
610
                        SPObject *selobj = SP_OBJECT(i->data);
 
611
 
 
612
                        SPStyle *style = SP_OBJECT_STYLE(selobj);
 
613
                        if (style && ((kind == FILL) ? style->fill : style->stroke).isPaintserver()) {
 
614
                            SPObject *server = (kind == FILL) ?
 
615
                                SP_OBJECT_STYLE_FILL_SERVER(selobj) :
 
616
                                SP_OBJECT_STYLE_STROKE_SERVER(selobj);
 
617
                            if (SP_IS_PATTERN(server) && pattern_getroot(SP_PATTERN(server)) == pattern)
 
618
                                // only if this object's pattern is not rooted in our selected pattern, apply
 
619
                                continue;
 
620
                        }
 
621
 
 
622
                        if (kind == FILL) {
 
623
                            sp_desktop_apply_css_recursive(selobj, css, true);
 
624
                        } else {
 
625
                            sp_repr_css_change_recursive(selrepr, css, "style");
 
626
                        }
 
627
                    }
 
628
 
 
629
                    sp_repr_css_attr_unref(css);
 
630
                    css = 0;
 
631
                    g_free(urltext);
437
632
 
438
633
                } // end if
439
634
 
440
 
                sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE,
441
 
                                  _("Set pattern on stroke"));
 
635
                sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
 
636
                                 (kind == FILL) ? _("Set pattern on fill") :
 
637
                                 _("Set pattern on stroke"));
442
638
            } // end if
443
639
 
444
640
            break;
445
641
 
446
 
        case SPPaintSelector::MODE_SWATCH:
447
 
            // TODO
448
 
            break;
449
 
 
450
642
        case SPPaintSelector::MODE_UNSET:
451
643
            if (items) {
452
 
                    SPCSSAttr *css = sp_repr_css_attr_new ();
453
 
                    sp_repr_css_unset_property (css, "stroke");
454
 
                    sp_repr_css_unset_property (css, "stroke-opacity");
455
 
                    sp_repr_css_unset_property (css, "stroke-width");
456
 
                    sp_repr_css_unset_property (css, "stroke-miterlimit");
457
 
                    sp_repr_css_unset_property (css, "stroke-linejoin");
458
 
                    sp_repr_css_unset_property (css, "stroke-linecap");
459
 
                    sp_repr_css_unset_property (css, "stroke-dashoffset");
460
 
                    sp_repr_css_unset_property (css, "stroke-dasharray");
461
 
 
462
 
                    sp_desktop_set_style (desktop, css);
463
 
                    sp_repr_css_attr_unref (css);
464
 
 
465
 
                    sp_document_done (document, SP_VERB_DIALOG_FILL_STROKE,
466
 
                                      _("Unset stroke"));
 
644
                SPCSSAttr *css = sp_repr_css_attr_new();
 
645
                if (kind == FILL) {
 
646
                    sp_repr_css_unset_property(css, "fill");
 
647
                } else {
 
648
                    sp_repr_css_unset_property(css, "stroke");
 
649
                    sp_repr_css_unset_property(css, "stroke-opacity");
 
650
                    sp_repr_css_unset_property(css, "stroke-width");
 
651
                    sp_repr_css_unset_property(css, "stroke-miterlimit");
 
652
                    sp_repr_css_unset_property(css, "stroke-linejoin");
 
653
                    sp_repr_css_unset_property(css, "stroke-linecap");
 
654
                    sp_repr_css_unset_property(css, "stroke-dashoffset");
 
655
                    sp_repr_css_unset_property(css, "stroke-dasharray");
 
656
                }
 
657
 
 
658
                sp_desktop_set_style(desktop, css);
 
659
                sp_repr_css_attr_unref(css);
 
660
                css = 0;
 
661
 
 
662
                sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
 
663
                                 (kind == FILL) ? _("Unset fill") : _("Unset stroke"));
467
664
            }
468
665
            break;
469
666
 
475
672
            break;
476
673
    }
477
674
 
478
 
    g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE));
479
 
}
480
 
 
 
675
    g_object_set_data(G_OBJECT(spw), "update", GINT_TO_POINTER(FALSE));
 
676
}
 
677
 
 
678
 
 
679
static void fillnstroke_transientize_called(Inkscape::Application * /*inkscape*/,
 
680
                                    SPDesktop * /*desktop*/,
 
681
                                    SPWidget * /*spw*/ )
 
682
{
 
683
// TODO:  Either of these will cause crashes sometimes
 
684
//    sp_stroke_style_line_update( SP_WIDGET(spw), desktop ? sp_desktop_selection(desktop) : NULL);
 
685
//    ink_markers_menu_update(spw);
 
686
}
481
687
 
482
688
 
483
689
 
537
743
 
538
744
}
539
745
 
540
 
static void
541
 
sp_stroke_style_widget_transientize_callback(Inkscape::Application */*inkscape*/,
542
 
                                             SPDesktop */*desktop*/,
543
 
                                             SPWidget */*spw*/ )
544
 
{
545
 
// TODO:  Either of these will cause crashes sometimes
546
 
//    sp_stroke_style_line_update( SP_WIDGET(spw), desktop ? sp_desktop_selection(desktop) : NULL);
547
 
//    ink_markers_menu_update(spw);
548
 
}
549
 
 
550
746
/**
551
 
 * Creates a copy of the marker named mname, determines its visible and renderable
 
747
 * Create sa copy of the marker named mname, determines its visible and renderable
552
748
 * area in menu_id's bounding box, and then renders it.  This allows us to fill in
553
749
 * preview images of each marker in the marker menu.
554
750
 */
555
751
static Gtk::Image *
556
752
sp_marker_prev_new(unsigned psize, gchar const *mname,
557
753
                   SPDocument *source, SPDocument *sandbox,
558
 
                   gchar const *menu_id, NRArena const */*arena*/, unsigned /*visionkey*/, NRArenaItem *root)
 
754
                   gchar const *menu_id, NRArena const * /*arena*/, unsigned /*visionkey*/, NRArenaItem *root)
559
755
{
560
756
    // Retrieve the marker named 'mname' from the source SVG document
561
757
    SPObject const *marker = source->getObjectById(mname);
699
895
 *
700
896
 */
701
897
static void
702
 
sp_marker_list_from_doc (Gtk::Menu *m, SPDocument */*current_doc*/, SPDocument *source, SPDocument */*markers_doc*/, SPDocument *sandbox, gchar const *menu_id)
 
898
sp_marker_list_from_doc (Gtk::Menu *m, SPDocument * /*current_doc*/, SPDocument *source, SPDocument * /*markers_doc*/, SPDocument *sandbox, gchar const *menu_id)
703
899
{
704
900
    GSList *ml = ink_marker_list_get(source);
705
901
    GSList *clean_ml = NULL;
808
1004
 * Creates a menu widget to display markers from markers.svg
809
1005
 */
810
1006
static Gtk::OptionMenu *
811
 
ink_marker_menu(Gtk::Widget */*tbl*/, gchar const *menu_id, SPDocument *sandbox)
 
1007
ink_marker_menu(Gtk::Widget * /*tbl*/, gchar const *menu_id, SPDocument *sandbox)
812
1008
{
813
1009
    SPDesktop *desktop = inkscape_active_desktop();
814
1010
    SPDocument *doc = sp_desktop_document(desktop);
903
1099
     }
904
1100
 
905
1101
    sp_repr_css_attr_unref(css);
 
1102
    css = 0;
906
1103
 
907
1104
    sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
908
1105
                     _("Set markers"));
1269
1466
 
1270
1467
    // FIXME: we cheat and still use gtk+ signals
1271
1468
 
1272
 
    gtk_signal_connect(GTK_OBJECT(spw_old), "modify_selection",
1273
 
                       GTK_SIGNAL_FUNC(sp_stroke_style_line_selection_modified),
1274
 
                       spw);
1275
 
    gtk_signal_connect(GTK_OBJECT(spw_old), "change_selection",
1276
 
                       GTK_SIGNAL_FUNC(sp_stroke_style_line_selection_changed),
1277
 
                       spw);
 
1469
    g_signal_connect(G_OBJECT(spw_old), "modify_selection",
 
1470
                     G_CALLBACK(sp_stroke_style_line_selection_modified),
 
1471
                     spw);
 
1472
    g_signal_connect(G_OBJECT(spw_old), "change_selection",
 
1473
                     G_CALLBACK(sp_stroke_style_line_selection_changed),
 
1474
                     spw);
1278
1475
 
1279
1476
    sp_stroke_style_line_update(spw, desktop ? sp_desktop_selection(desktop) : NULL);
1280
1477
 
1393
1590
 
1394
1591
    spw->set_data("update", GINT_TO_POINTER(TRUE));
1395
1592
 
 
1593
    FillOrStroke kind = GPOINTER_TO_INT(spw->get_data("kind")) ? FILL : STROKE;
 
1594
 
1396
1595
    Gtk::Table *sset = static_cast<Gtk::Table *>(spw->get_data("stroke"));
1397
1596
    Gtk::Adjustment *width = static_cast<Gtk::Adjustment *>(spw->get_data("width"));
1398
1597
    Gtk::Adjustment *ml = static_cast<Gtk::Adjustment *>(spw->get_data("miterlimit"));
1406
1605
    int result_ml = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEMITERLIMIT);
1407
1606
    int result_cap = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKECAP);
1408
1607
    int result_join = sp_desktop_query_style (SP_ACTIVE_DESKTOP, query, QUERY_STYLE_PROPERTY_STROKEJOIN);
 
1608
    SPIPaint &targPaint = (kind == FILL) ? query->fill : query->stroke;
1409
1609
 
1410
1610
    if (!sel || sel->isEmpty()) {
1411
1611
        // Nothing selected, grey-out all controls in the stroke-style dialog
1412
 
        sset->set_sensitive(false);
 
1612
        sset->set_sensitive(false);
1413
1613
 
1414
1614
        spw->set_data("update", GINT_TO_POINTER(FALSE));
1415
1615
 
1439
1639
 
1440
1640
        // if none of the selected objects has a stroke, than quite some controls should be disabled
1441
1641
        // The markers might still be shown though, so these will not be disabled
1442
 
        bool enabled = (result_sw != QUERY_STYLE_NOTHING) && !query->stroke.isNoneSet();
 
1642
        bool enabled = (result_sw != QUERY_STYLE_NOTHING) && !targPaint.isNoneSet();
1443
1643
        /* No objects stroked, set insensitive */
1444
1644
        Gtk::RadioButton *tb = NULL;
1445
1645
        tb = static_cast<Gtk::RadioButton *>(spw->get_data("miter join"));
1454
1654
        sb->set_sensitive(enabled);
1455
1655
 
1456
1656
        tb = static_cast<Gtk::RadioButton *>(spw->get_data("cap butt"));
1457
 
                tb->set_sensitive(enabled);
1458
 
                tb = static_cast<Gtk::RadioButton *>(spw->get_data("cap round"));
1459
 
                tb->set_sensitive(enabled);
1460
 
                tb = static_cast<Gtk::RadioButton *>(spw->get_data("cap square"));
1461
 
                tb->set_sensitive(enabled);
 
1657
        tb->set_sensitive(enabled);
 
1658
        tb = static_cast<Gtk::RadioButton *>(spw->get_data("cap round"));
 
1659
        tb->set_sensitive(enabled);
 
1660
        tb = static_cast<Gtk::RadioButton *>(spw->get_data("cap square"));
 
1661
        tb->set_sensitive(enabled);
1462
1662
 
1463
1663
        dsel->set_sensitive(enabled);
1464
1664
    }
1604
1804
    sp_desktop_set_style (desktop, css, false);
1605
1805
 
1606
1806
    sp_repr_css_attr_unref(css);
 
1807
    css = 0;
1607
1808
 
1608
1809
    sp_document_done(document, SP_VERB_DIALOG_FILL_STROKE,
1609
1810
                     _("Set stroke style"));
1700
1901
        }
1701
1902
 
1702
1903
        sp_repr_css_attr_unref(css);
 
1904
        css = 0;
1703
1905
 
1704
1906
        sp_document_done(sp_desktop_document(desktop), SP_VERB_DIALOG_FILL_STROKE,
1705
1907
                         _("Set stroke style"));