コード例 #1
0
ファイル: fill-style.c プロジェクト: benjohnson2001/base
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);
}
コード例 #2
0
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;
}
コード例 #3
0
ファイル: gdkpixbuf-input.cpp プロジェクト: tik0/inkscapeGrid
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;
}
コード例 #4
0
ファイル: text-edit.c プロジェクト: benjohnson2001/base
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);
}
コード例 #5
0
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."));
    }
}
コード例 #6
0
ファイル: sp-path.c プロジェクト: benjohnson2001/base
/**
 *  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);
	}
}
コード例 #7
0
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;
}
コード例 #8
0
ファイル: fill-style.c プロジェクト: benjohnson2001/base
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));
}