From 2aca58a57e33c224650b5cd1686ac211aa75964a Mon Sep 17 00:00:00 2001 From: Johan Engelen Date: Sun, 14 Mar 2010 18:59:51 +0100 Subject: [PATCH] fix pasting of LPE stacks --- src/path-chemistry.cpp | 34 +++++++++++++++++++++++++++++++++- src/path-chemistry.h | 3 ++- src/ui/clipboard.cpp | 29 ++++++++++++++++++----------- 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/src/path-chemistry.cpp b/src/path-chemistry.cpp index 50d26ba64..c44ab5bc6 100644 --- a/src/path-chemistry.cpp +++ b/src/path-chemistry.cpp @@ -323,8 +323,33 @@ sp_selected_path_to_curves(SPDesktop *desktop, bool interactive) } } +/** Converts the selected items to LPEItems if they are not already so; e.g. SPRects) */ +void sp_selected_to_lpeitems(SPDesktop *desktop) +{ + Inkscape::Selection *selection = sp_desktop_selection(desktop); + + if (selection->isEmpty()) { + return; + } + + bool did = false; + + GSList *selected = g_slist_copy((GSList *) selection->itemList()); + GSList *to_select = NULL; + selection->clear(); + GSList *items = g_slist_copy(selected); + + did = sp_item_list_to_curves(items, &selected, &to_select, true); + + g_slist_free (items); + selection->setReprList(to_select); + selection->addList(selected); + g_slist_free (to_select); + g_slist_free (selected); +} + bool -sp_item_list_to_curves(const GSList *items, GSList **selected, GSList **to_select) +sp_item_list_to_curves(const GSList *items, GSList **selected, GSList **to_select, bool skip_all_lpeitems) { bool did = false; @@ -335,6 +360,13 @@ sp_item_list_to_curves(const GSList *items, GSList **selected, GSList **to_selec SPItem *item = SP_ITEM(items->data); SPDocument *document = item->document; + if ( skip_all_lpeitems && + SP_IS_LPE_ITEM(item) && + !SP_IS_GROUP(item) ) // also convert objects in an SPGroup when skip_all_lpeitems is set. + { + continue; + } + if (SP_IS_PATH(item) && !SP_PATH(item)->original_curve) { continue; // already a path, and no path effect } diff --git a/src/path-chemistry.h b/src/path-chemistry.h index 14b2b6ffb..64d7f63af 100644 --- a/src/path-chemistry.h +++ b/src/path-chemistry.h @@ -18,9 +18,10 @@ void sp_selected_path_combine (SPDesktop *desktop); void sp_selected_path_break_apart (SPDesktop *desktop); void sp_selected_path_to_curves (SPDesktop *desktop, bool interactive = true); +void sp_selected_to_lpeitems(SPDesktop *desktop); Inkscape::XML::Node *sp_selected_item_to_curved_repr(SPItem *item, guint32 text_grouping_policy); void sp_selected_path_reverse (SPDesktop *desktop); -bool sp_item_list_to_curves(const GSList *items, GSList **selected, GSList **to_select); +bool sp_item_list_to_curves(const GSList *items, GSList **selected, GSList **to_select, bool skip_all_lpeitems = false); #endif diff --git a/src/ui/clipboard.cpp b/src/ui/clipboard.cpp index 99d835730..db509da2e 100644 --- a/src/ui/clipboard.cpp +++ b/src/ui/clipboard.cpp @@ -489,13 +489,14 @@ bool ClipboardManagerImpl::pastePathEffect() Inkscape::XML::Node *root = sp_document_repr_root(tempdoc); Inkscape::XML::Node *clipnode = sp_repr_lookup_name(root, "inkscape:clipboard", 1); if ( clipnode ) { - gchar const *effect = clipnode->attribute("inkscape:path-effect"); - if ( effect ) { + gchar const *effectstack = clipnode->attribute("inkscape:path-effect"); + if ( effectstack ) { _pasteDefs(tempdoc); // make sure all selected items are converted to paths first (i.e. rectangles) - sp_selected_path_to_curves(desktop, false); - for (GSList *item = const_cast(selection->itemList()) ; item ; item = item->next) { - _applyPathEffect(reinterpret_cast(item->data), effect); + sp_selected_to_lpeitems(desktop); + for (GSList *itemptr = const_cast(selection->itemList()) ; itemptr ; itemptr = itemptr->next) { + SPItem *item = reinterpret_cast(itemptr->data); + _applyPathEffect(item, effectstack); } return true; @@ -976,7 +977,7 @@ SPCSSAttr *ClipboardManagerImpl::_parseColor(const Glib::ustring &text) /** * @brief Applies a pasted path effect to a given item */ -void ClipboardManagerImpl::_applyPathEffect(SPItem *item, gchar const *effect) +void ClipboardManagerImpl::_applyPathEffect(SPItem *item, gchar const *effectstack) { if ( item == NULL ) return; if ( SP_IS_RECT(item) ) return; @@ -984,11 +985,17 @@ void ClipboardManagerImpl::_applyPathEffect(SPItem *item, gchar const *effect) if (SP_IS_LPE_ITEM(item)) { SPLPEItem *lpeitem = SP_LPE_ITEM(item); - SPObject *obj = sp_uri_reference_resolve(_clipboardSPDoc, effect); - if (!obj) return; - // if the effect is not used by anyone, we might as well take it - LivePathEffectObject *lpeobj = LIVEPATHEFFECT(obj)->fork_private_if_necessary(1); - sp_lpe_item_add_path_effect(lpeitem, lpeobj); + // for each effect in the stack, check if we need to fork it before adding it to the item + std::istringstream iss(effectstack); + std::string href; + while (std::getline(iss, href, ';')) + { + SPObject *obj = sp_uri_reference_resolve(_clipboardSPDoc, href.c_str()); + if (!obj) return; + // if the effectstack is not used by anyone, we might as well take it + LivePathEffectObject *lpeobj = LIVEPATHEFFECT(obj)->fork_private_if_necessary(1); + sp_lpe_item_add_path_effect(lpeitem, lpeobj); + } } } -- 2.30.2