diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 6c92624d60d071bf5829f9505cc421bf418610a2..09f72589cf2a8903c6aea1f1bc6745e38189947b 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -424,7 +424,7 @@ bool ClipboardManagerImpl::paste(SPDesktop *desktop, bool in_place) if ( Inkscape::have_viable_layer(desktop, desktop->getMessageStack()) == false ) { return false; } - + Glib::ustring target = _getBestTarget(); // Special cases of clipboard content handling go here @@ -591,10 +591,13 @@ bool ClipboardManagerImpl::pasteStyle(ObjectSet *set) bool pasted = false; if (clipnode) { - set->document()->importDefs(tempdoc.get()); - SPCSSAttr *style = sp_repr_css_attr(clipnode, "style"); - sp_desktop_set_style(set, set->desktop(), style); - pasted = true; + for (auto node : set->xmlNodes()) { + pasted = node->copyAttribute("class", clipnode, true) || pasted; + pasted = node->copyAttribute("style", clipnode, true) || pasted; + } + if (pasted) { + set->document()->importDefs(tempdoc.get()); + } } else { _userWarn(set->desktop(), _("No style on the clipboard.")); @@ -900,16 +903,6 @@ void ClipboardManagerImpl::_copySelection(ObjectSet *selection) else obj_copy = _copyNode(obj, _doc, _clipnode); - // copy complete inherited style - SPCSSAttr *css = sp_repr_css_attr_inherited(obj, "style"); - for (auto iter : item->style->properties()) { - if (iter->style_src == SPStyleSrc::STYLE_SHEET) { - css->setAttributeOrRemoveIfEmpty(iter->name(), iter->get_value()); - } - } - sp_repr_css_set(obj_copy, css, "style"); - sp_repr_css_attr_unref(css); - // 1.1 COPYPASTECLONESTAMPLPEBUG if (_clipboardSPDoc) { SPItem *newitem = dynamic_cast(_clipboardSPDoc->getObjectByRepr(obj_copy)); @@ -928,18 +921,14 @@ void ClipboardManagerImpl::_copySelection(ObjectSet *selection) // copy style for Paste Style action if (!sorted_items.empty()) { SPObject *object = sorted_items[0]; - SPItem *item = dynamic_cast(object); - if (item) { - SPCSSAttr *style = take_style_from_item(item); - sp_repr_css_set(_clipnode, style, "style"); - sp_repr_css_attr_unref(style); - } - // copy path effect from the first path if (object) { - gchar const *effect =object->getRepr()->attribute("inkscape:path-effect"); - if (effect) { - _clipnode->setAttribute("inkscape:path-effect", effect); - } + auto *const node = object->getRepr(); + + _clipnode->copyAttribute("class", node, true); + _clipnode->copyAttribute("style", node, true); + + // copy path effect from the first path + _clipnode->copyAttribute("inkscape:path-effect", node); } } diff --git a/src/xml/node.cpp b/src/xml/node.cpp index 94a41989a781de6d422093f5fb7daeab82f68e2c..516e03a9bceb41f794f3f5bab3bcd14bc2de6feb 100644 --- a/src/xml/node.cpp +++ b/src/xml/node.cpp @@ -26,6 +26,26 @@ void Node::setAttribute(Util::const_char_ptr key, Util::const_char_ptr value) this->setAttributeImpl(key.data(), value.data()); } +bool Node::copyAttribute(Util::const_char_ptr key, Node const *source_node, + bool remove_if_empty) +{ + if (source_node) { + if (auto const value = source_node->attribute(key.data())) { + if (*value || !remove_if_empty) { + setAttribute(key, value); + } + return true; + } + + if (remove_if_empty) { + removeAttribute(key); + return true; + } + } + + return false; +} + bool Node::getAttributeBoolean(Util::const_char_ptr key, bool default_value) const { auto v = this->attribute(key.data()); @@ -150,4 +170,4 @@ void Node::setAttributeOrRemoveIfEmpty(Inkscape::Util::const_char_ptr key, Inksc } } // namespace XML -} // namespace Inkscape \ No newline at end of file +} // namespace Inkscape diff --git a/src/xml/node.h b/src/xml/node.h index 5c84394dfa785f02a6ce5dd62d5bf6b2ee4625eb..3847c56dae2ec80a995d411fb77f887da0beaca3 100644 --- a/src/xml/node.h +++ b/src/xml/node.h @@ -206,11 +206,26 @@ public: * * @param key Name of the attribute to change * @param value The new value of the attribute - * @param is_interactive Ignored */ void setAttribute(Util::const_char_ptr key, Util::const_char_ptr value); + /** + * @brief Copy attribute value from another node to this node + * + * @param key Name of the attribute to change + * @param source_node Node from which to take the attribute value + * @param remove_if_empty + * If true, and the source node has no such attribute, or the source + * node's value for the attribute is an empty string, the attribute + * will be removed (if present) from this node. + * + * @return true if the attribute was set, false otherwise. + */ + + bool copyAttribute(Util::const_char_ptr key, Node const *source_node, + bool remove_if_empty = false); + /** * Parses the boolean value of an attribute "key" in repr and sets val accordingly, or to false if * the attr is not set.