summaryrefslogtreecommitdiffstats
path: root/src/path-chemistry.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/path-chemistry.cpp')
-rw-r--r--src/path-chemistry.cpp172
1 files changed, 118 insertions, 54 deletions
diff --git a/src/path-chemistry.cpp b/src/path-chemistry.cpp
index 8efd27be8..81bc531c1 100644
--- a/src/path-chemistry.cpp
+++ b/src/path-chemistry.cpp
@@ -95,9 +95,7 @@ ObjectSet::combine(bool skip_undo)
// remember the position, id, transform and style of the topmost path, they will be assigned to the combined one
gint position = 0;
- char const *id = nullptr;
char const *transform = nullptr;
- char const *style = nullptr;
char const *path_effect = nullptr;
SPCurve* curve = nullptr;
@@ -126,10 +124,8 @@ ObjectSet::combine(bool skip_undo)
first = item;
parent = first->getRepr()->parent();
position = first->getRepr()->position();
- id = first->getRepr()->attribute("id");
transform = first->getRepr()->attribute("transform");
// FIXME: merge styles of combined objects instead of using the first one's style
- style = first->getRepr()->attribute("style");
path_effect = first->getRepr()->attribute("inkscape:path-effect");
//c->transform(item->transform);
curve = c;
@@ -149,18 +145,18 @@ ObjectSet::combine(bool skip_undo)
if (did) {
- first->deleteObject(false);
- // delete the topmost.
-
Inkscape::XML::Document *xml_doc = doc->getReprDoc();
Inkscape::XML::Node *repr = xml_doc->createElement("svg:path");
+ Inkscape::copy_object_properties(repr, first->getRepr());
+
+ // delete the topmost.
+ first->deleteObject(false);
+
// restore id, transform, path effect, and style
- repr->setAttribute("id", id);
if (transform) {
repr->setAttribute("transform", transform);
}
- repr->setAttribute("style", style);
repr->setAttribute("inkscape:path-effect", path_effect);
@@ -447,14 +443,6 @@ sp_item_list_to_curves(const std::vector<SPItem*> &items, std::vector<SPItem*>&
Inkscape::XML::Node *parent = item->getRepr()->parent();
// remember class
char const *class_attr = item->getRepr()->attribute("class");
- // remember title
- gchar *title = item->title();
- // remember description
- gchar *desc = item->desc();
- // remember highlight color
- guint32 highlight_color = 0;
- if (item->isHighlightSet())
- highlight_color = item->highlight_color();
// It's going to resurrect, so we delete without notifying listeners.
item->deleteObject(false);
@@ -465,18 +453,6 @@ sp_item_list_to_curves(const std::vector<SPItem*> &items, std::vector<SPItem*>&
repr->setAttribute("class", class_attr);
// add the new repr to the parent
parent->appendChild(repr);
- SPObject* newObj = document->getObjectByRepr(repr);
- if (title && newObj) {
- newObj->setTitle(title);
- g_free(title);
- }
- if (desc && newObj) {
- newObj->setDesc(desc);
- g_free(desc);
- }
- if (highlight_color && newObj) {
- SP_ITEM(newObj)->setHighlightColor( highlight_color );
- }
// move to the saved position
repr->setPosition(pos > 0 ? pos : 0);
@@ -511,17 +487,8 @@ sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/)
}
g_repr->setAttribute("transform", item->getRepr()->attribute("transform"));
- /* Mask */
- gchar *mask_str = (gchar *) item->getRepr()->attribute("mask");
- if ( mask_str )
- g_repr->setAttribute("mask", mask_str);
- /* Clip path */
- gchar *clip_path_str = (gchar *) item->getRepr()->attribute("clip-path");
- if ( clip_path_str )
- g_repr->setAttribute("clip-path", clip_path_str);
- /* Rotation center */
- g_repr->setAttribute("inkscape:transform-center-x", item->getRepr()->attribute("inkscape:transform-center-x"), false);
- g_repr->setAttribute("inkscape:transform-center-y", item->getRepr()->attribute("inkscape:transform-center-y"), false);
+
+ Inkscape::copy_object_properties(g_repr, item->getRepr());
/* Whole text's style */
Glib::ustring style_str =
@@ -599,6 +566,9 @@ sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/)
}
Inkscape::XML::Node *repr = xml_doc->createElement("svg:path");
+
+ Inkscape::copy_object_properties(repr, item->getRepr());
+
/* Transformation */
repr->setAttribute("transform", item->getRepr()->attribute("transform"));
@@ -607,20 +577,6 @@ sp_selected_item_to_curved_repr(SPItem *item, guint32 /*text_grouping_policy*/)
item->style->write( SP_STYLE_FLAG_IFDIFF, SP_STYLE_SRC_UNSET, item->parent ? item->parent->style : nullptr); // TODO investigate possibility
repr->setAttribute("style", style_str.c_str());
- /* Mask */
- gchar *mask_str = (gchar *) item->getRepr()->attribute("mask");
- if ( mask_str )
- repr->setAttribute("mask", mask_str);
-
- /* Clip path */
- gchar *clip_path_str = (gchar *) item->getRepr()->attribute("clip-path");
- if ( clip_path_str )
- repr->setAttribute("clip-path", clip_path_str);
-
- /* Rotation center */
- repr->setAttribute("inkscape:transform-center-x", item->getRepr()->attribute("inkscape:transform-center-x"), false);
- repr->setAttribute("inkscape:transform-center-y", item->getRepr()->attribute("inkscape:transform-center-y"), false);
-
/* Definition */
gchar *def_str = sp_svg_write_path(curve->get_pathvector());
repr->setAttribute("d", def_str);
@@ -688,6 +644,114 @@ ObjectSet::pathReverse()
}
}
+
+/**
+ * Copy generic attributes, like those from the "Object Properties" dialog,
+ * but also style and transformation center.
+ *
+ * @param dest XML node to copy attributes to
+ * @param src XML node to copy attributes from
+ */
+static void ink_copy_generic_attributes( //
+ Inkscape::XML::Node *dest, //
+ Inkscape::XML::Node const *src)
+{
+ static char const *const keys[] = {
+ // core
+ "id",
+
+ // clip & mask
+ "clip-path",
+ "mask",
+
+ // style
+ "style",
+
+ // inkscape
+ "inkscape:highlight-color",
+ "inkscape:label",
+ "inkscape:transform-center-x",
+ "inkscape:transform-center-y",
+
+ // interactivity
+ "onclick",
+ "onmouseover",
+ "onmouseout",
+ "onmousedown",
+ "onmouseup",
+ "onmousemove",
+ "onfocusin",
+ "onfocusout",
+ "onload",
+ };
+
+ for (auto *key : keys) {
+ auto *value = src->attribute(key);
+ if (value) {
+ dest->setAttribute(key, value);
+ }
+ }
+}
+
+
+/**
+ * Copy generic child elements, like those from the "Object Properties" dialog
+ * (title and description) but also XML comments.
+ *
+ * Does not check if children of the same type already exist in dest.
+ *
+ * @param dest XML node to copy children to
+ * @param src XML node to copy children from
+ */
+static void ink_copy_generic_children( //
+ Inkscape::XML::Node *dest, //
+ Inkscape::XML::Node const *src)
+{
+ static std::set<std::string> const names{
+ // descriptive elements
+ "svg:title",
+ "svg:desc",
+ };
+
+ for (const auto *child = src->firstChild(); child != nullptr; child = child->next()) {
+ // check if this child should be copied
+ if (!(child->type() == Inkscape::XML::COMMENT_NODE || //
+ (child->name() && names.count(child->name())))) {
+ continue;
+ }
+
+ auto dchild = child->duplicate(dest->document());
+ dest->appendChild(dchild);
+ dchild->release();
+ }
+}
+
+
+/**
+ * Copy generic object properties, like:
+ * - id
+ * - label
+ * - title
+ * - description
+ * - style
+ * - clip
+ * - mask
+ * - transformation center
+ * - highlight color
+ * - interactivity (event attributes)
+ *
+ * @param dest XML node to copy to
+ * @param src XML node to copy from
+ */
+void Inkscape::copy_object_properties( //
+ Inkscape::XML::Node *dest, //
+ Inkscape::XML::Node const *src)
+{
+ ink_copy_generic_attributes(dest, src);
+ ink_copy_generic_children(dest, src);
+}
+
+
/*
Local Variables:
mode:c++