static void sp_fill_style_widget_fill_rule_activate (GtkWidget *w, SPWidget *spw) { const GSList *items, *i, *r; GSList *reprs; SPCSSAttr *css; if (g_object_get_data (G_OBJECT (spw), "update")) return; if (spw->inkscape) { reprs = NULL; items = sp_widget_get_item_list (spw); for (i = items; i != NULL; i = i->next) { reprs = g_slist_prepend (reprs, SP_OBJECT_REPR (i->data)); } } else { reprs = g_slist_prepend (NULL, spw->repr); items = NULL; } css = sp_repr_css_attr_new (); sp_repr_css_set_property (css, "fill-rule", (const gchar *)g_object_get_data (G_OBJECT (w), "fill-rule")); for (r = reprs; r != NULL; r = r->next) { sp_repr_css_change_recursive ((SPRepr *) r->data, css, "style"); } sp_repr_css_attr_unref (css); if (spw->inkscape) sp_document_done (SP_WIDGET_DOCUMENT (spw)); g_slist_free (reprs); }
void ObjectCompositeSettings::_opacityValueChanged() { if (!_subject) { return; } SPDesktop *desktop = _subject->getDesktop(); if (!desktop) { return; } if (_blocked) return; _blocked = true; // FIXME: fix for GTK breakage, see comment in SelectedStyle::on_opacity_changed; here it results in crash 1580903 // UPDATE: crash fixed in GTK+ 2.10.7 (bug 374378), remove this as soon as it's reasonably common // (though this only fixes the crash, not the multiple change events) //sp_canvas_force_full_redraw_after_interruptions(sp_desktop_canvas(desktop), 0); SPCSSAttr *css = sp_repr_css_attr_new (); Inkscape::CSSOStringStream os; os << CLAMP (_opacity_scale.get_adjustment()->get_value() / 100, 0.0, 1.0); sp_repr_css_set_property (css, "opacity", os.str().c_str()); _subject->setCSS(css); sp_repr_css_attr_unref (css); DocumentUndo::maybeDone(sp_desktop_document (desktop), _opacity_tag.c_str(), _verb_code, _("Change opacity")); // resume interruptibility //sp_canvas_end_forced_full_redraws(sp_desktop_canvas(desktop)); _blocked = false; }
SPDocument * GdkpixbufInput::open(Inkscape::Extension::Input *mod, char const *uri) { // Determine whether the image should be embedded Inkscape::Preferences *prefs = Inkscape::Preferences::get(); bool ask = prefs->getBool("/dialogs/import/ask"); Glib::ustring link = prefs->getString("/dialogs/import/link"); bool forcexdpi = prefs->getBool("/dialogs/import/forcexdpi"); Glib::ustring scale = prefs->getString("/dialogs/import/scale"); // std::cout << "GkdpixbufInput::open: " // << " ask: " << ask // << ", link: " << link // << ", forcexdpi: " << forcexdpi // << ", scale: " << scale << std::endl; // std::cout << " in preferences: " // << " ask: " << !mod->get_param_bool("do_not_ask") // << ", link: " << mod->get_param_optiongroup("link") // << ", mod_dpi: " << mod->get_param_optiongroup("dpi") // << ", scale: " << mod->get_param_optiongroup("scale") << std::endl; if( ask ) { Glib::ustring mod_link = mod->get_param_optiongroup("link"); Glib::ustring mod_dpi = mod->get_param_optiongroup("dpi"); bool mod_forcexdpi = ( mod_dpi.compare( "from_default" ) == 0 ); Glib::ustring mod_scale = mod->get_param_optiongroup("scale"); if( link.compare( mod_link ) != 0 ) { link = mod_link; } prefs->setString("/dialogs/import/link", link ); if( forcexdpi != mod_forcexdpi ) { forcexdpi = mod_forcexdpi; } prefs->setBool("/dialogs/import/forcexdpi", forcexdpi ); if( scale.compare( mod_scale ) != 0 ) { scale = mod_scale; } prefs->setString("/dialogs/import/scale", scale ); prefs->setBool("/dialogs/import/ask", !mod->get_param_bool("do_not_ask") ); } bool embed = ( link.compare( "embed" ) == 0 ); SPDocument *doc = NULL; boost::scoped_ptr<Inkscape::Pixbuf> pb(Inkscape::Pixbuf::create_from_file(uri)); // TODO: the pixbuf is created again from the base64-encoded attribute in SPImage. // Find a way to create the pixbuf only once. if (pb) { doc = SPDocument::createNewDoc(NULL, TRUE, TRUE); bool saved = DocumentUndo::getUndoSensitive(doc); DocumentUndo::setUndoSensitive(doc, false); // no need to undo in this temporary document double width = pb->width(); double height = pb->height(); double defaultxdpi = prefs->getDouble("/dialogs/import/defaultxdpi/value", Inkscape::Util::Quantity::convert(1, "in", "px")); //bool forcexdpi = prefs->getBool("/dialogs/import/forcexdpi"); ImageResolution *ir = 0; double xscale = 1; double yscale = 1; if (!ir && !forcexdpi) { ir = new ImageResolution(uri); } if (ir && ir->ok()) { xscale = 900.0 / floor(10.*ir->x() + .5); // round-off to 0.1 dpi yscale = 900.0 / floor(10.*ir->y() + .5); } else { xscale = 90.0 / defaultxdpi; yscale = 90.0 / defaultxdpi; } width *= xscale; height *= yscale; delete ir; // deleting NULL is safe // Create image node Inkscape::XML::Document *xml_doc = doc->getReprDoc(); Inkscape::XML::Node *image_node = xml_doc->createElement("svg:image"); sp_repr_set_svg_double(image_node, "width", width); sp_repr_set_svg_double(image_node, "height", height); // Added 11 Feb 2014 as we now honor "preserveAspectRatio" and this is // what Inkscaper's expect. image_node->setAttribute("preserveAspectRatio", "none"); if( scale.compare( "auto" ) != 0 ) { SPCSSAttr *css = sp_repr_css_attr_new(); sp_repr_css_set_property(css, "image-rendering", scale.c_str()); sp_repr_css_set(image_node, css, "style"); sp_repr_css_attr_unref( css ); } if (embed) { sp_embed_image(image_node, pb.get()); } else { // convert filename to uri gchar* _uri = g_filename_to_uri(uri, NULL, NULL); if(_uri) { image_node->setAttribute("xlink:href", _uri); g_free(_uri); } else { image_node->setAttribute("xlink:href", uri); } } // Add it to the current layer doc->getRoot()->appendChildRepr(image_node); Inkscape::GC::release(image_node); fit_canvas_to_drawing(doc); // Set viewBox if it doesn't exist if (!doc->getRoot()->viewBox_set) { //std::cout << "Viewbox not set, setting" << std::endl; doc->setViewBox(Geom::Rect::from_xywh(0, 0, doc->getWidth().value(doc->getDefaultUnit()), doc->getHeight().value(doc->getDefaultUnit()))); } // restore undo, as now this document may be shown to the user if a bitmap was opened DocumentUndo::setUndoSensitive(doc, saved); } else { printf("GdkPixbuf loader failed\n"); } return doc; }
static void sp_text_edit_dialog_update_object (SPText *text, SPRepr *repr) { g_object_set_data (G_OBJECT (dlg), "blocked", GINT_TO_POINTER (TRUE)); if (text) { GtkTextBuffer *tb; GtkTextIter start, end; gchar *str; tb = (GtkTextBuffer*)g_object_get_data (G_OBJECT (dlg), "text"); /* Content */ gtk_text_buffer_get_bounds (tb, &start, &end); str = gtk_text_buffer_get_text (tb, &start, &end, TRUE); sp_text_set_repr_text_multiline (text, str); g_free (str); } if (repr) { GtkWidget *fontsel, *preview, *b, *combo; SPCSSAttr *css; NRFont *font; gchar c[256]; const char *sstr; fontsel = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "fontsel"); preview = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "preview"); css = sp_repr_css_attr_new (); /* font */ font = sp_font_selector_get_font (SP_FONT_SELECTOR (fontsel)); nr_typeface_family_name_get (NR_FONT_TYPEFACE (font), c, 256); sp_repr_css_set_property (css, "font-family", c); nr_typeface_attribute_get (NR_FONT_TYPEFACE (font), "weight", c, 256); g_strdown (c); sp_repr_css_set_property (css, "font-weight", c); nr_typeface_attribute_get (NR_FONT_TYPEFACE (font), "style", c, 256); g_strdown (c); sp_repr_css_set_property (css, "font-style", c); g_snprintf (c, 64, "%g", NR_FONT_SIZE (font)); sp_repr_css_set_property (css, "font-size", c); nr_font_unref (font); /* Layout */ b = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "text_anchor_start"); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (b))) { sp_repr_css_set_property (css, "text-anchor", "start"); } else { b = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "text_anchor_middle"); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (b))) { sp_repr_css_set_property (css, "text-anchor", "middle"); } else { sp_repr_css_set_property (css, "text-anchor", "end"); } } b = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "writing_mode_lr"); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (b))) { sp_repr_css_set_property (css, "writing-mode", "lr"); } else { sp_repr_css_set_property (css, "writing-mode", "tb"); } combo = (GtkWidget*)g_object_get_data ((GObject *) dlg, "line_spacing"); sstr = gtk_entry_get_text ((GtkEntry *) ((GtkCombo *) (combo))->entry); sp_repr_set_attr (repr, "sodipodi:linespacing", sstr); sp_repr_css_change (repr, css, "style"); sp_repr_css_attr_unref (css); } if (text) { sp_document_done (SP_DT_DOCUMENT (SP_ACTIVE_DESKTOP)); sp_document_ensure_up_to_date (SP_OBJECT_DOCUMENT (text)); } g_object_set_data (G_OBJECT (dlg), "blocked", NULL); }
static void sp_gradient_drag(SPGradientContext &rc, Geom::Point const pt, guint /*state*/, guint32 etime) { SPDesktop *desktop = SP_EVENT_CONTEXT(&rc)->desktop; Inkscape::Selection *selection = sp_desktop_selection(desktop); SPDocument *document = sp_desktop_document(desktop); SPEventContext *ec = SP_EVENT_CONTEXT(&rc); if (!selection->isEmpty()) { Inkscape::Preferences *prefs = Inkscape::Preferences::get(); int type = prefs->getInt("/tools/gradient/newgradient", 1); int fill_or_stroke = prefs->getInt("/tools/gradient/newfillorstroke", 1); SPGradient *vector; if (ec->item_to_select) { // pick color from the object where drag started vector = sp_gradient_vector_for_object(document, desktop, ec->item_to_select, fill_or_stroke); } else { // Starting from empty space: // Sort items so that the topmost comes last GSList *items = g_slist_copy ((GSList *) selection->itemList()); items = g_slist_sort(items, (GCompareFunc) sp_item_repr_compare_position); // take topmost vector = sp_gradient_vector_for_object(document, desktop, SP_ITEM(g_slist_last(items)->data), fill_or_stroke); g_slist_free (items); } // HACK: reset fill-opacity - that 0.75 is annoying; BUT remove this when we have an opacity slider for all tabs SPCSSAttr *css = sp_repr_css_attr_new(); sp_repr_css_set_property(css, "fill-opacity", "1.0"); for (GSList const *i = selection->itemList(); i != NULL; i = i->next) { //FIXME: see above sp_repr_css_change_recursive(SP_OBJECT_REPR(i->data), css, "style"); sp_item_set_gradient(SP_ITEM(i->data), vector, (SPGradientType) type, fill_or_stroke); if (type == SP_GRADIENT_TYPE_LINEAR) { sp_item_gradient_set_coords (SP_ITEM(i->data), POINT_LG_BEGIN, 0, rc.origin, fill_or_stroke, true, false); sp_item_gradient_set_coords (SP_ITEM(i->data), POINT_LG_END, 0, pt, fill_or_stroke, true, false); } else if (type == SP_GRADIENT_TYPE_RADIAL) { sp_item_gradient_set_coords (SP_ITEM(i->data), POINT_RG_CENTER, 0, rc.origin, fill_or_stroke, true, false); sp_item_gradient_set_coords (SP_ITEM(i->data), POINT_RG_R1, 0, pt, fill_or_stroke, true, false); } SP_OBJECT (i->data)->requestModified(SP_OBJECT_MODIFIED_FLAG); } if (ec->_grdrag) { ec->_grdrag->updateDraggers(); // prevent regenerating draggers by selection modified signal, which sometimes // comes too late and thus destroys the knot which we will now grab: ec->_grdrag->local_change = true; // give the grab out-of-bounds values of xp/yp because we're already dragging // and therefore are already out of tolerance ec->_grdrag->grabKnot (SP_ITEM(selection->itemList()->data), type == SP_GRADIENT_TYPE_LINEAR? POINT_LG_END : POINT_RG_R1, -1, // ignore number (though it is always 1) fill_or_stroke, 99999, 99999, etime); } // We did an undoable action, but sp_document_done will be called by the knot when released // status text; we do not track coords because this branch is run once, not all the time // during drag int n_objects = g_slist_length((GSList *) selection->itemList()); rc._message_context->setF(Inkscape::NORMAL_MESSAGE, ngettext("<b>Gradient</b> for %d object; with <b>Ctrl</b> to snap angle", "<b>Gradient</b> for %d objects; with <b>Ctrl</b> to snap angle", n_objects), n_objects); } else { sp_desktop_message_stack(desktop)->flash(Inkscape::WARNING_MESSAGE, _("Select <b>objects</b> on which to create gradient.")); } }
/** * Given a repr, this sets the data items in the path object such as * fill & style attributes, markers, and CSS properties. */ static void sp_path_build (SPObject *object, SPDocument *document, SPRepr *repr) { SPPath *path; SPVersion version; const gchar* marker_value; path = SP_PATH (object); version = sp_object_get_sodipodi_version (object); /* Fixes old Sodipodi nodetype to namespaced parameter */ if (sp_version_inside_range (version, 0, 0, 0, 25)) { const gchar *str; str = sp_repr_attr (repr, "INKSCAPE-PATH-NODE-TYPES"); sp_repr_set_attr (repr, "sodipodi:nodetypes", str); sp_repr_set_attr (repr, "INKSCAPE-PATH-NODE-TYPES", NULL); } sp_object_read_attr (object, "d"); /* Are these calls actually necessary? */ sp_object_read_attr (object, "marker"); sp_object_read_attr (object, "marker-start"); sp_object_read_attr (object, "marker-mid"); sp_object_read_attr (object, "marker-end"); if (sp_version_inside_range (version, 0, 0, 0, 25)) { SPShape *shape; SPCSSAttr *css; const gchar *val; gboolean changed; gboolean open; shape = (SPShape *) path; /* Remove fill from open paths for compatibility with inkscape < 0.25 */ /* And set fill-rule of closed paths to evenodd */ /* We force style rewrite at moment (Lauris) */ changed = TRUE; open = FALSE; if (shape->curve && shape->curve->bpath) { ArtBpath *bp; for (bp = shape->curve->bpath; bp->code != ART_END; bp++) { if (bp->code == ART_MOVETO_OPEN) { open = TRUE; break; } } } css = sp_repr_css_attr (repr, "style"); if (open) { val = sp_repr_css_property (css, "fill", NULL); if (val && strcmp (val, "none")) { sp_repr_css_set_property (css, "fill", "none"); changed = TRUE; } } else { val = sp_repr_css_property (css, "fill-rule", NULL); if (!val) { sp_repr_css_set_property (css, "fill-rule", "evenodd"); changed = TRUE; } } if (changed) { sp_repr_css_set (repr, css, "style"); } sp_repr_css_attr_unref (css); } if (((SPObjectClass *) parent_class)->build) { ((SPObjectClass *) parent_class)->build (object, document, repr); } }
SPCSSAttr * sp_get_text_dialog_style () { GtkWidget *fontsel = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "fontsel"); SPCSSAttr *css = sp_repr_css_attr_new (); /* font */ font_instance *font = sp_font_selector_get_font (SP_FONT_SELECTOR (fontsel)); if ( font ) { Glib::ustring fontName = font_factory::Default()->ConstructFontSpecification(font); sp_repr_css_set_property (css, "-inkscape-font-specification", fontName.c_str()); gchar c[256]; font->Family(c, 256); sp_repr_css_set_property (css, "font-family", c); font->Attribute( "weight", c, 256); sp_repr_css_set_property (css, "font-weight", c); font->Attribute("style", c, 256); sp_repr_css_set_property (css, "font-style", c); font->Attribute("stretch", c, 256); sp_repr_css_set_property (css, "font-stretch", c); font->Attribute("variant", c, 256); sp_repr_css_set_property (css, "font-variant", c); Inkscape::CSSOStringStream os; os << sp_font_selector_get_size (SP_FONT_SELECTOR (fontsel)) << "px"; // must specify px, see inkscape bug 1221626 and 1610103 sp_repr_css_set_property (css, "font-size", os.str().c_str()); font->Unref(); font=NULL; } /* Layout */ GtkWidget *b = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), "text_anchor_start"); // Align Left if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (b))) { sp_repr_css_set_property (css, "text-anchor", "start"); sp_repr_css_set_property (css, "text-align", "start"); } else { // Align Center b = (GtkWidget*)g_object_get_data ( G_OBJECT (dlg), "text_anchor_middle"); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (b))) { sp_repr_css_set_property (css, "text-anchor", "middle"); sp_repr_css_set_property (css, "text-align", "center"); } else { // Align Right b = (GtkWidget*)g_object_get_data ( G_OBJECT (dlg), "text_anchor_end"); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (b))) { sp_repr_css_set_property (css, "text-anchor", "end"); sp_repr_css_set_property (css, "text-align", "end"); } else { // Align Justify sp_repr_css_set_property (css, "text-anchor", "start"); sp_repr_css_set_property (css, "text-align", "justify"); } } } b = (GtkWidget*)g_object_get_data (G_OBJECT (dlg), INKSCAPE_STOCK_WRITING_MODE_LR ); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (b))) { sp_repr_css_set_property (css, "writing-mode", "lr"); } else { sp_repr_css_set_property (css, "writing-mode", "tb"); } // Note that CSS 1.1 does not support line-height; we set it for consistency, but also set // sodipodi:linespacing for backwards compatibility; in 1.2 we use line-height for flowtext GtkWidget *combo = (GtkWidget*)g_object_get_data ((GObject *) dlg, "line_spacing"); const char *sstr = gtk_entry_get_text ((GtkEntry *) ((GtkCombo *) (combo))->entry); sp_repr_css_set_property (css, "line-height", sstr); return css; }
static void sp_fill_style_widget_paint_changed (SPPaintSelector *psel, SPWidget *spw) { const GSList *items, *i, *r; GSList *reprs; SPCSSAttr *css; gfloat rgba[4], cmyka[5]; SPGradient *vector; gchar b[64]; if (g_object_get_data (G_OBJECT (spw), "update")) return; g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (TRUE)); #ifdef SP_FS_VERBOSE g_print ("FillStyleWidget: paint changed\n"); #endif if (spw->inkscape) { /* fixme: */ if (!SP_WIDGET_DOCUMENT (spw)) { g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE)); return; } reprs = NULL; items = sp_widget_get_item_list (spw); for (i = items; i != NULL; i = i->next) { reprs = g_slist_prepend (reprs, SP_OBJECT_REPR (i->data)); } } else { reprs = g_slist_prepend (NULL, spw->repr); items = NULL; } switch (psel->mode) { case SP_PAINT_SELECTOR_MODE_EMPTY: case SP_PAINT_SELECTOR_MODE_MULTIPLE: g_warning ("file %s: line %d: Paint %d should not emit 'changed'", __FILE__, __LINE__, psel->mode); break; case SP_PAINT_SELECTOR_MODE_NONE: css = sp_repr_css_attr_new (); sp_repr_css_set_property (css, "fill", "none"); for (r = reprs; r != NULL; r = r->next) { sp_repr_css_change_recursive ((SPRepr *) r->data, css, "style"); sp_repr_set_attr_recursive ((SPRepr *) r->data, "sodipodi:fill-cmyk", NULL); } sp_repr_css_attr_unref (css); if (spw->inkscape) sp_document_done (SP_WIDGET_DOCUMENT (spw)); break; case SP_PAINT_SELECTOR_MODE_COLOR_RGB: css = sp_repr_css_attr_new (); sp_paint_selector_get_rgba_floatv (psel, rgba); sp_svg_write_color (b, 64, SP_RGBA32_F_COMPOSE (rgba[0], rgba[1], rgba[2], 0.0)); sp_repr_css_set_property (css, "fill", b); g_snprintf (b, 64, "%g", rgba[3]); sp_repr_css_set_property (css, "fill-opacity", b); for (r = reprs; r != NULL; r = r->next) { sp_repr_set_attr_recursive ((SPRepr *) r->data, "sodipodi:fill-cmyk", NULL); sp_repr_css_change_recursive ((SPRepr *) r->data, css, "style"); } sp_repr_css_attr_unref (css); if (spw->inkscape) sp_document_done (SP_WIDGET_DOCUMENT (spw)); break; case SP_PAINT_SELECTOR_MODE_COLOR_CMYK: css = sp_repr_css_attr_new (); sp_paint_selector_get_cmyka_floatv (psel, cmyka); sp_color_cmyk_to_rgb_floatv (rgba, cmyka[0], cmyka[1], cmyka[2], cmyka[3]); sp_svg_write_color (b, 64, SP_RGBA32_F_COMPOSE (rgba[0], rgba[1], rgba[2], 0.0)); sp_repr_css_set_property (css, "fill", b); g_snprintf (b, 64, "%g", cmyka[4]); sp_repr_css_set_property (css, "fill-opacity", b); g_snprintf (b, 64, "(%g %g %g %g)", cmyka[0], cmyka[1], cmyka[2], cmyka[3]); for (r = reprs; r != NULL; r = r->next) { sp_repr_set_attr_recursive ((SPRepr *) r->data, "sodipodi:fill-cmyk", b); sp_repr_css_change_recursive ((SPRepr *) r->data, css, "style"); } sp_repr_css_attr_unref (css); if (spw->inkscape) sp_document_done (SP_WIDGET_DOCUMENT (spw)); break; case SP_PAINT_SELECTOR_MODE_GRADIENT_LINEAR: if (items) { vector = sp_paint_selector_get_gradient_vector (psel); if (!vector) { /* No vector in paint selector should mean that we just changed mode */ vector = sp_document_default_gradient_vector (SP_WIDGET_DOCUMENT (spw)); for (i = items; i != NULL; i = i->next) { sp_item_force_fill_lineargradient_vector (SP_ITEM (i->data), vector); } } else { vector = sp_gradient_ensure_vector_normalized (vector); for (i = items; i != NULL; i = i->next) { SPGradient *lg; lg = sp_item_force_fill_lineargradient_vector (SP_ITEM (i->data), vector); sp_paint_selector_write_lineargradient (psel, SP_LINEARGRADIENT (lg), SP_ITEM (i->data)); sp_object_invoke_write (SP_OBJECT (lg), SP_OBJECT_REPR (lg), SP_OBJECT_WRITE_EXT); } } sp_document_done (SP_WIDGET_DOCUMENT (spw)); } break; case SP_PAINT_SELECTOR_MODE_GRADIENT_RADIAL: if (items) { vector = sp_paint_selector_get_gradient_vector (psel); if (!vector) { /* No vector in paint selector should mean that we just changed mode */ vector = sp_document_default_gradient_vector (SP_WIDGET_DOCUMENT (spw)); for (i = items; i != NULL; i = i->next) { sp_item_force_fill_radialgradient_vector (SP_ITEM (i->data), vector); } } else { vector = sp_gradient_ensure_vector_normalized (vector); for (i = items; i != NULL; i = i->next) { SPGradient *rg; rg = sp_item_force_fill_radialgradient_vector (SP_ITEM (i->data), vector); sp_paint_selector_write_radialgradient (psel, SP_RADIALGRADIENT (rg), SP_ITEM (i->data)); sp_object_invoke_write (SP_OBJECT (rg), SP_OBJECT_REPR (rg), SP_OBJECT_WRITE_EXT); } } sp_document_done (SP_WIDGET_DOCUMENT (spw)); } break; default: g_warning ("file %s: line %d: Paint selector should not be in mode %d", __FILE__, __LINE__, psel->mode); break; } g_slist_free (reprs); g_object_set_data (G_OBJECT (spw), "update", GINT_TO_POINTER (FALSE)); }