From 2d2718e48ee56f975342f0329b98f892f118d85e Mon Sep 17 00:00:00 2001 From: Jabier Arraiza Cenoz Date: Sun, 22 May 2016 00:03:52 +0200 Subject: Fixing undo thing (bzr r14865.1.5) --- src/selection-chemistry.cpp | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 7d32477a1..2c93c5496 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -1031,7 +1031,7 @@ sp_selection_raise(Inkscape::Selection *selection, SPDesktop *desktop) C_("Undo action", "Raise")); } -void sp_selection_raise_to_top(Inkscape::Selection *selection, SPDesktop *desktop) +void sp_selection_raise_to_top(Inkscape::Selection *selection, SPDesktop *desktop, bool skip_undo) { SPDocument *document = selection->layers()->getDocument(); @@ -1055,9 +1055,10 @@ void sp_selection_raise_to_top(Inkscape::Selection *selection, SPDesktop *deskto Inkscape::XML::Node *repr =(*l); repr->setPosition(-1); } - - DocumentUndo::done(document, SP_VERB_SELECTION_TO_FRONT, - _("Raise to top")); + if (!skip_undo) { + DocumentUndo::done(document, SP_VERB_SELECTION_TO_FRONT, + _("Raise to top")); + } } void sp_selection_lower(Inkscape::Selection *selection, SPDesktop *desktop) @@ -1115,7 +1116,7 @@ void sp_selection_lower(Inkscape::Selection *selection, SPDesktop *desktop) C_("Undo action", "Lower")); } -void sp_selection_lower_to_bottom(Inkscape::Selection *selection, SPDesktop *desktop) +void sp_selection_lower_to_bottom(Inkscape::Selection *selection, SPDesktop *desktop, bool skip_undo) { SPDocument *document = selection->layers()->getDocument(); @@ -1149,9 +1150,10 @@ void sp_selection_lower_to_bottom(Inkscape::Selection *selection, SPDesktop *des } repr->setPosition(minpos); } - - DocumentUndo::done(document, SP_VERB_SELECTION_TO_BACK, - _("Lower to bottom")); + if (!skip_undo) { + DocumentUndo::done(document, SP_VERB_SELECTION_TO_BACK, + _("Lower to bottom")); + } } void @@ -3859,7 +3861,7 @@ void sp_selection_set_clipgroup(SPDesktop *desktop) * If \a apply_clip_path parameter is true, clipPath is created, otherwise mask * */ -void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_to_layer) +void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_to_layer, bool skip_undo) { if (desktop == NULL) { return; @@ -4021,11 +4023,12 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ } selection->addList(items_to_select); - - if (apply_clip_path) { - DocumentUndo::done(doc, SP_VERB_OBJECT_SET_CLIPPATH, _("Set clipping path")); - } else { - DocumentUndo::done(doc, SP_VERB_OBJECT_SET_MASK, _("Set mask")); + if (!skip_undo) { + if (apply_clip_path) { + DocumentUndo::done(doc, SP_VERB_OBJECT_SET_CLIPPATH, _("Set clipping path")); + } else { + DocumentUndo::done(doc, SP_VERB_OBJECT_SET_MASK, _("Set mask")); + } } } -- cgit v1.2.3 From 1636c1dd1651780d01759676b194312529f211f7 Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Sat, 25 Jun 2016 22:24:26 +0200 Subject: Moved next functions, added namespace, renamed range functions (bzr r14954.1.10) --- src/selection-chemistry.cpp | 82 ++++++++++++++++++++++----------------------- 1 file changed, 41 insertions(+), 41 deletions(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index a13f3e64d..ded776fea 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -282,7 +282,7 @@ void SelectionHelper::fixSelection(SPDesktop *dt) std::vector items ; - std::vector const selList = selection->itemList(); + std::vector const selList = selection->items(); for( std::vector::const_reverse_iterator i = selList.rbegin(); i != selList.rend(); ++i ) { SPItem *item = *i; @@ -409,7 +409,7 @@ void sp_selection_delete(SPDesktop *desktop) desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Nothing was deleted.")); return; } - std::vector selected(selection->itemList()); + std::vector selected(selection->items()); selection->clear(); sp_selection_delete_impl(selected); desktop->currentLayer()->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); @@ -454,7 +454,7 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone, bool duplicat desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to duplicate.")); return; } - std::vector reprs(selection->reprList()); + std::vector reprs(selection->xmlNodes()); if(duplicateLayer){ reprs.clear(); @@ -624,7 +624,7 @@ static void sp_edit_select_all_full(SPDesktop *dt, bool force_all_layers, bool i std::vector exclude; if (invert) { - exclude = selection->itemList(); + exclude = selection->items(); } if (force_all_layers) @@ -763,7 +763,7 @@ void sp_selection_group(Inkscape::Selection *selection, SPDesktop *desktop) return; } - std::vector p (selection->reprList()); + std::vector p (selection->xmlNodes()); selection->clear(); @@ -798,7 +798,7 @@ void sp_selection_ungroup_pop_selection(Inkscape::Selection *selection, SPDeskto selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("No objects selected to pop out of group.")); return; } - std::vector selection_list = selection->itemList(); + std::vector selection_list = selection->items(); std::vector::const_iterator item = selection_list.begin(); // leaving this because it will be useful for // future implementation of complex pop ungrouping @@ -831,7 +831,7 @@ void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop) } // first check whether there is anything to ungroup - std::vector old_select = selection->itemList(); + std::vector old_select = selection->items(); std::vector new_select; GSList *groups = NULL; for (std::vector::const_iterator item = old_select.begin(); item!=old_select.end(); ++item) { @@ -983,7 +983,7 @@ bool sp_item_repr_compare_position_bool(SPObject const *first, SPObject const *s void sp_selection_raise(Inkscape::Selection *selection, SPDesktop *desktop) { - std::vector items= selection->itemList(); + std::vector items= selection->items(); if (items.empty()) { selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select object(s) to raise.")); return; @@ -1040,7 +1040,7 @@ void sp_selection_raise_to_top(Inkscape::Selection *selection, SPDesktop *deskto return; } - std::vector items = selection->itemList(); + std::vector items = selection->items(); SPGroup const *group = sp_item_list_common_parent_group(items); if (!group) { @@ -1048,7 +1048,7 @@ void sp_selection_raise_to_top(Inkscape::Selection *selection, SPDesktop *deskto return; } - std::vector rl(selection->reprList()); + std::vector rl(selection->xmlNodes()); sort(rl.begin(),rl.end(),sp_repr_compare_position_bool); for (std::vector::const_iterator l=rl.begin(); l!=rl.end();++l) { @@ -1062,7 +1062,7 @@ void sp_selection_raise_to_top(Inkscape::Selection *selection, SPDesktop *deskto void sp_selection_lower(Inkscape::Selection *selection, SPDesktop *desktop) { - std::vector items = selection->itemList(); + std::vector items = selection->items(); if (items.empty()) { selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select object(s) to lower.")); return; @@ -1124,7 +1124,7 @@ void sp_selection_lower_to_bottom(Inkscape::Selection *selection, SPDesktop *des return; } - std::vector items =selection->itemList(); + std::vector items = selection->items(); SPGroup const *group = sp_item_list_common_parent_group(items); if (!group) { @@ -1132,7 +1132,7 @@ void sp_selection_lower_to_bottom(Inkscape::Selection *selection, SPDesktop *des return; } - std::vector rl(selection->reprList()); + std::vector rl(selection->xmlNodes()); sort(rl.begin(),rl.end(),sp_repr_compare_position_bool); for (std::vector::const_reverse_iterator l=rl.rbegin();l!=rl.rend();++l) { @@ -1287,7 +1287,7 @@ void sp_selection_remove_livepatheffect(SPDesktop *desktop) desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to remove live path effects from.")); return; } - std::vector list=selection->itemList(); + std::vector list= selection->items(); for ( std::vector::const_iterator itemlist=list.begin();itemlist!=list.end();++itemlist) { SPItem *item = *itemlist; @@ -1368,7 +1368,7 @@ void sp_selection_to_next_layer(SPDesktop *dt, bool suppressDone) return; } - std::vector items(selection->itemList()); + std::vector items(selection->items()); bool no_more = false; // Set to true, if no more layers above SPObject *next=Inkscape::next_layer(dt->currentRoot(), dt->currentLayer()); @@ -1412,7 +1412,7 @@ void sp_selection_to_prev_layer(SPDesktop *dt, bool suppressDone) return; } - const std::vector items(selection->itemList()); + const std::vector items(selection->items()); bool no_more = false; // Set to true, if no more layers below SPObject *next=Inkscape::previous_layer(dt->currentRoot(), dt->currentLayer()); @@ -1455,7 +1455,7 @@ void sp_selection_to_layer(SPDesktop *dt, SPObject *moveto, bool suppressDone) return; } - std::vector items(selection->itemList()); + std::vector items(selection->items()); if (moveto) { selection->clear(); @@ -1506,7 +1506,7 @@ static bool selection_contains_both_clone_and_original(Inkscape::Selection *selection) { bool clone_with_original = false; - std::vector items = selection->itemList(); + std::vector items = selection->items(); for (std::vector::const_iterator l=items.begin();l!=items.end() ;++l) { SPItem *item = *l; if (item) { @@ -1551,7 +1551,7 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons persp3d_apply_affine_transformation(transf_persp, affine); } - std::vector items = selection->itemList(); + std::vector items = selection->items(); for (std::vector::const_iterator l=items.begin();l!=items.end() ;++l) { SPItem *item = *l; @@ -1722,7 +1722,7 @@ void sp_selection_remove_transform(SPDesktop *desktop) Inkscape::Selection *selection = desktop->getSelection(); - std::vector items = selection->reprList(); + std::vector items = selection->xmlNodes(); for (std::vector::const_iterator l=items.begin();l!=items.end() ;++l) { (*l)->setAttribute("transform", NULL, false); } @@ -1822,7 +1822,7 @@ void sp_selection_rotate_90(SPDesktop *desktop, bool ccw) if (selection->isEmpty()) return; - std::vector items = selection->itemList(); + std::vector items = selection->items(); Geom::Rotate const rot_90(Geom::Point(0, ccw ? 1 : -1)); // pos. or neg. rotation, depending on the value of ccw for (std::vector::const_iterator l=items.begin();l!=items.end() ;++l) { SPItem *item = *l; @@ -1886,7 +1886,7 @@ void sp_select_same_fill_stroke_style(SPDesktop *desktop, gboolean fill, gboolea std::vector all_matches; Inkscape::Selection *selection = desktop->getSelection(); - std::vector items = selection->itemList(); + std::vector items = selection->items(); std::vector tmp; for (std::vector::const_iterator iter=all_list.begin();iter!=all_list.end();++iter) { @@ -1943,7 +1943,7 @@ void sp_select_same_object_type(SPDesktop *desktop) Inkscape::Selection *selection = desktop->getSelection(); - std::vector items=selection->itemList(); + std::vector items= selection->items(); for (std::vector::const_iterator sel_iter=items.begin();sel_iter!=items.end();++sel_iter) { SPItem *sel = *sel_iter; if (sel) { @@ -2456,7 +2456,7 @@ sp_selection_item_next(SPDesktop *desktop) root = desktop->currentRoot(); } - SPItem *item=next_item_from_list(desktop, selection->itemList(), root, SP_CYCLING == SP_CYCLE_VISIBLE, inlayer, onlyvisible, onlysensitive); + SPItem *item=next_item_from_list(desktop, selection->items(), root, SP_CYCLING == SP_CYCLE_VISIBLE, inlayer, onlyvisible, onlysensitive); if (item) { selection->set(item, PREFS_SELECTION_LAYER_RECURSIVE == inlayer); @@ -2486,7 +2486,7 @@ sp_selection_item_prev(SPDesktop *desktop) root = desktop->currentRoot(); } - SPItem *item=next_item_from_list(desktop, selection->itemList(), root, SP_CYCLING == SP_CYCLE_VISIBLE, inlayer, onlyvisible, onlysensitive); + SPItem *item=next_item_from_list(desktop, selection->items(), root, SP_CYCLING == SP_CYCLE_VISIBLE, inlayer, onlyvisible, onlysensitive); if (item) { selection->set(item, PREFS_SELECTION_LAYER_RECURSIVE == inlayer); @@ -2603,7 +2603,7 @@ void sp_selection_clone(SPDesktop *desktop) return; } - std::vector reprs (selection->reprList()); + std::vector reprs (selection->xmlNodes()); selection->clear(); @@ -2662,7 +2662,7 @@ sp_selection_relink(SPDesktop *desktop) // Get a copy of current selection. bool relinked = false; - std::vector items=selection->itemList(); + std::vector items= selection->items(); for (std::vector::const_iterator i=items.begin();i!=items.end();++i){ SPItem *item = *i; @@ -2700,7 +2700,7 @@ sp_selection_unlink(SPDesktop *desktop) // Get a copy of current selection. std::vector new_select; bool unlinked = false; - std::vector items=selection->itemList(); + std::vector items= selection->items(); for (std::vector::const_reverse_iterator i=items.rbegin();i!=items.rend();++i){ SPItem *item = *i; @@ -2767,7 +2767,7 @@ sp_select_clone_original(SPDesktop *desktop) // Check if other than two objects are selected - std::vector items=selection->itemList(); + std::vector items= selection->items(); if (items.size() != 1 || !item) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, error); return; @@ -2865,7 +2865,7 @@ void sp_selection_clone_original_path_lpe(SPDesktop *desktop) Inkscape::SVGOStringStream os; SPObject * firstItem = NULL; - std::vector items=selection->itemList(); + std::vector items= selection->items(); for (std::vector::const_iterator i=items.begin();i!=items.end();++i){ if (SP_IS_SHAPE(*i) || SP_IS_TEXT(*i)) { if (firstItem) { @@ -2950,7 +2950,7 @@ void sp_selection_to_marker(SPDesktop *desktop, bool apply) Geom::Point center( *c - corner ); // As defined by rotation center center[Geom::Y] = -center[Geom::Y]; - std::vector items(selection->itemList()); + std::vector items(selection->items()); //items = g_slist_sort(items, (GCompareFunc) sp_object_compare_position); // Why needed? @@ -3024,7 +3024,7 @@ void sp_selection_to_guides(SPDesktop *desktop) SPDocument *doc = desktop->getDocument(); Inkscape::Selection *selection = desktop->getSelection(); // we need to copy the list because it gets reset when objects are deleted - std::vector items(selection->itemList()); + std::vector items(selection->items()); if (items.empty()) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to convert to guides.")); @@ -3090,7 +3090,7 @@ void sp_selection_symbol(SPDesktop *desktop, bool /*apply*/ ) doc->ensureUpToDate(); - std::vector items(selection->range().begin(), selection->range().end()); + std::vector items(selection->objects().begin(), selection->objects().end()); sort(items.begin(),items.end(),sp_object_compare_position_bool); // Keep track of parent, this is where will be inserted. @@ -3302,7 +3302,7 @@ sp_selection_tile(SPDesktop *desktop, bool apply) move_p[Geom::Y] = -move_p[Geom::Y]; Geom::Affine move = Geom::Affine(Geom::Translate(move_p)); - std::vector items (selection->itemList()); + std::vector items (selection->items()); sort(items.begin(),items.end(),sp_object_compare_position_bool); @@ -3407,7 +3407,7 @@ void sp_selection_untile(SPDesktop *desktop) bool did = false; - std::vector items(selection->itemList()); + std::vector items(selection->items()); for (std::vector::const_reverse_iterator i=items.rbegin();i!=items.rend();++i){ SPItem *item = *i; @@ -3472,7 +3472,7 @@ void sp_selection_get_export_hints(Inkscape::Selection *selection, Glib::ustring return; } - std::vector const reprlst = selection->reprList(); + std::vector const reprlst = selection->xmlNodes(); bool filename_search = TRUE; bool xdpi_search = TRUE; bool ydpi_search = TRUE; @@ -3564,7 +3564,7 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop) } // List of the items to show; all others will be hidden - std::vector items(selection->itemList()); + std::vector items(selection->items()); // Sort items so that the topmost comes last sort(items.begin(),items.end(),sp_item_repr_compare_position_bool); @@ -3765,7 +3765,7 @@ void sp_selection_set_clipgroup(SPDesktop *desktop) return; } - std::vector p(selection->reprList()); + std::vector p(selection->xmlNodes()); sort(p.begin(),p.end(),sp_repr_compare_position_bool); @@ -3875,7 +3875,7 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ if ( apply_to_layer && is_empty) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to create clippath or mask from.")); return; - } else if (!apply_to_layer && ( is_empty || selection->itemList().size()==1 )) { + } else if (!apply_to_layer && ( is_empty || selection->items().size()==1 )) { desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select mask object and object(s) to apply clippath or mask to.")); return; } @@ -3890,7 +3890,7 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ doc->ensureUpToDate(); - std::vector items(selection->itemList()); + std::vector items(selection->items()); sort(items.begin(),items.end(),sp_object_compare_position_bool); @@ -4052,7 +4052,7 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) { gchar const *attributeName = apply_clip_path ? "clip-path" : "mask"; std::map referenced_objects; - std::vector items(selection->itemList()); + std::vector items(selection->items()); selection->clear(); GSList *items_to_ungroup = NULL; -- cgit v1.2.3 From 22262f2db6747eb516283b92abcfd348c700911a Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Fri, 1 Jul 2016 20:57:32 +0200 Subject: Added xmlNodes as range function (bzr r14954.1.12) --- src/selection-chemistry.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index ded776fea..82f89c03a 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -454,7 +454,7 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone, bool duplicat desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to duplicate.")); return; } - std::vector reprs(selection->xmlNodes()); + std::vector reprs(selection->xmlNodes().begin(), selection->xmlNodes().end()); if(duplicateLayer){ reprs.clear(); @@ -763,7 +763,7 @@ void sp_selection_group(Inkscape::Selection *selection, SPDesktop *desktop) return; } - std::vector p (selection->xmlNodes()); + std::vector p (selection->xmlNodes().begin(), selection->xmlNodes().end()); selection->clear(); @@ -1048,7 +1048,7 @@ void sp_selection_raise_to_top(Inkscape::Selection *selection, SPDesktop *deskto return; } - std::vector rl(selection->xmlNodes()); + std::vector rl(selection->xmlNodes().begin(), selection->xmlNodes().end()); sort(rl.begin(),rl.end(),sp_repr_compare_position_bool); for (std::vector::const_iterator l=rl.begin(); l!=rl.end();++l) { @@ -1132,7 +1132,7 @@ void sp_selection_lower_to_bottom(Inkscape::Selection *selection, SPDesktop *des return; } - std::vector rl(selection->xmlNodes()); + std::vector rl(selection->xmlNodes().begin(), selection->xmlNodes().end()); sort(rl.begin(),rl.end(),sp_repr_compare_position_bool); for (std::vector::const_reverse_iterator l=rl.rbegin();l!=rl.rend();++l) { @@ -1722,8 +1722,8 @@ void sp_selection_remove_transform(SPDesktop *desktop) Inkscape::Selection *selection = desktop->getSelection(); - std::vector items = selection->xmlNodes(); - for (std::vector::const_iterator l=items.begin();l!=items.end() ;++l) { + auto items = selection->xmlNodes(); + for (auto l=items.begin();l!=items.end() ;++l) { (*l)->setAttribute("transform", NULL, false); } @@ -2603,7 +2603,7 @@ void sp_selection_clone(SPDesktop *desktop) return; } - std::vector reprs (selection->xmlNodes()); + std::vector reprs(selection->xmlNodes().begin(), selection->xmlNodes().end()); selection->clear(); @@ -3472,12 +3472,12 @@ void sp_selection_get_export_hints(Inkscape::Selection *selection, Glib::ustring return; } - std::vector const reprlst = selection->xmlNodes(); + auto reprlst = selection->xmlNodes(); bool filename_search = TRUE; bool xdpi_search = TRUE; bool ydpi_search = TRUE; - for (std::vector::const_iterator i=reprlst.begin();filename_search&&xdpi_search&&ydpi_search&&i!=reprlst.end();++i){ + for (auto i=reprlst.begin();filename_search&&xdpi_search&&ydpi_search&&i!=reprlst.end();++i){ gchar const *dpi_string; Inkscape::XML::Node *repr = *i; @@ -3765,7 +3765,7 @@ void sp_selection_set_clipgroup(SPDesktop *desktop) return; } - std::vector p(selection->xmlNodes()); + std::vector p(selection->xmlNodes().begin(), selection->xmlNodes().end()); sort(p.begin(),p.end(),sp_repr_compare_position_bool); -- cgit v1.2.3 From 058e95a59ccb2ab1748392acdfdbbffd516c9c81 Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Mon, 11 Jul 2016 14:24:52 +0200 Subject: First part of new SPObject children list (bzr r14954.1.17) --- src/selection-chemistry.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 4b5c3f921..1f34f798d 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -4261,11 +4261,11 @@ static void itemtree_map(void (*f)(SPItem *, SPDesktop *), SPObject *root, SPDes f(item, desktop); } } - for ( SPObject::SiblingIterator iter = root->firstChild() ; iter ; ++iter ) { + for (auto& child: root->_children) { //don't recurse into locked layers - SPItem *item = dynamic_cast(&*iter); + SPItem *item = dynamic_cast(&child); if (!(item && desktop->isLayer(item) && item->isLocked())) { - itemtree_map(f, iter, desktop); + itemtree_map(f, &child, desktop); } } } -- cgit v1.2.3 From d1947e768272c703674129d5c583204ff2b59251 Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Wed, 13 Jul 2016 13:36:19 +0200 Subject: Second part of new SPObject children list (bzr r14954.1.19) --- src/selection-chemistry.cpp | 43 +++++++++++++++++++++++-------------------- 1 file changed, 23 insertions(+), 20 deletions(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 1f34f798d..55f4118b0 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -88,6 +88,7 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include #include #include +#include #include "sp-item.h" #include "box3d.h" #include "persp3d.h" @@ -432,8 +433,8 @@ static void add_ids_recursive(std::vector &ids, SPObject *obj) ids.push_back(obj->getId()); if (dynamic_cast(obj)) { - for (SPObject *child = obj->firstChild() ; child; child = child->getNext() ) { - add_ids_recursive(ids, child); + for (auto& child: obj->_children) { + add_ids_recursive(ids, &child); } } } @@ -586,20 +587,20 @@ void sp_edit_clear_all(Inkscape::Selection *selection) */ std::vector &get_all_items(std::vector &list, SPObject *from, SPDesktop *desktop, bool onlyvisible, bool onlysensitive, bool ingroups, std::vector const &exclude) { - for ( SPObject *child = from->firstChild() ; child; child = child->getNext() ) { - SPItem *item = dynamic_cast(child); + for (auto& child: from->_children) { + SPItem *item = dynamic_cast(&child); if (item && !desktop->isLayer(item) && (!onlysensitive || !item->isLocked()) && (!onlyvisible || !desktop->itemIsHidden(item)) && - (exclude.empty() || exclude.end() == std::find(exclude.begin(),exclude.end(),child)) + (exclude.empty() || exclude.end() == std::find(exclude.begin(), exclude.end(), &child)) ) { list.insert(list.begin(),item); } if (ingroups || (item && desktop->isLayer(item))) { - list = get_all_items(list, child, desktop, onlyvisible, onlysensitive, ingroups, exclude); + list = get_all_items(list, &child, desktop, onlyvisible, onlysensitive, ingroups, exclude); } } @@ -1200,9 +1201,10 @@ take_style_from_item(SPObject *object) (dynamic_cast(object) && object->children && object->children->next == NULL)) { // if this is a text with exactly one tspan child, merge the style of that tspan as well // If this is a group, merge the style of its topmost (last) child with style - for (SPObject *last_element = object->lastChild(); last_element != NULL; last_element = last_element->getPrev()) { - if ( last_element->style ) { - SPCSSAttr *temp = sp_css_attr_from_object(last_element, SP_STYLE_FLAG_IFSET); + auto list = object->_children | boost::adaptors::reversed; + for (auto& element: list) { + if (element.style ) { + SPCSSAttr *temp = sp_css_attr_from_object(&element, SP_STYLE_FLAG_IFSET); if (temp) { sp_repr_css_merge(css, temp); sp_repr_css_attr_unref(temp); @@ -1621,10 +1623,10 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons } else if (transform_flowtext_with_frame) { // apply the inverse of the region's transform to the so that the flow remains // the same (even though the output itself gets transformed) - for ( SPObject *region = item->firstChild() ; region ; region = region->getNext() ) { - if (dynamic_cast(region) || dynamic_cast(region)) { - for ( SPObject *item = region->firstChild() ; item ; item = item->getNext() ) { - SPUse *use = dynamic_cast(item); + for (auto& region: item->_children) { + if (dynamic_cast(®ion) || dynamic_cast(®ion)) { + for (auto& itm: region._children) { + SPUse *use = dynamic_cast(&itm); if ( use ) { use->doWriteTransform(use->getRepr(), use->transform.inverse(), NULL, compensate); } @@ -2702,8 +2704,9 @@ sp_selection_unlink(SPDesktop *desktop) // Get a copy of current selection. std::vector new_select; bool unlinked = false; - auto items= selection->items(); - for (auto i=boost::rbegin(items);i!=boost::rend(items);++i){ + std::vector items(selection->items().begin(), selection->items().end()); + + for (auto i=items.rbegin();i!=items.rend();++i){ SPItem *item = *i; if (dynamic_cast(item)) { @@ -3432,9 +3435,9 @@ void sp_selection_untile(SPDesktop *desktop) Geom::Affine pat_transform = basePat->getTransform(); pat_transform *= item->transform; - for (SPObject *child = pattern->firstChild() ; child != NULL; child = child->next ) { - if (dynamic_cast(child)) { - Inkscape::XML::Node *copy = child->getRepr()->duplicate(xml_doc); + for (auto& child: pattern->_children) { + if (dynamic_cast(&child)) { + Inkscape::XML::Node *copy = child.getRepr()->duplicate(xml_doc); SPItem *i = dynamic_cast(desktop->currentLayer()->appendChildRepr(copy)); // FIXME: relink clones to the new canvas objects @@ -4100,9 +4103,9 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) { for ( std::map::iterator it = referenced_objects.begin() ; it != referenced_objects.end() ; ++it) { SPObject *obj = (*it).first; // Group containing the clipped paths or masks GSList *items_to_move = NULL; - for ( SPObject *child = obj->firstChild() ; child; child = child->getNext() ) { + for (auto& child: obj->_children) { // Collect all clipped paths and masks within a single group - Inkscape::XML::Node *copy = child->getRepr()->duplicate(xml_doc); + Inkscape::XML::Node *copy = child.getRepr()->duplicate(xml_doc); if(copy->attribute("inkscape:original-d") && copy->attribute("inkscape:path-effect")) { copy->setAttribute("d", copy->attribute("inkscape:original-d")); -- cgit v1.2.3 From 9e210a6d1333c3366681547e3e81593ef69ff73e Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Thu, 14 Jul 2016 12:56:49 +0200 Subject: Last part of new SPObject children list (bzr r14954.1.20) --- src/selection-chemistry.cpp | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 55f4118b0..28bcadef5 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -1010,7 +1010,7 @@ sp_selection_raise(Inkscape::Selection *selection, SPDesktop *desktop) for (std::vector::const_iterator item=rev.begin();item!=rev.end();++item) { SPObject *child = *item; // for each selected object, find the next sibling - for (SPObject *newref = child->next; newref; newref = newref->next) { + for (SPObject *newref = child->getNext(); newref; newref = newref->getNext()) { // if the sibling is an item AND overlaps our selection, SPItem *newItem = dynamic_cast(newref); if (newItem) { @@ -1138,15 +1138,16 @@ void sp_selection_lower_to_bottom(Inkscape::Selection *selection, SPDesktop *des for (std::vector::const_reverse_iterator l=rl.rbegin();l!=rl.rend();++l) { gint minpos; - SPObject *pp, *pc; + SPObject *pp; Inkscape::XML::Node *repr = (*l); pp = document->getObjectByRepr(repr->parent()); minpos = 0; g_assert(dynamic_cast(pp)); - pc = pp->firstChild(); - while (!dynamic_cast(pc)) { + for (auto& pc: pp->_children) { + if(dynamic_cast(&pc)) { + break; + } minpos += 1; - pc = pc->next; } repr->setPosition(minpos); } @@ -1197,8 +1198,8 @@ take_style_from_item(SPObject *object) if (css == NULL) return NULL; - if ((dynamic_cast(object) && object->children) || - (dynamic_cast(object) && object->children && object->children->next == NULL)) { + if ((dynamic_cast(object) && object->firstChild()) || + (dynamic_cast(object) && object->firstChild() && object->firstChild()->getNext() == NULL)) { // if this is a text with exactly one tspan child, merge the style of that tspan as well // If this is a group, merge the style of its topmost (last) child with style auto list = object->_children | boost::adaptors::reversed; @@ -2330,10 +2331,10 @@ typedef struct ListReverse { typedef GSList *Iterator; static Iterator children(SPObject *o) { - return make_list(o->firstChild(), NULL); + return make_list(o, NULL); } static Iterator siblings_after(SPObject *o) { - return make_list(o->parent->firstChild(), o); + return make_list(o->parent, o); } static void dispose(Iterator i) { g_slist_free(i); @@ -2347,13 +2348,12 @@ typedef struct ListReverse { private: static GSList *make_list(SPObject *object, SPObject *limit) { GSList *list = NULL; - while ( object != limit ) { - if (!object) { // TODO check if this happens in practice - g_warning("Unexpected list overrun"); + for (auto &child: object->_children) { + if (&child == limit) { break; } - list = g_slist_prepend(list, object); - object = object->getNext(); + list = g_slist_prepend(list, &child); + } return list; } -- cgit v1.2.3 From 24d3f50003ca3cec6a03a7f5267cc4fe5588c69f Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Thu, 14 Jul 2016 13:17:21 +0200 Subject: Renamed children list in SPObject (bzr r14954.1.21) --- src/selection-chemistry.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 28bcadef5..81d711e77 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -433,7 +433,7 @@ static void add_ids_recursive(std::vector &ids, SPObject *obj) ids.push_back(obj->getId()); if (dynamic_cast(obj)) { - for (auto& child: obj->_children) { + for (auto& child: obj->children) { add_ids_recursive(ids, &child); } } @@ -587,7 +587,7 @@ void sp_edit_clear_all(Inkscape::Selection *selection) */ std::vector &get_all_items(std::vector &list, SPObject *from, SPDesktop *desktop, bool onlyvisible, bool onlysensitive, bool ingroups, std::vector const &exclude) { - for (auto& child: from->_children) { + for (auto& child: from->children) { SPItem *item = dynamic_cast(&child); if (item && !desktop->isLayer(item) && @@ -1143,7 +1143,7 @@ void sp_selection_lower_to_bottom(Inkscape::Selection *selection, SPDesktop *des pp = document->getObjectByRepr(repr->parent()); minpos = 0; g_assert(dynamic_cast(pp)); - for (auto& pc: pp->_children) { + for (auto& pc: pp->children) { if(dynamic_cast(&pc)) { break; } @@ -1202,7 +1202,7 @@ take_style_from_item(SPObject *object) (dynamic_cast(object) && object->firstChild() && object->firstChild()->getNext() == NULL)) { // if this is a text with exactly one tspan child, merge the style of that tspan as well // If this is a group, merge the style of its topmost (last) child with style - auto list = object->_children | boost::adaptors::reversed; + auto list = object->children | boost::adaptors::reversed; for (auto& element: list) { if (element.style ) { SPCSSAttr *temp = sp_css_attr_from_object(&element, SP_STYLE_FLAG_IFSET); @@ -1624,9 +1624,9 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons } else if (transform_flowtext_with_frame) { // apply the inverse of the region's transform to the so that the flow remains // the same (even though the output itself gets transformed) - for (auto& region: item->_children) { + for (auto& region: item->children) { if (dynamic_cast(®ion) || dynamic_cast(®ion)) { - for (auto& itm: region._children) { + for (auto& itm: region.children) { SPUse *use = dynamic_cast(&itm); if ( use ) { use->doWriteTransform(use->getRepr(), use->transform.inverse(), NULL, compensate); @@ -2348,7 +2348,7 @@ typedef struct ListReverse { private: static GSList *make_list(SPObject *object, SPObject *limit) { GSList *list = NULL; - for (auto &child: object->_children) { + for (auto &child: object->children) { if (&child == limit) { break; } @@ -3435,7 +3435,7 @@ void sp_selection_untile(SPDesktop *desktop) Geom::Affine pat_transform = basePat->getTransform(); pat_transform *= item->transform; - for (auto& child: pattern->_children) { + for (auto& child: pattern->children) { if (dynamic_cast(&child)) { Inkscape::XML::Node *copy = child.getRepr()->duplicate(xml_doc); SPItem *i = dynamic_cast(desktop->currentLayer()->appendChildRepr(copy)); @@ -4103,7 +4103,7 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) { for ( std::map::iterator it = referenced_objects.begin() ; it != referenced_objects.end() ; ++it) { SPObject *obj = (*it).first; // Group containing the clipped paths or masks GSList *items_to_move = NULL; - for (auto& child: obj->_children) { + for (auto& child: obj->children) { // Collect all clipped paths and masks within a single group Inkscape::XML::Node *copy = child.getRepr()->duplicate(xml_doc); if(copy->attribute("inkscape:original-d") && copy->attribute("inkscape:path-effect")) @@ -4264,7 +4264,7 @@ static void itemtree_map(void (*f)(SPItem *, SPDesktop *), SPObject *root, SPDes f(item, desktop); } } - for (auto& child: root->_children) { + for (auto& child: root->children) { //don't recurse into locked layers SPItem *item = dynamic_cast(&child); if (!(item && desktop->isLayer(item) && item->isLocked())) { -- cgit v1.2.3 From 3c593bb8da3357514ff5b4f3154d08c4508ad47e Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Wed, 20 Jul 2016 11:01:17 +0200 Subject: Changed arguments and names of selection chemistry functions (bzr r14954.1.22) --- src/selection-chemistry.cpp | 289 ++++++++++++++++++++++---------------------- 1 file changed, 145 insertions(+), 144 deletions(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 81d711e77..e8c408ed8 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -12,8 +12,9 @@ * Abhishek Sharma * Kris De Gussem * Tavmjong Bah (Symbol additions) + * Adrian Boguszewski * - * Copyright (C) 1999-2010,2012 authors + * Copyright (C) 1999-2016 authors * Copyright (C) 2001-2002 Ximian, Inc. * * Released under GNU GPL, read the file 'COPYING' for more information @@ -109,6 +110,7 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "live_effects/effect-enum.h" #include "live_effects/parameter/originalpath.h" #include "layer-manager.h" +#include "object-set.h" #include "enums.h" #include "sp-item-group.h" @@ -124,6 +126,7 @@ using Inkscape::DocumentUndo; using Geom::X; using Geom::Y; using Inkscape::UI::Tools::NodeTool; +using namespace Inkscape; /* The clipboard handling is in ui/clipboard.cpp now. There are some legacy functions left here, because the layer manipulation code uses them. It should be rewritten specifically @@ -691,9 +694,13 @@ void sp_edit_invert_in_all_layers(SPDesktop *desktop) sp_edit_select_all_full(desktop, true, true); } -static void sp_selection_group_impl(std::vector p, Inkscape::XML::Node *group, Inkscape::XML::Document *xml_doc, SPDocument *doc) { +static Inkscape::XML::Node* sp_selection_group(ObjectSet *set) { + SPDocument *doc = set->desktop()->getDocument(); + Inkscape::XML::Document *xml_doc = doc->getReprDoc(); + Inkscape::XML::Node *group = xml_doc->createElement("svg:g"); - sort(p.begin(),p.end(),sp_repr_compare_position_bool); + std::vector p(set->xmlNodes().begin(), set->xmlNodes().end()); + std::sort(p.begin(), p.end(), sp_repr_compare_position_bool); // Remember the position and parent of the topmost object. gint topmost = p.back()->position(); @@ -751,31 +758,24 @@ static void sp_selection_group_impl(std::vector p, Inkscap // Move to the position of the topmost, reduced by the number of items deleted from topmost_parent group->setPosition(topmost + 1); + + set->set(doc->getObjectByRepr(group)); + + return group; } -void sp_selection_group(Inkscape::Selection *selection, SPDesktop *desktop) +void sp_selection_group_ui(Inkscape::Selection *selection, SPDesktop *desktop) { - SPDocument *doc = selection->layers()->getDocument(); - Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - // Check if something is selected. if (selection->isEmpty()) { selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select some objects to group.")); return; } + Inkscape::XML::Node* group = sp_selection_group(selection); - std::vector p (selection->xmlNodes().begin(), selection->xmlNodes().end()); - - selection->clear(); - - Inkscape::XML::Node *group = xml_doc->createElement("svg:g"); - - sp_selection_group_impl(p, group, xml_doc, doc); - - DocumentUndo::done(doc, SP_VERB_SELECTION_GROUP, + DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_GROUP, C_("Verb", "Group")); - selection->set(group); Inkscape::GC::release(group); } @@ -823,32 +823,16 @@ void sp_selection_ungroup_pop_selection(Inkscape::Selection *selection, SPDeskto } - -void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop) +static void sp_selection_ungroup(ObjectSet *set) { - if (selection->isEmpty()) { - selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select a group to ungroup.")); - } - - // first check whether there is anything to ungroup - auto old_select = selection->items(); - std::vector new_select; GSList *groups = NULL; - for (auto item = old_select.begin(); item!=old_select.end(); ++item) { - SPItem *obj = *item; - if (dynamic_cast(obj)) { - groups = g_slist_prepend(groups, obj); - } - } - - if (groups == NULL) { - selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("No groups to ungroup in the selection.")); - g_slist_free(groups); - return; + for (auto g: set->groups()) { + groups = g_slist_prepend(groups, g); } + std::vector new_select; + auto old_select = set->items(); std::vector items(old_select.begin(), old_select.end()); - selection->clear(); // If any of the clones refer to the groups, unlink them and replace them with successors // in the items list. @@ -895,7 +879,21 @@ void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop) } } - selection->addList(new_select); + set->setList(new_select); +} + +void sp_selection_ungroup_ui(Inkscape::Selection *selection, SPDesktop *desktop) +{ + if (selection->isEmpty()) { + selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select a group to ungroup.")); + } + + if (boost::distance(selection->groups()) == 0) { + selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("No groups to ungroup in the selection.")); + return; + } + + sp_selection_ungroup(selection); DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_UNGROUP, _("Ungroup")); @@ -931,18 +929,18 @@ sp_degroup_list(std::vector &items) /** If items in the list have a common parent, return it, otherwise return NULL */ static SPGroup * -sp_item_list_common_parent_group(std::vector const &items) +sp_item_list_common_parent_group(const SPItemRange &items) { if (items.empty()) { return NULL; } - SPObject *parent = items[0]->parent; + SPObject *parent = items.front()->parent; // Strictly speaking this CAN happen, if user selects from Inkscape::XML editor if (!dynamic_cast(parent)) { return NULL; } - for (std::vector::const_iterator item=items.begin();item!=items.end();++item) { - if((*item)==items[0])continue; + for (auto item=items.begin();item!=items.end();++item) { + if((*item)==items.front())continue; if ((*item)->parent != parent) { return NULL; } @@ -980,23 +978,9 @@ bool sp_item_repr_compare_position_bool(SPObject const *first, SPObject const *s ((SPItem*)second)->getRepr())<0; } -void -sp_selection_raise(Inkscape::Selection *selection, SPDesktop *desktop) -{ - std::vector items(selection->items().begin(), selection->items().end()); - - if (items.empty()) { - selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select object(s) to raise.")); - return; - } - - SPGroup const *group = sp_item_list_common_parent_group(items); - if (!group) { - selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); - return; - } - - Inkscape::XML::Node *grepr = const_cast(group->getRepr()); +void sp_selection_raise(ObjectSet* set) { + std::vector items(set->items().begin(), set->items().end()); + Inkscape::XML::Node *grepr = const_cast(items.front()->parent->getRepr()); /* Construct reverse-ordered list of selected children. */ std::vector rev(items); @@ -1027,55 +1011,61 @@ sp_selection_raise(Inkscape::Selection *selection, SPDesktop *desktop) } } } - DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_RAISE, - //TRANSLATORS: "Raise" means "to raise an object" in the undo history - C_("Undo action", "Raise")); } -void sp_selection_raise_to_top(Inkscape::Selection *selection, SPDesktop *desktop) +void sp_selection_raise_ui(Inkscape::Selection *selection, SPDesktop *desktop) { - SPDocument *document = selection->layers()->getDocument(); - - if (selection->isEmpty()) { - selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select object(s) to raise to top.")); + if (selection->items().empty()) { + selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select object(s) to raise.")); return; } - std::vector items(selection->items().begin(), selection->items().end()); - - SPGroup const *group = sp_item_list_common_parent_group(items); + SPGroup const *group = sp_item_list_common_parent_group(selection->items()); if (!group) { selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); return; } + sp_selection_raise(selection); + + DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_RAISE, + //TRANSLATORS: "Raise" means "to raise an object" in the undo history + C_("Undo action", "Raise")); +} - std::vector rl(selection->xmlNodes().begin(), selection->xmlNodes().end()); +void sp_selection_raise_to_top(ObjectSet* set) { + std::vector rl(set->xmlNodes().begin(), set->xmlNodes().end()); sort(rl.begin(),rl.end(),sp_repr_compare_position_bool); for (std::vector::const_iterator l=rl.begin(); l!=rl.end();++l) { Inkscape::XML::Node *repr =(*l); repr->setPosition(-1); } - - DocumentUndo::done(document, SP_VERB_SELECTION_TO_FRONT, - _("Raise to top")); } -void sp_selection_lower(Inkscape::Selection *selection, SPDesktop *desktop) +void sp_selection_raise_to_top_ui(Inkscape::Selection *selection, SPDesktop *desktop) { - std::vector items(selection->items().begin(), selection->items().end()); - if (items.empty()) { - selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select object(s) to lower.")); + SPDocument *document = selection->layers()->getDocument(); + + if (selection->isEmpty()) { + selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select object(s) to raise to top.")); return; } - SPGroup const *group = sp_item_list_common_parent_group(items); + SPGroup const *group = sp_item_list_common_parent_group(selection->items()); if (!group) { selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); return; } - Inkscape::XML::Node *grepr = const_cast(group->getRepr()); + sp_selection_raise_to_top(selection); + + DocumentUndo::done(document, SP_VERB_SELECTION_TO_FRONT, + _("Raise to top")); +} + +void sp_selection_lower(ObjectSet *set) { + std::vector items(set->items().begin(), set->items().end()); + Inkscape::XML::Node *grepr = const_cast(items.front()->parent->getRepr()); // Determine the common bbox of the selected items. Geom::OptRect selected = enclose_items(items); @@ -1110,37 +1100,37 @@ void sp_selection_lower(Inkscape::Selection *selection, SPDesktop *desktop) } } } - - DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_LOWER, - //TRANSLATORS: "Lower" means "to lower an object" in the undo history - C_("Undo action", "Lower")); } -void sp_selection_lower_to_bottom(Inkscape::Selection *selection, SPDesktop *desktop) +void sp_selection_lower_ui(Inkscape::Selection *selection, SPDesktop *desktop) { - SPDocument *document = selection->layers()->getDocument(); - - if (selection->isEmpty()) { - selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select object(s) to lower to bottom.")); + if (selection->items().empty()) { + selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select object(s) to lower.")); return; } - std::vector items(selection->items().begin(), selection->items().end()); - - SPGroup const *group = sp_item_list_common_parent_group(items); + SPGroup const *group = sp_item_list_common_parent_group(selection->items()); if (!group) { selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); return; } - std::vector rl(selection->xmlNodes().begin(), selection->xmlNodes().end()); + sp_selection_lower(selection); + + DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_LOWER, + //TRANSLATORS: "Lower" means "to lower an object" in the undo history + C_("Undo action", "Lower")); +} + +void sp_selection_lower_to_bottom(ObjectSet *set) { + std::vector rl(set->xmlNodes().begin(), set->xmlNodes().end()); sort(rl.begin(),rl.end(),sp_repr_compare_position_bool); for (std::vector::const_reverse_iterator l=rl.rbegin();l!=rl.rend();++l) { gint minpos; SPObject *pp; Inkscape::XML::Node *repr = (*l); - pp = document->getObjectByRepr(repr->parent()); + pp = set->desktop()->getDocument()->getObjectByRepr(repr->parent()); minpos = 0; g_assert(dynamic_cast(pp)); for (auto& pc: pp->children) { @@ -1151,8 +1141,24 @@ void sp_selection_lower_to_bottom(Inkscape::Selection *selection, SPDesktop *des } repr->setPosition(minpos); } +} + +void sp_selection_lower_to_bottom_ui(Inkscape::Selection *selection, SPDesktop *desktop) +{ + if (selection->isEmpty()) { + selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select object(s) to lower to bottom.")); + return; + } + + SPGroup const *group = sp_item_list_common_parent_group(selection->items()); + if (!group) { + selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); + return; + } + + sp_selection_lower_to_bottom(selection); - DocumentUndo::done(document, SP_VERB_SELECTION_TO_BACK, + DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_TO_BACK, _("Lower to bottom")); } @@ -1478,7 +1484,7 @@ void sp_selection_to_layer(SPDesktop *dt, SPObject *moveto, bool suppressDone) } static bool -selection_contains_original(SPItem *item, Inkscape::Selection *selection) +selection_contains_original(SPItem *item, ObjectSet* set) { bool contains_original = false; @@ -1489,7 +1495,7 @@ selection_contains_original(SPItem *item, Inkscape::Selection *selection) { item_use = use->get_original(); use = dynamic_cast(item_use); - contains_original |= selection->includes(item_use); + contains_original |= set->includes(item_use); if (item_use == item_use_first) break; } @@ -1498,7 +1504,7 @@ selection_contains_original(SPItem *item, Inkscape::Selection *selection) // data is part of the selection SPTRef *tref = dynamic_cast(item); if (!contains_original && tref) { - contains_original = selection->includes(tref->getObjectReferredTo()); + contains_original = set->includes(tref->getObjectReferredTo()); } return contains_original; @@ -1506,14 +1512,14 @@ selection_contains_original(SPItem *item, Inkscape::Selection *selection) static bool -selection_contains_both_clone_and_original(Inkscape::Selection *selection) +selection_contains_both_clone_and_original(ObjectSet *set) { bool clone_with_original = false; - auto items = selection->items(); + auto items = set->items(); for (auto l=items.begin();l!=items.end() ;++l) { SPItem *item = *l; if (item) { - clone_with_original |= selection_contains_original(item, selection); + clone_with_original |= selection_contains_original(item, set); if (clone_with_original) break; } @@ -1527,21 +1533,21 @@ value of set_i2d==false is only used by seltrans when it's dragging objects live that case, items are already in the new position, but the repr is in the old, and this function then simply updates the repr from item->transform. */ -void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine const &affine, bool set_i2d, bool compensate, bool adjust_transf_center) +void sp_selection_apply_affine(ObjectSet *set, Geom::Affine const &affine, bool set_i2d, bool compensate, bool adjust_transf_center) { - if (selection->isEmpty()) + if (set->isEmpty()) return; // For each perspective with a box in selection, check whether all boxes are selected and // unlink all non-selected boxes. Persp3D *persp; Persp3D *transf_persp; - std::list plist = selection->perspList(); + std::list plist = set->perspList(); for (std::list::iterator i = plist.begin(); i != plist.end(); ++i) { persp = (Persp3D *) (*i); - if (!persp3d_has_all_boxes_in_selection (persp, selection)) { - std::list selboxes = selection->box3DList(persp); + if (!persp3d_has_all_boxes_in_selection (persp, set)) { + std::list selboxes = set->box3DList(persp); // create a new perspective as a copy of the current one and link the selected boxes to it transf_persp = persp3d_create_xml_element (persp->document, persp->perspective_impl); @@ -1554,14 +1560,14 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons persp3d_apply_affine_transformation(transf_persp, affine); } - auto items = selection->items(); + auto items = set->items(); for (auto l=items.begin();l!=items.end() ;++l) { SPItem *item = *l; if( dynamic_cast(item) ) { // An SVG element cannot have a transform. We could change 'x' and 'y' in response // to a translation... but leave that for another day. - selection->desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Cannot transform an embedded SVG.")); + set->desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Cannot transform an embedded SVG.")); break; } @@ -1575,17 +1581,17 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons #endif // we're moving both a clone and its original or any ancestor in clone chain? - bool transform_clone_with_original = selection_contains_original(item, selection); + bool transform_clone_with_original = selection_contains_original(item, set); // ...both a text-on-path and its path? bool transform_textpath_with_path = ((dynamic_cast(item) && item->firstChild() && dynamic_cast(item->firstChild())) - && selection->includes( sp_textpath_get_path_item(dynamic_cast(item->firstChild())) )); + && set->includes( sp_textpath_get_path_item(dynamic_cast(item->firstChild())) )); // ...both a flowtext and its frame? - bool transform_flowtext_with_frame = (dynamic_cast(item) && selection->includes( dynamic_cast(item)->get_frame(NULL))); // (only the first frame is checked so far) + bool transform_flowtext_with_frame = (dynamic_cast(item) && set->includes( dynamic_cast(item)->get_frame(NULL))); // (only the first frame is checked so far) // ...both an offset and its source? - bool transform_offset_with_source = (dynamic_cast(item) && dynamic_cast(item)->sourceHref) && selection->includes( sp_offset_get_source(dynamic_cast(item)) ); + bool transform_offset_with_source = (dynamic_cast(item) && dynamic_cast(item)->sourceHref) && set->includes( sp_offset_get_source(dynamic_cast(item)) ); // If we're moving a connector, we want to detach it // from shapes that aren't part of the selection, but @@ -1596,7 +1602,7 @@ void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine cons SPItem *attItem[2] = {0, 0}; path->connEndPair.getAttachedItems(attItem); for (int n = 0; n < 2; ++n) { - if (!selection->includes(attItem[n])) { + if (!set->includes(attItem[n])) { sp_conn_end_detach(item, n); } } @@ -1735,14 +1741,14 @@ void sp_selection_remove_transform(SPDesktop *desktop) } void -sp_selection_scale_absolute(Inkscape::Selection *selection, +sp_selection_scale_absolute(ObjectSet *set, double const x0, double const x1, double const y0, double const y1) { - if (selection->isEmpty()) + if (set->isEmpty()) return; - Geom::OptRect bbox = selection->visualBounds(); + Geom::OptRect bbox = set->visualBounds(); if ( !bbox ) { return; } @@ -1755,16 +1761,16 @@ sp_selection_scale_absolute(Inkscape::Selection *selection, Geom::Translate const o2n(x0, y0); Geom::Affine const final( p2o * scale * o2n ); - sp_selection_apply_affine(selection, final); + sp_selection_apply_affine(set, final); } -void sp_selection_scale_relative(Inkscape::Selection *selection, Geom::Point const &align, Geom::Scale const &scale) +void sp_selection_scale_relative(ObjectSet *set, Geom::Point const &align, Geom::Scale const &scale) { - if (selection->isEmpty()) + if (set->isEmpty()) return; - Geom::OptRect bbox = selection->visualBounds(); + Geom::OptRect bbox = set->visualBounds(); if ( !bbox ) { return; @@ -1780,21 +1786,21 @@ void sp_selection_scale_relative(Inkscape::Selection *selection, Geom::Point con Geom::Translate const n2d(-align); Geom::Translate const d2n(align); Geom::Affine const final( n2d * scale * d2n ); - sp_selection_apply_affine(selection, final); + sp_selection_apply_affine(set, final); } void -sp_selection_rotate_relative(Inkscape::Selection *selection, Geom::Point const ¢er, gdouble const angle_degrees) +sp_selection_rotate_relative(ObjectSet *set, Geom::Point const ¢er, gdouble const angle_degrees) { Geom::Translate const d2n(center); Geom::Translate const n2d(-center); Geom::Rotate const rotate(Geom::Rotate::from_degrees(angle_degrees)); Geom::Affine const final( Geom::Affine(n2d) * rotate * d2n ); - sp_selection_apply_affine(selection, final); + sp_selection_apply_affine(set, final); } void -sp_selection_skew_relative(Inkscape::Selection *selection, Geom::Point const &align, double dx, double dy) +sp_selection_skew_relative(ObjectSet *set, Geom::Point const &align, double dx, double dy) { Geom::Translate const d2n(align); Geom::Translate const n2d(-align); @@ -1802,17 +1808,17 @@ sp_selection_skew_relative(Inkscape::Selection *selection, Geom::Point const &al dx, 1, 0, 0); Geom::Affine const final( n2d * skew * d2n ); - sp_selection_apply_affine(selection, final); + sp_selection_apply_affine(set, final); } -void sp_selection_move_relative(Inkscape::Selection *selection, Geom::Point const &move, bool compensate) +void sp_selection_move_relative(ObjectSet *set, Geom::Point const &move, bool compensate) { - sp_selection_apply_affine(selection, Geom::Affine(Geom::Translate(move)), true, compensate); + sp_selection_apply_affine(set, Geom::Affine(Geom::Translate(move)), true, compensate); } -void sp_selection_move_relative(Inkscape::Selection *selection, double dx, double dy) +void sp_selection_move_relative(ObjectSet *set, double dx, double dy) { - sp_selection_apply_affine(selection, Geom::Affine(Geom::Translate(dx, dy))); + sp_selection_apply_affine(set, Geom::Affine(Geom::Translate(dx, dy))); } /** @@ -2244,8 +2250,7 @@ sp_selection_scale(Inkscape::Selection *selection, gdouble grow) void sp_selection_scale_screen(Inkscape::Selection *selection, gdouble grow_pixels) { - sp_selection_scale(selection, - grow_pixels / selection->desktop()->current_zoom()); + sp_selection_scale(selection, grow_pixels / selection->desktop()->current_zoom()); } void @@ -3471,13 +3476,13 @@ void sp_selection_untile(SPDesktop *desktop) } } -void sp_selection_get_export_hints(Inkscape::Selection *selection, Glib::ustring &filename, float *xdpi, float *ydpi) +void sp_selection_get_export_hints(ObjectSet *set, Glib::ustring &filename, float *xdpi, float *ydpi) { - if (selection->isEmpty()) { + if (set->isEmpty()) { return; } - auto reprlst = selection->xmlNodes(); + auto reprlst = set->xmlNodes(); bool filename_search = TRUE; bool xdpi_search = TRUE; bool ydpi_search = TRUE; @@ -3947,18 +3952,13 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ if (grouping == PREFS_MASKOBJECT_GROUPING_ALL) { // group all those objects into one group // and apply mask to that - Inkscape::XML::Node *group = xml_doc->createElement("svg:g"); + ObjectSet* set = new ObjectSet(selection->desktop()); + set->add(apply_to_items.begin(), apply_to_items.end()); - // make a note we should ungroup this when unsetting mask - group->setAttribute("inkscape:groupmode", "maskhelper"); - - std::vector reprs_to_group; - for (std::vector::const_iterator i = apply_to_items.begin(); i != apply_to_items.end(); ++i) { - reprs_to_group.push_back(static_cast(*i)->getRepr()); - } items_to_select.clear(); - sp_selection_group_impl(reprs_to_group, group, xml_doc, doc); + Inkscape::XML::Node *group = sp_selection_group(set); + group->setAttribute("inkscape:groupmode", "maskhelper"); // apply clip/mask only to newly created group apply_to_items.clear(); @@ -3966,6 +3966,7 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ items_to_select.push_back((SPItem*)(doc->getObjectByRepr(group))); + delete set; Inkscape::GC::release(group); } if (grouping == PREFS_MASKOBJECT_GROUPING_SEPARATE) { -- cgit v1.2.3 From ff4fbbc93f67afd6cbf851691833a50d6c76b350 Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Wed, 27 Jul 2016 12:19:03 +0200 Subject: Renamed some functions, fixed tests (bzr r14954.1.28) --- src/selection-chemistry.cpp | 97 +++++++++++++++++++++++---------------------- 1 file changed, 49 insertions(+), 48 deletions(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index e8c408ed8..cd0a29b05 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -694,7 +694,7 @@ void sp_edit_invert_in_all_layers(SPDesktop *desktop) sp_edit_select_all_full(desktop, true, true); } -static Inkscape::XML::Node* sp_selection_group(ObjectSet *set) { +static Inkscape::XML::Node* sp_object_set_group(ObjectSet *set) { SPDocument *doc = set->desktop()->getDocument(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); Inkscape::XML::Node *group = xml_doc->createElement("svg:g"); @@ -764,14 +764,14 @@ static Inkscape::XML::Node* sp_selection_group(ObjectSet *set) { return group; } -void sp_selection_group_ui(Inkscape::Selection *selection, SPDesktop *desktop) +void sp_selection_group(Inkscape::Selection *selection, SPDesktop *desktop) { // Check if something is selected. if (selection->isEmpty()) { selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select some objects to group.")); return; } - Inkscape::XML::Node* group = sp_selection_group(selection); + Inkscape::XML::Node* group = sp_object_set_group(selection); DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_GROUP, C_("Verb", "Group")); @@ -823,7 +823,7 @@ void sp_selection_ungroup_pop_selection(Inkscape::Selection *selection, SPDeskto } -static void sp_selection_ungroup(ObjectSet *set) +static void sp_object_set_ungroup(ObjectSet *set) { GSList *groups = NULL; for (auto g: set->groups()) { @@ -882,7 +882,7 @@ static void sp_selection_ungroup(ObjectSet *set) set->setList(new_select); } -void sp_selection_ungroup_ui(Inkscape::Selection *selection, SPDesktop *desktop) +void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop) { if (selection->isEmpty()) { selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select a group to ungroup.")); @@ -893,7 +893,7 @@ void sp_selection_ungroup_ui(Inkscape::Selection *selection, SPDesktop *desktop) return; } - sp_selection_ungroup(selection); + sp_object_set_ungroup(selection); DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_UNGROUP, _("Ungroup")); @@ -978,7 +978,7 @@ bool sp_item_repr_compare_position_bool(SPObject const *first, SPObject const *s ((SPItem*)second)->getRepr())<0; } -void sp_selection_raise(ObjectSet* set) { +void sp_object_set_raise(ObjectSet *set) { std::vector items(set->items().begin(), set->items().end()); Inkscape::XML::Node *grepr = const_cast(items.front()->parent->getRepr()); @@ -1013,7 +1013,7 @@ void sp_selection_raise(ObjectSet* set) { } } -void sp_selection_raise_ui(Inkscape::Selection *selection, SPDesktop *desktop) +void sp_selection_raise(Inkscape::Selection *selection, SPDesktop *desktop) { if (selection->items().empty()) { selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select object(s) to raise.")); @@ -1025,14 +1025,14 @@ void sp_selection_raise_ui(Inkscape::Selection *selection, SPDesktop *desktop) selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); return; } - sp_selection_raise(selection); + sp_object_set_raise(selection); DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_RAISE, //TRANSLATORS: "Raise" means "to raise an object" in the undo history C_("Undo action", "Raise")); } -void sp_selection_raise_to_top(ObjectSet* set) { +void sp_object_set_raise_to_top(ObjectSet *set) { std::vector rl(set->xmlNodes().begin(), set->xmlNodes().end()); sort(rl.begin(),rl.end(),sp_repr_compare_position_bool); @@ -1042,7 +1042,7 @@ void sp_selection_raise_to_top(ObjectSet* set) { } } -void sp_selection_raise_to_top_ui(Inkscape::Selection *selection, SPDesktop *desktop) +void sp_selection_raise_to_top(Inkscape::Selection *selection, SPDesktop *desktop) { SPDocument *document = selection->layers()->getDocument(); @@ -1057,13 +1057,13 @@ void sp_selection_raise_to_top_ui(Inkscape::Selection *selection, SPDesktop *des return; } - sp_selection_raise_to_top(selection); + sp_object_set_raise_to_top(selection); DocumentUndo::done(document, SP_VERB_SELECTION_TO_FRONT, _("Raise to top")); } -void sp_selection_lower(ObjectSet *set) { +void sp_object_set_lower(ObjectSet *set) { std::vector items(set->items().begin(), set->items().end()); Inkscape::XML::Node *grepr = const_cast(items.front()->parent->getRepr()); @@ -1102,7 +1102,7 @@ void sp_selection_lower(ObjectSet *set) { } } -void sp_selection_lower_ui(Inkscape::Selection *selection, SPDesktop *desktop) +void sp_selection_lower(Inkscape::Selection *selection, SPDesktop *desktop) { if (selection->items().empty()) { selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select object(s) to lower.")); @@ -1115,14 +1115,14 @@ void sp_selection_lower_ui(Inkscape::Selection *selection, SPDesktop *desktop) return; } - sp_selection_lower(selection); + sp_object_set_lower(selection); DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_LOWER, //TRANSLATORS: "Lower" means "to lower an object" in the undo history C_("Undo action", "Lower")); } -void sp_selection_lower_to_bottom(ObjectSet *set) { +void sp_object_set_lower_to_bottom(ObjectSet *set) { std::vector rl(set->xmlNodes().begin(), set->xmlNodes().end()); sort(rl.begin(),rl.end(),sp_repr_compare_position_bool); @@ -1143,7 +1143,7 @@ void sp_selection_lower_to_bottom(ObjectSet *set) { } } -void sp_selection_lower_to_bottom_ui(Inkscape::Selection *selection, SPDesktop *desktop) +void sp_selection_lower_to_bottom(Inkscape::Selection *selection, SPDesktop *desktop) { if (selection->isEmpty()) { selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select object(s) to lower to bottom.")); @@ -1156,7 +1156,7 @@ void sp_selection_lower_to_bottom_ui(Inkscape::Selection *selection, SPDesktop * return; } - sp_selection_lower_to_bottom(selection); + sp_object_set_lower_to_bottom(selection); DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_TO_BACK, _("Lower to bottom")); @@ -1484,7 +1484,7 @@ void sp_selection_to_layer(SPDesktop *dt, SPObject *moveto, bool suppressDone) } static bool -selection_contains_original(SPItem *item, ObjectSet* set) +object_set_contains_original(SPItem *item, ObjectSet *set) { bool contains_original = false; @@ -1512,14 +1512,14 @@ selection_contains_original(SPItem *item, ObjectSet* set) static bool -selection_contains_both_clone_and_original(ObjectSet *set) +object_set_contains_both_clone_and_original(ObjectSet *set) { bool clone_with_original = false; auto items = set->items(); for (auto l=items.begin();l!=items.end() ;++l) { SPItem *item = *l; if (item) { - clone_with_original |= selection_contains_original(item, set); + clone_with_original |= object_set_contains_original(item, set); if (clone_with_original) break; } @@ -1533,7 +1533,8 @@ value of set_i2d==false is only used by seltrans when it's dragging objects live that case, items are already in the new position, but the repr is in the old, and this function then simply updates the repr from item->transform. */ -void sp_selection_apply_affine(ObjectSet *set, Geom::Affine const &affine, bool set_i2d, bool compensate, bool adjust_transf_center) +void sp_object_set_apply_affine(ObjectSet *set, Geom::Affine const &affine, bool set_i2d, bool compensate, + bool adjust_transf_center) { if (set->isEmpty()) return; @@ -1581,7 +1582,7 @@ void sp_selection_apply_affine(ObjectSet *set, Geom::Affine const &affine, bool #endif // we're moving both a clone and its original or any ancestor in clone chain? - bool transform_clone_with_original = selection_contains_original(item, set); + bool transform_clone_with_original = object_set_contains_original(item, set); // ...both a text-on-path and its path? bool transform_textpath_with_path = ((dynamic_cast(item) && item->firstChild() && dynamic_cast(item->firstChild())) @@ -1724,7 +1725,7 @@ void sp_selection_apply_affine(ObjectSet *set, Geom::Affine const &affine, bool } } -void sp_selection_remove_transform(SPDesktop *desktop) +void sp_object_set_remove_transform(SPDesktop *desktop) { if (desktop == NULL) return; @@ -1741,9 +1742,9 @@ void sp_selection_remove_transform(SPDesktop *desktop) } void -sp_selection_scale_absolute(ObjectSet *set, - double const x0, double const x1, - double const y0, double const y1) +sp_object_set_scale_absolute(ObjectSet *set, + double x0, double x1, + double y0, double y1) { if (set->isEmpty()) return; @@ -1761,11 +1762,11 @@ sp_selection_scale_absolute(ObjectSet *set, Geom::Translate const o2n(x0, y0); Geom::Affine const final( p2o * scale * o2n ); - sp_selection_apply_affine(set, final); + sp_object_set_apply_affine(set, final); } -void sp_selection_scale_relative(ObjectSet *set, Geom::Point const &align, Geom::Scale const &scale) +void sp_object_set_scale_relative(ObjectSet *set, Geom::Point const &align, Geom::Scale const &scale) { if (set->isEmpty()) return; @@ -1786,21 +1787,21 @@ void sp_selection_scale_relative(ObjectSet *set, Geom::Point const &align, Geom: Geom::Translate const n2d(-align); Geom::Translate const d2n(align); Geom::Affine const final( n2d * scale * d2n ); - sp_selection_apply_affine(set, final); + sp_object_set_apply_affine(set, final); } void -sp_selection_rotate_relative(ObjectSet *set, Geom::Point const ¢er, gdouble const angle_degrees) +sp_object_set_rotate_relative(ObjectSet *set, Geom::Point const ¢er, double angle_degrees) { Geom::Translate const d2n(center); Geom::Translate const n2d(-center); Geom::Rotate const rotate(Geom::Rotate::from_degrees(angle_degrees)); Geom::Affine const final( Geom::Affine(n2d) * rotate * d2n ); - sp_selection_apply_affine(set, final); + sp_object_set_apply_affine(set, final); } void -sp_selection_skew_relative(ObjectSet *set, Geom::Point const &align, double dx, double dy) +sp_object_set_skew_relative(ObjectSet *set, Geom::Point const &align, double dx, double dy) { Geom::Translate const d2n(align); Geom::Translate const n2d(-align); @@ -1808,17 +1809,17 @@ sp_selection_skew_relative(ObjectSet *set, Geom::Point const &align, double dx, dx, 1, 0, 0); Geom::Affine const final( n2d * skew * d2n ); - sp_selection_apply_affine(set, final); + sp_object_set_apply_affine(set, final); } -void sp_selection_move_relative(ObjectSet *set, Geom::Point const &move, bool compensate) +void sp_object_set_move_relative(ObjectSet *set, Geom::Point const &move, bool compensate) { - sp_selection_apply_affine(set, Geom::Affine(Geom::Translate(move)), true, compensate); + sp_object_set_apply_affine(set, Geom::Affine(Geom::Translate(move)), true, compensate); } -void sp_selection_move_relative(ObjectSet *set, double dx, double dy) +void sp_object_set_move_relative(ObjectSet *set, double dx, double dy) { - sp_selection_apply_affine(set, Geom::Affine(Geom::Translate(dx, dy))); + sp_object_set_apply_affine(set, Geom::Affine(Geom::Translate(dx, dy))); } /** @@ -1858,7 +1859,7 @@ sp_selection_rotate(Inkscape::Selection *selection, gdouble const angle_degrees) return; } - sp_selection_rotate_relative(selection, *center, angle_degrees); + sp_object_set_rotate_relative(selection, *center, angle_degrees); DocumentUndo::maybeDone(selection->desktop()->getDocument(), ( ( angle_degrees > 0 ) @@ -2207,7 +2208,7 @@ sp_selection_rotate_screen(Inkscape::Selection *selection, gdouble angle) gdouble const zangle = 180 * atan2(zmove, r) / M_PI; - sp_selection_rotate_relative(selection, *center, zangle); + sp_object_set_rotate_relative(selection, *center, zangle); DocumentUndo::maybeDone(selection->desktop()->getDocument(), ( (angle > 0) @@ -2237,7 +2238,7 @@ sp_selection_scale(Inkscape::Selection *selection, gdouble grow) } double const times = 1.0 + grow / max_len; - sp_selection_scale_relative(selection, center, Geom::Scale(times, times)); + sp_object_set_scale_relative(selection, center, Geom::Scale(times, times)); DocumentUndo::maybeDone(selection->desktop()->getDocument(), ( (grow > 0) @@ -2266,7 +2267,7 @@ sp_selection_scale_times(Inkscape::Selection *selection, gdouble times) } Geom::Point const center(sel_bbox->midpoint()); - sp_selection_scale_relative(selection, center, Geom::Scale(times, times)); + sp_object_set_scale_relative(selection, center, Geom::Scale(times, times)); DocumentUndo::done(selection->desktop()->getDocument(), SP_VERB_CONTEXT_SELECT, _("Scale by whole factor")); } @@ -2278,7 +2279,7 @@ sp_selection_move(Inkscape::Selection *selection, gdouble dx, gdouble dy) return; } - sp_selection_move_relative(selection, dx, dy); + sp_object_set_move_relative(selection, dx, dy); SPDocument *doc = selection->layers()->getDocument(); if (dx == 0) { @@ -2304,7 +2305,7 @@ sp_selection_move_screen(Inkscape::Selection *selection, gdouble dx, gdouble dy) gdouble const zoom = selection->desktop()->current_zoom(); gdouble const zdx = dx / zoom; gdouble const zdy = dy / zoom; - sp_selection_move_relative(selection, zdx, zdy); + sp_object_set_move_relative(selection, zdx, zdy); SPDocument *doc = selection->layers()->getDocument(); if (dx == 0) { @@ -3476,7 +3477,7 @@ void sp_selection_untile(SPDesktop *desktop) } } -void sp_selection_get_export_hints(ObjectSet *set, Glib::ustring &filename, float *xdpi, float *ydpi) +void sp_object_set_get_export_hints(ObjectSet *set, Glib::ustring &filename, float *xdpi, float *ydpi) { if (set->isEmpty()) { return; @@ -3627,7 +3628,7 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop) float hint_xdpi = 0, hint_ydpi = 0; Glib::ustring hint_filename; // take resolution hint from the selected objects - sp_selection_get_export_hints(selection, hint_filename, &hint_xdpi, &hint_ydpi); + sp_object_set_get_export_hints(selection, hint_filename, &hint_xdpi, &hint_ydpi); if (hint_xdpi != 0) { res = hint_xdpi; } else { @@ -3892,7 +3893,7 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ // FIXME: temporary patch to prevent crash! // Remove this when bboxes are fixed to not blow up on an item clipped/masked with its own clone - bool clone_with_original = selection_contains_both_clone_and_original(selection); + bool clone_with_original = object_set_contains_both_clone_and_original(selection); if (clone_with_original) { return; // in this version, you cannot clip/mask an object with its own clone } @@ -3957,7 +3958,7 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ items_to_select.clear(); - Inkscape::XML::Node *group = sp_selection_group(set); + Inkscape::XML::Node *group = sp_object_set_group(set); group->setAttribute("inkscape:groupmode", "maskhelper"); // apply clip/mask only to newly created group -- cgit v1.2.3 From f35bb1f74a0ffeb5c6477a25e3c4cde87a97bcf1 Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Thu, 28 Jul 2016 12:06:06 +0200 Subject: Removed unused includes, decrease compilation time (bzr r15025) --- src/selection-chemistry.cpp | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 7d32477a1..f6923d1ea 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -20,7 +20,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include #endif #include @@ -34,7 +34,6 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "svg/svg.h" #include "desktop.h" #include "desktop-style.h" -#include "dir-util.h" #include "layer-model.h" #include "selection.h" #include "ui/tools-switch.h" @@ -42,7 +41,6 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "message-stack.h" #include "sp-item-transform.h" #include "sp-marker.h" -#include "sp-use.h" #include "sp-textpath.h" #include "sp-tspan.h" #include "sp-tref.h" @@ -53,7 +51,6 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "sp-ellipse.h" #include "sp-star.h" #include "sp-spiral.h" -#include "sp-switch.h" #include "sp-polyline.h" #include "sp-line.h" #include "text-editing.h" @@ -64,13 +61,10 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "sp-conn-end.h" #include "ui/tools/dropper-tool.h" #include -#include <2geom/transforms.h> -#include "xml/repr.h" #include "xml/rebase-hrefs.h" #include "style.h" #include "document-private.h" #include "document-undo.h" -#include "sp-gradient.h" #include "sp-gradient-reference.h" #include "sp-linear-gradient.h" #include "sp-pattern.h" @@ -78,42 +72,25 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "sp-radial-gradient.h" #include "ui/tools/gradient-tool.h" #include "sp-namedview.h" -#include "preferences.h" #include "sp-offset.h" #include "sp-clippath.h" #include "sp-mask.h" #include "helper/png-write.h" #include "layer-fns.h" #include "context-fns.h" -#include -#include -#include -#include "sp-item.h" #include "box3d.h" #include "persp3d.h" -#include "util/units.h" #include "xml/simple-document.h" -#include "sp-filter-reference.h" #include "gradient-drag.h" -#include "uri-references.h" -#include "display/curve.h" -#include "display/canvas-bpath.h" #include "display/cairo-utils.h" -#include "inkscape.h" #include "path-chemistry.h" #include "ui/tool/control-point-selection.h" #include "ui/tool/multi-path-manipulator.h" -#include "sp-lpe-item.h" #include "live_effects/effect.h" -#include "live_effects/effect-enum.h" #include "live_effects/parameter/originalpath.h" #include "layer-manager.h" -#include "enums.h" -#include "sp-item-group.h" - // For clippath editing -#include "ui/tools-switch.h" #include "ui/tools/node-tool.h" #include "ui/clipboard.h" -- cgit v1.2.3 From 43b49e325db73cc19b1731db6c69545664ee8fbe Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Thu, 28 Jul 2016 13:26:17 +0200 Subject: Reverted changes to r15024 after many building problems (bzr r15027) --- src/selection-chemistry.cpp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index f6923d1ea..7d32477a1 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -20,7 +20,7 @@ */ #ifdef HAVE_CONFIG_H -#include +# include "config.h" #endif #include @@ -34,6 +34,7 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "svg/svg.h" #include "desktop.h" #include "desktop-style.h" +#include "dir-util.h" #include "layer-model.h" #include "selection.h" #include "ui/tools-switch.h" @@ -41,6 +42,7 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "message-stack.h" #include "sp-item-transform.h" #include "sp-marker.h" +#include "sp-use.h" #include "sp-textpath.h" #include "sp-tspan.h" #include "sp-tref.h" @@ -51,6 +53,7 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "sp-ellipse.h" #include "sp-star.h" #include "sp-spiral.h" +#include "sp-switch.h" #include "sp-polyline.h" #include "sp-line.h" #include "text-editing.h" @@ -61,10 +64,13 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "sp-conn-end.h" #include "ui/tools/dropper-tool.h" #include +#include <2geom/transforms.h> +#include "xml/repr.h" #include "xml/rebase-hrefs.h" #include "style.h" #include "document-private.h" #include "document-undo.h" +#include "sp-gradient.h" #include "sp-gradient-reference.h" #include "sp-linear-gradient.h" #include "sp-pattern.h" @@ -72,25 +78,42 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "sp-radial-gradient.h" #include "ui/tools/gradient-tool.h" #include "sp-namedview.h" +#include "preferences.h" #include "sp-offset.h" #include "sp-clippath.h" #include "sp-mask.h" #include "helper/png-write.h" #include "layer-fns.h" #include "context-fns.h" +#include +#include +#include +#include "sp-item.h" #include "box3d.h" #include "persp3d.h" +#include "util/units.h" #include "xml/simple-document.h" +#include "sp-filter-reference.h" #include "gradient-drag.h" +#include "uri-references.h" +#include "display/curve.h" +#include "display/canvas-bpath.h" #include "display/cairo-utils.h" +#include "inkscape.h" #include "path-chemistry.h" #include "ui/tool/control-point-selection.h" #include "ui/tool/multi-path-manipulator.h" +#include "sp-lpe-item.h" #include "live_effects/effect.h" +#include "live_effects/effect-enum.h" #include "live_effects/parameter/originalpath.h" #include "layer-manager.h" +#include "enums.h" +#include "sp-item-group.h" + // For clippath editing +#include "ui/tools-switch.h" #include "ui/tools/node-tool.h" #include "ui/clipboard.h" -- cgit v1.2.3 From 35830f456cadaecf8b8e3944e3031a1a93f6cb41 Mon Sep 17 00:00:00 2001 From: Adrian Boguszewski Date: Wed, 3 Aug 2016 15:29:38 +0200 Subject: Removed unused includes, decreased compilation time. Once again (bzr r15034) --- src/selection-chemistry.cpp | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 7d32477a1..f6923d1ea 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -20,7 +20,7 @@ */ #ifdef HAVE_CONFIG_H -# include "config.h" +#include #endif #include @@ -34,7 +34,6 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "svg/svg.h" #include "desktop.h" #include "desktop-style.h" -#include "dir-util.h" #include "layer-model.h" #include "selection.h" #include "ui/tools-switch.h" @@ -42,7 +41,6 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "message-stack.h" #include "sp-item-transform.h" #include "sp-marker.h" -#include "sp-use.h" #include "sp-textpath.h" #include "sp-tspan.h" #include "sp-tref.h" @@ -53,7 +51,6 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "sp-ellipse.h" #include "sp-star.h" #include "sp-spiral.h" -#include "sp-switch.h" #include "sp-polyline.h" #include "sp-line.h" #include "text-editing.h" @@ -64,13 +61,10 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "sp-conn-end.h" #include "ui/tools/dropper-tool.h" #include -#include <2geom/transforms.h> -#include "xml/repr.h" #include "xml/rebase-hrefs.h" #include "style.h" #include "document-private.h" #include "document-undo.h" -#include "sp-gradient.h" #include "sp-gradient-reference.h" #include "sp-linear-gradient.h" #include "sp-pattern.h" @@ -78,42 +72,25 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "sp-radial-gradient.h" #include "ui/tools/gradient-tool.h" #include "sp-namedview.h" -#include "preferences.h" #include "sp-offset.h" #include "sp-clippath.h" #include "sp-mask.h" #include "helper/png-write.h" #include "layer-fns.h" #include "context-fns.h" -#include -#include -#include -#include "sp-item.h" #include "box3d.h" #include "persp3d.h" -#include "util/units.h" #include "xml/simple-document.h" -#include "sp-filter-reference.h" #include "gradient-drag.h" -#include "uri-references.h" -#include "display/curve.h" -#include "display/canvas-bpath.h" #include "display/cairo-utils.h" -#include "inkscape.h" #include "path-chemistry.h" #include "ui/tool/control-point-selection.h" #include "ui/tool/multi-path-manipulator.h" -#include "sp-lpe-item.h" #include "live_effects/effect.h" -#include "live_effects/effect-enum.h" #include "live_effects/parameter/originalpath.h" #include "layer-manager.h" -#include "enums.h" -#include "sp-item-group.h" - // For clippath editing -#include "ui/tools-switch.h" #include "ui/tools/node-tool.h" #include "ui/clipboard.h" -- cgit v1.2.3 From c9aa88a1d57173cdcee7c35a78c82ba2adf54b32 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Fri, 16 Sep 2016 00:13:50 +0200 Subject: Duplicating text along path and its path relinks to the new path (if the prefs option is set) Fixed bugs: - https://launchpad.net/bugs/312116 (bzr r15117) --- src/selection-chemistry.cpp | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 37a0e42e1..7606fc477 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -497,6 +497,8 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone, bool duplicat const gchar *id = old_ids[i]; SPObject *old_clone = doc->getObjectById(id); SPUse *use = dynamic_cast(old_clone); + SPOffset *offset = dynamic_cast(old_clone); + SPText *text = dynamic_cast(old_clone); if (use) { SPItem *orig = use->get_original(); if (!orig) // orphaned @@ -510,14 +512,20 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone, bool duplicat new_clone->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); } } - } else { - SPOffset *offset = dynamic_cast(old_clone); - if (offset) { - for (guint j = 0; j < old_ids.size(); j++) { - gchar *source_href = offset->sourceHref; - if (source_href && source_href[0]=='#' && !strcmp(source_href+1, old_ids[j])) { - doc->getObjectById(new_ids[i])->getRepr()->setAttribute("xlink:href", Glib::ustring("#") + new_ids[j]); - } + } else if (offset) { + gchar *source_href = offset->sourceHref; + for (guint j = 0; j < old_ids.size(); j++) { + if (source_href && source_href[0]=='#' && !strcmp(source_href+1, old_ids[j])) { + doc->getObjectById(new_ids[i])->getRepr()->setAttribute("xlink:href", Glib::ustring("#") + new_ids[j]); + } + } + } else if (text) { + SPTextPath *textpath = dynamic_cast(text->firstChild()); + if (!textpath) continue; + const gchar *source_href = sp_textpath_get_path_item(textpath)->getId(); + for (guint j = 0; j < old_ids.size(); j++) { + if (!strcmp(source_href, old_ids[j])) { + textpath->getRepr()->setAttribute("xlink:href", Glib::ustring("#") + new_ids[j]); } } } -- cgit v1.2.3 From 8ed02c48e6b56a5ea1f204a7938ee20a3da2a65a Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Fri, 16 Sep 2016 00:31:44 +0200 Subject: Fix minor problem in previous commit Fixed bugs: - https://launchpad.net/bugs/312116 (bzr r15118) --- src/selection-chemistry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 7606fc477..834f82edc 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -525,7 +525,7 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone, bool duplicat const gchar *source_href = sp_textpath_get_path_item(textpath)->getId(); for (guint j = 0; j < old_ids.size(); j++) { if (!strcmp(source_href, old_ids[j])) { - textpath->getRepr()->setAttribute("xlink:href", Glib::ustring("#") + new_ids[j]); + doc->getObjectById(new_ids[i])->firstChild()->getRepr()->setAttribute("xlink:href", Glib::ustring("#") + new_ids[j]); } } } -- cgit v1.2.3 From 532f77b14a76fc04e6bdeca3625f9a55b5f11bdf Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Tue, 25 Oct 2016 00:58:43 +0200 Subject: CPPification: almost all sp_object_set_whatever and sp_selection_whatever global functions are now methods of ObjectSet*, with these additional benefits: - They can now act on any SelectionSet, not just the current selection; - Whenever possible, they don't need a desktop anymore and can run if called from GUI. I hope I did not break too many things in the process. *: So instead of callink sp_selection_move(desktop,x,y), you call myobjectset->move(x,y) (bzr r15189) --- src/selection-chemistry.cpp | 1105 ++++++++++++++++++++----------------------- 1 file changed, 515 insertions(+), 590 deletions(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 7bed0a71d..2f9e72e2c 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -13,6 +13,7 @@ * Kris De Gussem * Tavmjong Bah (Symbol additions) * Adrian Boguszewski + * Marc Jeanmougin * * Copyright (C) 1999-2016 authors * Copyright (C) 2001-2002 Ximian, Inc. @@ -223,7 +224,7 @@ void SelectionHelper::reverse(SPDesktop *dt) NodeTool *nt = static_cast(dt->event_context); nt->_multipath->reverseSubpaths(); } else { - sp_selected_path_reverse(dt); + dt->getSelection()->pathReverse(); } } @@ -374,43 +375,42 @@ static void sp_selection_delete_impl(std::vector const &items, bool pro } -void sp_selection_delete(SPDesktop *desktop) +void ObjectSet::deleteItems() { - if (desktop == NULL) { - return; - } - - if (tools_isactive(desktop, TOOLS_TEXT)) - if (Inkscape::UI::Tools::sp_text_delete_selection(desktop->event_context)) { - DocumentUndo::done(desktop->getDocument(), SP_VERB_CONTEXT_TEXT, + if(desktop() && tools_isactive(desktop(), TOOLS_TEXT)){ + if (Inkscape::UI::Tools::sp_text_delete_selection(desktop()->event_context)) { + DocumentUndo::done(desktop()->getDocument(), SP_VERB_CONTEXT_TEXT, _("Delete text")); return; - } - - Inkscape::Selection *selection = desktop->getSelection(); - - // check if something is selected - if (selection->isEmpty()) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Nothing was deleted.")); + } + } + + if (isEmpty()) { + selection_display_message(desktop(),Inkscape::WARNING_MESSAGE, _("Nothing was deleted.")); return; } - std::vector selected(selection->items().begin(), selection->items().end()); - selection->clear(); + std::vector selected(items().begin(), items().end()); + clear(); sp_selection_delete_impl(selected); - desktop->currentLayer()->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - - /* a tool may have set up private information in it's selection context - * that depends on desktop items. I think the only sane way to deal with - * this currently is to reset the current tool, which will reset it's - * associated selection context. For example: deleting an object - * while moving it around the canvas. - */ - tools_switch( desktop, tools_active( desktop ) ); + if(SPDesktop *d = desktop()){ + d->currentLayer()->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + + /* a tool may have set up private information in it's selection context + * that depends on desktop items. I think the only sane way to deal with + * this currently is to reset the current tool, which will reset it's + * associated selection context. For example: deleting an object + * while moving it around the canvas. + */ + tools_switch( d, tools_active( d ) ); + } + if(document()) + DocumentUndo::done(document(), SP_VERB_EDIT_DELETE, + _("Delete")); - DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_DELETE, - _("Delete")); } + + static void add_ids_recursive(std::vector &ids, SPObject *obj) { if (obj) { @@ -424,29 +424,33 @@ static void add_ids_recursive(std::vector &ids, SPObject *obj) } } -void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone, bool duplicateLayer) +void ObjectSet::duplicate(bool suppressDone, bool duplicateLayer) { - if (desktop == NULL) { + if(duplicateLayer && !desktop() ){ + //TODO: understand why layer management is tied to desktop and not to document. return; } - - SPDocument *doc = desktop->doc(); + + SPDocument *doc = document(); + + if(!doc) + return; + Inkscape::XML::Document* xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected - if (selection->isEmpty() && !duplicateLayer) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to duplicate.")); + if (isEmpty() && !duplicateLayer) { + selection_display_message(desktop(),Inkscape::WARNING_MESSAGE, _("Select object(s) to duplicate.")); return; } - std::vector reprs(selection->xmlNodes().begin(), selection->xmlNodes().end()); + std::vector reprs(xmlNodes().begin(), xmlNodes().end()); if(duplicateLayer){ reprs.clear(); - reprs.push_back(desktop->currentLayer()->getRepr()); + reprs.push_back(desktop()->currentLayer()->getRepr()); } - selection->clear(); + clear(); // sorting items from different parents sorts each parent's subset without possibly mixing // them, just what we need @@ -534,15 +538,15 @@ void sp_selection_duplicate(SPDesktop *desktop, bool suppressDone, bool duplicat if ( !suppressDone ) { - DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_DUPLICATE, + DocumentUndo::done(document(), SP_VERB_EDIT_DUPLICATE, _("Duplicate")); } if(!duplicateLayer) - selection->setReprList(newsel); + setReprList(newsel); else{ SPObject* new_layer = doc->getObjectByRepr(newsel[0]); gchar* name = g_strdup_printf(_("%s copy"), new_layer->label()); - desktop->layer_manager->renameLayer( new_layer, name, TRUE ); + desktop()->layer_manager->renameLayer( new_layer, name, TRUE ); g_free(name); } } @@ -683,12 +687,18 @@ void sp_edit_invert_in_all_layers(SPDesktop *desktop) sp_edit_select_all_full(desktop, true, true); } -static Inkscape::XML::Node* sp_object_set_group(ObjectSet *set) { - SPDocument *doc = set->desktop()->getDocument(); +Inkscape::XML::Node* ObjectSet::group() { + SPDocument *doc = document(); + if(!doc) + return nullptr; + if (isEmpty()) { + selection_display_message(desktop(), Inkscape::WARNING_MESSAGE, _("Select some objects to group.")); + return nullptr; + } Inkscape::XML::Document *xml_doc = doc->getReprDoc(); Inkscape::XML::Node *group = xml_doc->createElement("svg:g"); - std::vector p(set->xmlNodes().begin(), set->xmlNodes().end()); + std::vector p(xmlNodes().begin(), xmlNodes().end()); std::sort(p.begin(), p.end(), sp_repr_compare_position_bool); // Remember the position and parent of the topmost object. @@ -748,25 +758,13 @@ static Inkscape::XML::Node* sp_object_set_group(ObjectSet *set) { // Move to the position of the topmost, reduced by the number of items deleted from topmost_parent group->setPosition(topmost + 1); - set->set(doc->getObjectByRepr(group)); + set(doc->getObjectByRepr(group)); + DocumentUndo::done(doc, SP_VERB_SELECTION_GROUP, + C_("Verb", "Group")); return group; } -void sp_selection_group(Inkscape::Selection *selection, SPDesktop *desktop) -{ - // Check if something is selected. - if (selection->isEmpty()) { - selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select some objects to group.")); - return; - } - Inkscape::XML::Node* group = sp_object_set_group(selection); - - DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_GROUP, - C_("Verb", "Group")); - - Inkscape::GC::release(group); -} static gint clone_depth_descending(gconstpointer a, gconstpointer b) { SPUse *use_a = static_cast(const_cast(a)); @@ -781,20 +779,19 @@ static gint clone_depth_descending(gconstpointer a, gconstpointer b) { return -1; } } - -void sp_selection_ungroup_pop_selection(Inkscape::Selection *selection, SPDesktop *desktop) -{ - if (selection->isEmpty()) { - selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("No objects selected to pop out of group.")); + +void ObjectSet::popFromGroup(){ + if (isEmpty()) { + selection_display_message(desktop(), Inkscape::WARNING_MESSAGE, _("No objects selected to pop out of group.")); return; } - auto item = selection->items().begin(); // leaving this because it will be useful for + auto item = items().begin(); // leaving this because it will be useful for // future implementation of complex pop ungrouping SPItem *obj = *item; SPItem *parent_group = static_cast(obj->parent); if (!SP_IS_GROUP(parent_group) || SP_IS_LAYER(parent_group)) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Selection not in a group.")); + selection_display_message(desktop(), Inkscape::WARNING_MESSAGE, _("Selection not in a group.")); return; } if (parent_group->firstChild()->getNext() == NULL) { @@ -802,22 +799,20 @@ void sp_selection_ungroup_pop_selection(Inkscape::Selection *selection, SPDeskto sp_item_group_ungroup(static_cast(parent_group), children, false); } else { - sp_selection_to_next_layer(desktop, 1); // suppress done + toNextLayer(1); } parent_group->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_UNGROUP_POP_SELECTION, + if(document()) + DocumentUndo::done(document(), SP_VERB_SELECTION_UNGROUP_POP_SELECTION, _("Pop selection from group")); } -static void sp_object_set_ungroup(ObjectSet *set) +static void ungroup_impl(ObjectSet *set) { - GSList *groups = NULL; - for (auto g: set->groups()) { - groups = g_slist_prepend(groups, g); - } + std::set groups(set->groups().begin(),set->groups().end()); std::vector new_select; auto old_select = set->items(); @@ -834,7 +829,7 @@ static void sp_object_set_ungroup(ObjectSet *set) original = dynamic_cast(original)->get_original(); } - if (g_slist_find(groups, original) != NULL) { + if (groups.find(original) != groups.end()) { clones_to_unlink = g_slist_prepend(clones_to_unlink, *item); } } @@ -856,7 +851,7 @@ static void sp_object_set_ungroup(ObjectSet *set) SPItem *obj = *item; // ungroup only the groups marked earlier - if (g_slist_find(groups, *item) != NULL) { + if (groups.find(*item) != groups.end()) { std::vector children; sp_item_group_ungroup(dynamic_cast(obj), children, false); // add the items resulting from ungrouping to the selection @@ -871,23 +866,28 @@ static void sp_object_set_ungroup(ObjectSet *set) set->setList(new_select); } -void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop) +void ObjectSet::ungroup() { - if (selection->isEmpty()) { - selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select a group to ungroup.")); + if (isEmpty()) { + if(desktop()) + selection_display_message(desktop(), Inkscape::WARNING_MESSAGE, _("Select a group to ungroup.")); + return; } - if (boost::distance(selection->groups()) == 0) { - selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("No groups to ungroup in the selection.")); + if (boost::distance(groups()) == 0) { + if(desktop()) + selection_display_message(desktop(), Inkscape::ERROR_MESSAGE, _("No groups to ungroup in the selection.")); return; } - sp_object_set_ungroup(selection); - - DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_UNGROUP, + ungroup_impl(this); + if(document()) + DocumentUndo::done(document(), SP_VERB_SELECTION_UNGROUP, _("Ungroup")); } +// TODO replace it with ObjectSet::degroup_list + /** Replace all groups in the list with their member objects, recursively; returns a new list, frees old */ std::vector sp_degroup_list(std::vector &items) @@ -967,16 +967,29 @@ bool sp_item_repr_compare_position_bool(SPObject const *first, SPObject const *s ((SPItem*)second)->getRepr())<0; } -void sp_object_set_raise(ObjectSet *set) { - std::vector items(set->items().begin(), set->items().end()); - Inkscape::XML::Node *grepr = const_cast(items.front()->parent->getRepr()); +void ObjectSet::raise(bool skip_undo){ + + if(isEmpty()){ + selection_display_message(desktop(), Inkscape::WARNING_MESSAGE, _("Select object(s) to raise.")); + return; + } + + SPGroup const *group = sp_item_list_common_parent_group(items()); + if (!group) { + if(desktop()) + selection_display_message(desktop(), Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); + return; + } + + std::vector items_copy(items().begin(), items().end()); + Inkscape::XML::Node *grepr = const_cast(items_copy.front()->parent->getRepr()); /* Construct reverse-ordered list of selected children. */ - std::vector rev(items); + std::vector rev(items_copy); sort(rev.begin(),rev.end(),sp_item_repr_compare_position_bool); // Determine the common bbox of the selected items. - Geom::OptRect selected = enclose_items(items); + Geom::OptRect selected = enclose_items(items_copy); // Iterate over all objects in the selection (starting from top). if (selected) { @@ -990,7 +1003,7 @@ void sp_object_set_raise(ObjectSet *set) { Geom::OptRect newref_bbox = newItem->desktopVisualBounds(); if ( newref_bbox && selected->intersects(*newref_bbox) ) { // AND if it's not one of our selected objects, - if ( std::find(items.begin(),items.end(),newref)==items.end()) { + if ( std::find(items_copy.begin(),items_copy.end(),newref)==items_copy.end()) { // move the selected object after that sibling grepr->changeOrder(child->getRepr(), newref->getRepr()); } @@ -1000,70 +1013,59 @@ void sp_object_set_raise(ObjectSet *set) { } } } + if(document() && !skip_undo) + DocumentUndo::done(document(), SP_VERB_SELECTION_RAISE, + //TRANSLATORS: "Raise" means "to raise an object" in the undo history + C_("Undo action", "Raise")); } -void sp_selection_raise(Inkscape::Selection *selection, SPDesktop *desktop) -{ - if (selection->items().empty()) { - selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select object(s) to raise.")); + +void ObjectSet::raiseToTop(bool skip_undo) { + if(isEmpty()){ + selection_display_message(desktop(), Inkscape::WARNING_MESSAGE, _("Select object(s) to raise.")); return; } - SPGroup const *group = sp_item_list_common_parent_group(selection->items()); + SPGroup const *group = sp_item_list_common_parent_group(items()); if (!group) { - selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); + selection_display_message(desktop(), Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); return; } - sp_object_set_raise(selection); - - DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_RAISE, - //TRANSLATORS: "Raise" means "to raise an object" in the undo history - C_("Undo action", "Raise")); -} - -void sp_object_set_raise_to_top(ObjectSet *set) { - std::vector rl(set->xmlNodes().begin(), set->xmlNodes().end()); + + std::vector rl(xmlNodes().begin(), xmlNodes().end()); sort(rl.begin(),rl.end(),sp_repr_compare_position_bool); for (std::vector::const_iterator l=rl.begin(); l!=rl.end();++l) { Inkscape::XML::Node *repr =(*l); repr->setPosition(-1); } + if (document() && !skip_undo) { + DocumentUndo::done(document(), SP_VERB_SELECTION_TO_FRONT, + _("Raise to top")); + } } -void sp_selection_raise_to_top(Inkscape::Selection *selection, SPDesktop *desktop, bool skip_undo) -{ - SPDocument *document = selection->layers()->getDocument(); - - if (selection->isEmpty()) { - selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select object(s) to raise to top.")); +void ObjectSet::lower(bool skip_undo){ + if(isEmpty()){ + selection_display_message(desktop(), Inkscape::WARNING_MESSAGE, _("Select object(s) to lower.")); return; } - SPGroup const *group = sp_item_list_common_parent_group(selection->items()); + SPGroup const *group = sp_item_list_common_parent_group(items()); if (!group) { - selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); + selection_display_message(desktop(), Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); return; } - sp_object_set_raise_to_top(selection); - - if (!skip_undo) { - DocumentUndo::done(document, SP_VERB_SELECTION_TO_FRONT, - _("Raise to top")); - } -} - -void sp_object_set_lower(ObjectSet *set) { - std::vector items(set->items().begin(), set->items().end()); - Inkscape::XML::Node *grepr = const_cast(items.front()->parent->getRepr()); + std::vector items_copy(items().begin(), items().end()); + Inkscape::XML::Node *grepr = const_cast(items_copy.front()->parent->getRepr()); // Determine the common bbox of the selected items. - Geom::OptRect selected = enclose_items(items); + Geom::OptRect selected = enclose_items(items_copy); /* Construct direct-ordered list of selected children. */ - std::vector rev(items); + std::vector rev(items_copy); sort(rev.begin(),rev.end(),sp_item_repr_compare_position_bool); // Iterate over all objects in the selection (starting from top). @@ -1078,7 +1080,7 @@ void sp_object_set_lower(ObjectSet *set) { Geom::OptRect ref_bbox = newItem->desktopVisualBounds(); if ( ref_bbox && selected->intersects(*ref_bbox) ) { // AND if it's not one of our selected objects, - if (items.end()==std::find(items.begin(),items.end(),newref)) { + if (items_copy.end()==std::find(items_copy.begin(),items_copy.end(),newref)) { // move the selected object before that sibling SPObject *put_after = prev_sibling(newref); if (put_after) @@ -1092,38 +1094,35 @@ void sp_object_set_lower(ObjectSet *set) { } } } + if(document() && !skip_undo) + DocumentUndo::done(document(), SP_VERB_SELECTION_LOWER, + //TRANSLATORS: "Lower" means "to lower an object" in the undo history + C_("Undo action", "Lower")); } -void sp_selection_lower(Inkscape::Selection *selection, SPDesktop *desktop) -{ - if (selection->items().empty()) { - selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select object(s) to lower.")); + +void ObjectSet::lowerToBottom(bool skip_undo){ + if(!document()) + return; + if (isEmpty()) { + selection_display_message(desktop(), Inkscape::WARNING_MESSAGE, _("Select object(s) to lower to bottom.")); return; } - SPGroup const *group = sp_item_list_common_parent_group(selection->items()); + SPGroup const *group = sp_item_list_common_parent_group(items()); if (!group) { - selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); + selection_display_message(desktop(), Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); return; } - sp_object_set_lower(selection); - - DocumentUndo::done(selection->layers()->getDocument(), SP_VERB_SELECTION_LOWER, - //TRANSLATORS: "Lower" means "to lower an object" in the undo history - C_("Undo action", "Lower")); -} - - -void sp_object_set_lower_to_bottom(ObjectSet *set) { - std::vector rl(set->xmlNodes().begin(), set->xmlNodes().end()); + std::vector rl(xmlNodes().begin(), xmlNodes().end()); sort(rl.begin(),rl.end(),sp_repr_compare_position_bool); for (std::vector::const_reverse_iterator l=rl.rbegin();l!=rl.rend();++l) { gint minpos; SPObject *pp; Inkscape::XML::Node *repr = (*l); - pp = set->desktop()->getDocument()->getObjectByRepr(repr->parent()); + pp = document()->getObjectByRepr(repr->parent()); minpos = 0; g_assert(dynamic_cast(pp)); for (auto& pc: pp->children) { @@ -1134,28 +1133,13 @@ void sp_object_set_lower_to_bottom(ObjectSet *set) { } repr->setPosition(minpos); } -} - -void sp_selection_lower_to_bottom(Inkscape::Selection *selection, SPDesktop *desktop, bool skip_undo) -{ - if (selection->isEmpty()) { - selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select object(s) to lower to bottom.")); - return; - } - - SPGroup const *group = sp_item_list_common_parent_group(selection->items()); - if (!group) { - selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("You cannot raise/lower objects from different groups or layers.")); - return; - } - - sp_object_set_lower_to_bottom(selection); - if (!skip_undo) { - DocumentUndo::done(desktop->getDocument(), SP_VERB_SELECTION_TO_BACK, + if (document() && !skip_undo) { + DocumentUndo::done(document(), SP_VERB_SELECTION_TO_BACK, _("Lower to bottom")); } } + void sp_undo(SPDesktop *desktop, SPDocument *) { @@ -1178,10 +1162,10 @@ sp_redo(SPDesktop *desktop, SPDocument *) } } -void sp_selection_cut(SPDesktop *desktop) +void ObjectSet::cut() { - sp_selection_copy(desktop); - sp_selection_delete(desktop); + copy(); + deleteItems(); } /** @@ -1236,11 +1220,10 @@ take_style_from_item(SPObject *object) return css; } - -void sp_selection_copy(SPDesktop *desktop) +void ObjectSet::copy() { Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); - cm->copy(desktop); + cm->copy(this); } void sp_selection_paste(SPDesktop *desktop, bool in_place) @@ -1251,20 +1234,20 @@ void sp_selection_paste(SPDesktop *desktop, bool in_place) } } -void sp_selection_paste_style(SPDesktop *desktop) +void ObjectSet::pasteStyle() { Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); - if (cm->pasteStyle(desktop)) { - DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_PASTE_STYLE, _("Paste style")); + if (cm->pasteStyle(this)) { + DocumentUndo::done(document(), SP_VERB_EDIT_PASTE_STYLE, _("Paste style")); } } -void sp_selection_paste_livepatheffect(SPDesktop *desktop) +void ObjectSet::pastePathEffect() { Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); - if (cm->pastePathEffect(desktop)) { - DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_PASTE_LIVEPATHEFFECT, + if (cm->pastePathEffect(this)) { + DocumentUndo::done(document(), SP_VERB_EDIT_PASTE_LIVEPATHEFFECT, _("Paste live path effect")); } } @@ -1279,18 +1262,16 @@ static void sp_selection_remove_livepatheffect_impl(SPItem *item) } } -void sp_selection_remove_livepatheffect(SPDesktop *desktop) +void ObjectSet::removeLPE() { - if (desktop == NULL) return; - - Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected - if (selection->isEmpty()) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to remove live path effects from.")); + if (isEmpty()) { + if(desktop()) + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to remove live path effects from.")); return; } - auto list= selection->items(); + auto list= items(); for (auto itemlist=list.begin();itemlist!=list.end();++itemlist) { SPItem *item = *itemlist; @@ -1298,46 +1279,45 @@ void sp_selection_remove_livepatheffect(SPDesktop *desktop) } - DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_REMOVE_LIVEPATHEFFECT, + if(document()) + DocumentUndo::done(document(), SP_VERB_EDIT_REMOVE_LIVEPATHEFFECT, _("Remove live path effect")); } -void sp_selection_remove_filter(SPDesktop *desktop) +void ObjectSet::removeFilter() { - if (desktop == NULL) return; - - Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected - if (selection->isEmpty()) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to remove filters from.")); + if (isEmpty()) { + if(desktop()) + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to remove filters from.")); return; } SPCSSAttr *css = sp_repr_css_attr_new(); sp_repr_css_unset_property(css, "filter"); - sp_desktop_set_style(desktop, css); + sp_desktop_set_style(this, desktop(), css); sp_repr_css_attr_unref(css); - - DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_REMOVE_FILTER, + if(document()) + DocumentUndo::done(document(), SP_VERB_EDIT_REMOVE_FILTER, _("Remove filter")); } -void sp_selection_paste_size(SPDesktop *desktop, bool apply_x, bool apply_y) +void ObjectSet::pasteSize(bool apply_x, bool apply_y) { Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); - if (cm->pasteSize(desktop, false, apply_x, apply_y)) { - DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_PASTE_SIZE, + if (cm->pasteSize(this, false, apply_x, apply_y)) { + DocumentUndo::done(document(), SP_VERB_EDIT_PASTE_SIZE, _("Paste size")); } } -void sp_selection_paste_size_separately(SPDesktop *desktop, bool apply_x, bool apply_y) +void ObjectSet::pasteSizeSeparately(bool apply_x, bool apply_y) { Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); - if (cm->pasteSize(desktop, true, apply_x, apply_y)) { - DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_PASTE_SIZE_SEPARATELY, + if (cm->pasteSize(this, true, apply_x, apply_y)) { + DocumentUndo::done(document(), SP_VERB_EDIT_PASTE_SIZE_SEPARATELY, _("Paste size separately")); } } @@ -1360,27 +1340,28 @@ void sp_selection_change_layer_maintain_clones(std::vector const &items } } - -void sp_selection_to_next_layer(SPDesktop *dt, bool suppressDone) +void ObjectSet::toNextLayer(bool skip_undo) { - Inkscape::Selection *selection = dt->getSelection(); - + if(!desktop()) + return; + SPDesktop *dt=desktop(); //TODO make it desktop-independent + // check if something is selected - if (selection->isEmpty()) { + if (isEmpty()) { dt->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to move to the layer above.")); return; } - std::vector items(selection->items().begin(), selection->items().end()); + std::vector items_copy(items().begin(), items().end()); bool no_more = false; // Set to true, if no more layers above SPObject *next=Inkscape::next_layer(dt->currentRoot(), dt->currentLayer()); if (next) { - selection->clear(); - sp_selection_change_layer_maintain_clones(items,next); + clear(); + sp_selection_change_layer_maintain_clones(items_copy,next); std::vector temp_clip; - sp_selection_copy_impl(items, temp_clip, dt->doc()->getReprDoc()); - sp_selection_delete_impl(items, false, false); + sp_selection_copy_impl(items_copy, temp_clip, dt->doc()->getReprDoc()); + sp_selection_delete_impl(items_copy, false, false); next=Inkscape::next_layer(dt->currentRoot(), dt->currentLayer()); // Fixes bug 1482973: crash while moving layers std::vector copied; if (next) { @@ -1389,9 +1370,9 @@ void sp_selection_to_next_layer(SPDesktop *dt, bool suppressDone) copied = sp_selection_paste_impl(dt->getDocument(), dt->currentLayer(), temp_clip); no_more = true; } - selection->setReprList(copied); + setReprList(copied); if (next) dt->setCurrentLayer(next); - if ( !suppressDone ) { + if ( !skip_undo ) { DocumentUndo::done(dt->getDocument(), SP_VERB_LAYER_MOVE_TO_NEXT, _("Raise to next layer")); } @@ -1405,26 +1386,28 @@ void sp_selection_to_next_layer(SPDesktop *dt, bool suppressDone) } -void sp_selection_to_prev_layer(SPDesktop *dt, bool suppressDone) +void ObjectSet::toPrevLayer(bool skip_undo) { - Inkscape::Selection *selection = dt->getSelection(); + if(!desktop()) + return; + SPDesktop *dt=desktop(); //TODO make it desktop-independent // check if something is selected - if (selection->isEmpty()) { + if (isEmpty()) { dt->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to move to the layer below.")); return; } - std::vector items(selection->items().begin(), selection->items().end()); + std::vector items_copy(items().begin(), items().end()); bool no_more = false; // Set to true, if no more layers below SPObject *next=Inkscape::previous_layer(dt->currentRoot(), dt->currentLayer()); if (next) { - selection->clear(); - sp_selection_change_layer_maintain_clones(items,next); + clear(); + sp_selection_change_layer_maintain_clones(items_copy,next); std::vector temp_clip; - sp_selection_copy_impl(items, temp_clip, dt->doc()->getReprDoc()); // we're in the same doc, so no need to copy defs - sp_selection_delete_impl(items, false, false); + sp_selection_copy_impl(items_copy, temp_clip, dt->doc()->getReprDoc()); // we're in the same doc, so no need to copy defs + sp_selection_delete_impl(items_copy, false, false); next=Inkscape::previous_layer(dt->currentRoot(), dt->currentLayer()); // Fixes bug 1482973: crash while moving layers std::vector copied; if (next) { @@ -1433,9 +1416,9 @@ void sp_selection_to_prev_layer(SPDesktop *dt, bool suppressDone) copied = sp_selection_paste_impl(dt->getDocument(), dt->currentLayer(), temp_clip); no_more = true; } - selection->setReprList( copied); + setReprList( copied); if (next) dt->setCurrentLayer(next); - if ( !suppressDone ) { + if ( !skip_undo ) { DocumentUndo::done(dt->getDocument(), SP_VERB_LAYER_MOVE_TO_PREV, _("Lower to previous layer")); } @@ -1448,30 +1431,33 @@ void sp_selection_to_prev_layer(SPDesktop *dt, bool suppressDone) } } -void sp_selection_to_layer(SPDesktop *dt, SPObject *moveto, bool suppressDone) +void ObjectSet::toLayer(SPObject *moveto, bool skip_undo) { - Inkscape::Selection *selection = dt->getSelection(); + if(!document()) + return; + SPDesktop *dt = desktop(); // check if something is selected - if (selection->isEmpty()) { - dt->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to move.")); + if (isEmpty()) { + if(dt) + dt->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to move.")); return; } - std::vector items(selection->items().begin(), selection->items().end()); + std::vector items_copy(items().begin(), items().end()); if (moveto) { - selection->clear(); - sp_selection_change_layer_maintain_clones(items,moveto); + clear(); + sp_selection_change_layer_maintain_clones(items_copy,moveto); std::vector temp_clip; - sp_selection_copy_impl(items, temp_clip, dt->doc()->getReprDoc()); // we're in the same doc, so no need to copy defs - sp_selection_delete_impl(items, false, false); - std::vector copied = sp_selection_paste_impl(dt->getDocument(), moveto, temp_clip); - selection->setReprList(copied); + sp_selection_copy_impl(items_copy, temp_clip, document()->getReprDoc()); // we're in the same doc, so no need to copy defs + sp_selection_delete_impl(items_copy, false, false); + std::vector copied = sp_selection_paste_impl(document(), moveto, temp_clip); + setReprList(copied); if (!temp_clip.empty()) temp_clip.clear(); - if (moveto) dt->setCurrentLayer(moveto); - if ( !suppressDone ) { - DocumentUndo::done(dt->getDocument(), SP_VERB_LAYER_MOVE_TO, + if (moveto && dt) dt->setCurrentLayer(moveto); + if ( !skip_undo ) { + DocumentUndo::done(document(), SP_VERB_LAYER_MOVE_TO, _("Move selection to layer")); } } @@ -1527,22 +1513,23 @@ value of set_i2d==false is only used by seltrans when it's dragging objects live that case, items are already in the new position, but the repr is in the old, and this function then simply updates the repr from item->transform. */ -void sp_object_set_apply_affine(ObjectSet *set, Geom::Affine const &affine, bool set_i2d, bool compensate, + +void ObjectSet::applyAffine(Geom::Affine const &affine, bool set_i2d, bool compensate, bool adjust_transf_center) { - if (set->isEmpty()) + if (isEmpty()) return; // For each perspective with a box in selection, check whether all boxes are selected and // unlink all non-selected boxes. Persp3D *persp; Persp3D *transf_persp; - std::list plist = set->perspList(); + std::list plist = perspList(); for (std::list::iterator i = plist.begin(); i != plist.end(); ++i) { persp = (Persp3D *) (*i); - if (!persp3d_has_all_boxes_in_selection (persp, set)) { - std::list selboxes = set->box3DList(persp); + if (!persp3d_has_all_boxes_in_selection (persp, this)) { + std::list selboxes = box3DList(persp); // create a new perspective as a copy of the current one and link the selected boxes to it transf_persp = persp3d_create_xml_element (persp->document, persp->perspective_impl); @@ -1555,14 +1542,15 @@ void sp_object_set_apply_affine(ObjectSet *set, Geom::Affine const &affine, bool persp3d_apply_affine_transformation(transf_persp, affine); } - auto items = set->items(); - for (auto l=items.begin();l!=items.end() ;++l) { + auto items_copy = items(); + for (auto l=items_copy.begin();l!=items_copy.end() ;++l) { SPItem *item = *l; if( dynamic_cast(item) ) { // An SVG element cannot have a transform. We could change 'x' and 'y' in response // to a translation... but leave that for another day. - set->desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Cannot transform an embedded SVG.")); + if(desktop()) + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Cannot transform an embedded SVG.")); break; } @@ -1572,21 +1560,21 @@ void sp_object_set_apply_affine(ObjectSet *set, Geom::Affine const &affine, bool #if 0 /* Re-enable this once persistent guides have a graphical indication. At the time of writing, this is the only place to re-enable. */ - sp_item_update_cns(*item, selection->desktop()); + sp_item_update_cns(*item, desktop()); #endif // we're moving both a clone and its original or any ancestor in clone chain? - bool transform_clone_with_original = object_set_contains_original(item, set); + bool transform_clone_with_original = object_set_contains_original(item, this); // ...both a text-on-path and its path? bool transform_textpath_with_path = ((dynamic_cast(item) && item->firstChild() && dynamic_cast(item->firstChild())) - && set->includes( sp_textpath_get_path_item(dynamic_cast(item->firstChild())) )); + && includes( sp_textpath_get_path_item(dynamic_cast(item->firstChild())) )); // ...both a flowtext and its frame? - bool transform_flowtext_with_frame = (dynamic_cast(item) && set->includes( dynamic_cast(item)->get_frame(NULL))); // (only the first frame is checked so far) + bool transform_flowtext_with_frame = (dynamic_cast(item) && includes( dynamic_cast(item)->get_frame(NULL))); // (only the first frame is checked so far) // ...both an offset and its source? - bool transform_offset_with_source = (dynamic_cast(item) && dynamic_cast(item)->sourceHref) && set->includes( sp_offset_get_source(dynamic_cast(item)) ); + bool transform_offset_with_source = (dynamic_cast(item) && dynamic_cast(item)->sourceHref) && includes( sp_offset_get_source(dynamic_cast(item)) ); // If we're moving a connector, we want to detach it // from shapes that aren't part of the selection, but @@ -1597,7 +1585,7 @@ void sp_object_set_apply_affine(ObjectSet *set, Geom::Affine const &affine, bool SPItem *attItem[2] = {0, 0}; path->connEndPair.getAttachedItems(attItem); for (int n = 0; n < 2; ++n) { - if (!set->includes(attItem[n])) { + if (!includes(attItem[n])) { sp_conn_end_detach(item, n); } } @@ -1719,31 +1707,24 @@ void sp_object_set_apply_affine(ObjectSet *set, Geom::Affine const &affine, bool } } -void sp_object_set_remove_transform(SPDesktop *desktop) +void ObjectSet::removeTransform() { - if (desktop == NULL) - return; - - Inkscape::Selection *selection = desktop->getSelection(); - - auto items = selection->xmlNodes(); + auto items = xmlNodes(); for (auto l=items.begin();l!=items.end() ;++l) { (*l)->setAttribute("transform", NULL, false); } - DocumentUndo::done(desktop->getDocument(), SP_VERB_OBJECT_FLATTEN, + if(document()) + DocumentUndo::done(document(), SP_VERB_OBJECT_FLATTEN, _("Remove transform")); } -void -sp_object_set_scale_absolute(ObjectSet *set, - double x0, double x1, - double y0, double y1) +void ObjectSet::setScaleAbsolute(double x0, double x1,double y0, double y1) { - if (set->isEmpty()) + if (isEmpty()) return; - Geom::OptRect bbox = set->visualBounds(); + Geom::OptRect bbox = visualBounds(); if ( !bbox ) { return; } @@ -1756,16 +1737,15 @@ sp_object_set_scale_absolute(ObjectSet *set, Geom::Translate const o2n(x0, y0); Geom::Affine const final( p2o * scale * o2n ); - sp_object_set_apply_affine(set, final); + applyAffine(final); } - -void sp_object_set_scale_relative(ObjectSet *set, Geom::Point const &align, Geom::Scale const &scale) +void ObjectSet::setScaleRelative(Geom::Point const &align, Geom::Scale const &scale) { - if (set->isEmpty()) + if (isEmpty()) return; - Geom::OptRect bbox = set->visualBounds(); + Geom::OptRect bbox = visualBounds(); if ( !bbox ) { return; @@ -1781,21 +1761,19 @@ void sp_object_set_scale_relative(ObjectSet *set, Geom::Point const &align, Geom Geom::Translate const n2d(-align); Geom::Translate const d2n(align); Geom::Affine const final( n2d * scale * d2n ); - sp_object_set_apply_affine(set, final); + applyAffine(final); } -void -sp_object_set_rotate_relative(ObjectSet *set, Geom::Point const ¢er, double angle_degrees) +void ObjectSet::rotateRelative(Geom::Point const ¢er, double angle_degrees) { Geom::Translate const d2n(center); Geom::Translate const n2d(-center); Geom::Rotate const rotate(Geom::Rotate::from_degrees(angle_degrees)); Geom::Affine const final( Geom::Affine(n2d) * rotate * d2n ); - sp_object_set_apply_affine(set, final); + applyAffine(final); } -void -sp_object_set_skew_relative(ObjectSet *set, Geom::Point const &align, double dx, double dy) +void ObjectSet::skewRelative(Geom::Point const &align, double dx, double dy) { Geom::Translate const d2n(align); Geom::Translate const n2d(-align); @@ -1803,32 +1781,30 @@ sp_object_set_skew_relative(ObjectSet *set, Geom::Point const &align, double dx, dx, 1, 0, 0); Geom::Affine const final( n2d * skew * d2n ); - sp_object_set_apply_affine(set, final); + applyAffine(final); } -void sp_object_set_move_relative(ObjectSet *set, Geom::Point const &move, bool compensate) +void ObjectSet::moveRelative(Geom::Point const &move, bool compensate) { - sp_object_set_apply_affine(set, Geom::Affine(Geom::Translate(move)), true, compensate); + applyAffine(Geom::Affine(Geom::Translate(move)), true, compensate); } -void sp_object_set_move_relative(ObjectSet *set, double dx, double dy) +void ObjectSet::moveRelative(double dx, double dy) { - sp_object_set_apply_affine(set, Geom::Affine(Geom::Translate(dx, dy))); + applyAffine(Geom::Affine(Geom::Translate(dx, dy))); } /** * Rotates selected objects 90 degrees, either clock-wise or counter-clockwise, depending on the value of ccw. */ -void sp_selection_rotate_90(SPDesktop *desktop, bool ccw) +void ObjectSet::rotate90(bool ccw) { - Inkscape::Selection *selection = desktop->getSelection(); - - if (selection->isEmpty()) + if (isEmpty()) return; - auto items = selection->items(); + auto items_copy = items(); Geom::Rotate const rot_90(Geom::Point(0, ccw ? 1 : -1)); // pos. or neg. rotation, depending on the value of ccw - for (auto l=items.begin();l!=items.end() ;++l) { + for (auto l=items_copy.begin();l!=items_copy.end() ;++l) { SPItem *item = *l; if (item) { sp_item_rotate_rel(item, rot_90); @@ -1837,25 +1813,23 @@ void sp_selection_rotate_90(SPDesktop *desktop, bool ccw) } } - DocumentUndo::done(desktop->getDocument(), + DocumentUndo::done(document(), ccw ? SP_VERB_OBJECT_ROTATE_90_CCW : SP_VERB_OBJECT_ROTATE_90_CW, ccw ? _("Rotate 90\xc2\xb0 CCW") : _("Rotate 90\xc2\xb0 CW")); } -void -sp_selection_rotate(Inkscape::Selection *selection, gdouble const angle_degrees) +void ObjectSet::rotate(gdouble const angle_degrees) { - if (selection->isEmpty()) + if (isEmpty()) return; - boost::optional center = selection->center(); - if (!center) { + boost::optional center_ = center(); + if (!center_) { return; } + rotateRelative(*center_, angle_degrees); - sp_object_set_rotate_relative(selection, *center, angle_degrees); - - DocumentUndo::maybeDone(selection->desktop()->getDocument(), + DocumentUndo::maybeDone(document(), ( ( angle_degrees > 0 ) ? "selector:rotate:ccw" : "selector:rotate:cw" ), @@ -2183,28 +2157,27 @@ cornerFarthestFrom(Geom::Rect const &r, Geom::Point const &p){ /** \param angle the angle in "angular pixels", i.e. how many visible pixels must move the outermost point of the rotated object */ -void -sp_selection_rotate_screen(Inkscape::Selection *selection, gdouble angle) +void ObjectSet::rotateScreen(double angle) { - if (selection->isEmpty()) + if (isEmpty()||!desktop()) return; - Geom::OptRect bbox = selection->visualBounds(); - boost::optional center = selection->center(); + Geom::OptRect bbox = visualBounds(); + boost::optional center_ = center(); - if ( !bbox || !center ) { + if ( !bbox || !center_ ) { return; } - gdouble const zoom = selection->desktop()->current_zoom(); + gdouble const zoom = desktop()->current_zoom(); gdouble const zmove = angle / zoom; - gdouble const r = Geom::L2(cornerFarthestFrom(*bbox, *center) - *center); + gdouble const r = Geom::L2(cornerFarthestFrom(*bbox, *center_) - *center_); gdouble const zangle = 180 * atan2(zmove, r) / M_PI; - sp_object_set_rotate_relative(selection, *center, zangle); + rotateRelative(*center_, zangle); - DocumentUndo::maybeDone(selection->desktop()->getDocument(), + DocumentUndo::maybeDone(document(), ( (angle > 0) ? "selector:rotate:ccw" : "selector:rotate:cw" ), @@ -2212,18 +2185,17 @@ sp_selection_rotate_screen(Inkscape::Selection *selection, gdouble angle) _("Rotate by pixels")); } -void -sp_selection_scale(Inkscape::Selection *selection, gdouble grow) +void ObjectSet::scale(double grow) { - if (selection->isEmpty()) + if (isEmpty()) return; - Geom::OptRect bbox = selection->visualBounds(); + Geom::OptRect bbox = visualBounds(); if (!bbox) { return; } - Geom::Point const center(bbox->midpoint()); + Geom::Point const center_(bbox->midpoint()); // you can't scale "do nizhe pola" (below zero) double const max_len = bbox->maxExtent(); @@ -2232,9 +2204,9 @@ sp_selection_scale(Inkscape::Selection *selection, gdouble grow) } double const times = 1.0 + grow / max_len; - sp_object_set_scale_relative(selection, center, Geom::Scale(times, times)); + setScaleRelative(center_, Geom::Scale(times, times)); - DocumentUndo::maybeDone(selection->desktop()->getDocument(), + DocumentUndo::maybeDone(document(), ( (grow > 0) ? "selector:scale:larger" : "selector:scale:smaller" ), @@ -2242,40 +2214,39 @@ sp_selection_scale(Inkscape::Selection *selection, gdouble grow) _("Scale")); } -void -sp_selection_scale_screen(Inkscape::Selection *selection, gdouble grow_pixels) +void ObjectSet::scaleScreen(double grow_pixels) { - sp_selection_scale(selection, grow_pixels / selection->desktop()->current_zoom()); + if(!desktop()) + return; + scale(grow_pixels / desktop()->current_zoom()); } -void -sp_selection_scale_times(Inkscape::Selection *selection, gdouble times) +void ObjectSet::scaleTimes(double times) { - if (selection->isEmpty()) + if (isEmpty()) return; - Geom::OptRect sel_bbox = selection->visualBounds(); + Geom::OptRect sel_bbox = visualBounds(); if (!sel_bbox) { return; } - Geom::Point const center(sel_bbox->midpoint()); - sp_object_set_scale_relative(selection, center, Geom::Scale(times, times)); - DocumentUndo::done(selection->desktop()->getDocument(), SP_VERB_CONTEXT_SELECT, + Geom::Point const center_(sel_bbox->midpoint()); + setScaleRelative(center_, Geom::Scale(times, times)); + DocumentUndo::done(document(), SP_VERB_CONTEXT_SELECT, _("Scale by whole factor")); } -void -sp_selection_move(Inkscape::Selection *selection, gdouble dx, gdouble dy) +void ObjectSet::move(double dx, double dy) { - if (selection->isEmpty()) { + if (isEmpty()) { return; } - sp_object_set_move_relative(selection, dx, dy); + moveRelative(dx, dy); - SPDocument *doc = selection->layers()->getDocument(); + SPDocument *doc = document(); if (dx == 0) { DocumentUndo::maybeDone(doc, "selector:move:vertical", SP_VERB_CONTEXT_SELECT, _("Move vertically")); @@ -2288,20 +2259,19 @@ sp_selection_move(Inkscape::Selection *selection, gdouble dx, gdouble dy) } } -void -sp_selection_move_screen(Inkscape::Selection *selection, gdouble dx, gdouble dy) +void ObjectSet::moveScreen(double dx, double dy) { - if (selection->isEmpty() || !selection->desktop()) { + if (isEmpty() || !desktop()) { return; } // same as sp_selection_move but divide deltas by zoom factor - gdouble const zoom = selection->desktop()->current_zoom(); + gdouble const zoom = desktop()->current_zoom(); gdouble const zdx = dx / zoom; gdouble const zdy = dy / zoom; - sp_object_set_move_relative(selection, zdx, zdy); + moveRelative(zdx, zdy); - SPDocument *doc = selection->layers()->getDocument(); + SPDocument *doc = document(); if (dx == 0) { DocumentUndo::maybeDone(doc, "selector:move:vertical", SP_VERB_CONTEXT_SELECT, _("Move vertically by pixels")); @@ -2531,7 +2501,7 @@ void sp_selection_next_patheffect_param(SPDesktop * dt) return false; }*/ -void sp_selection_edit_clip_or_mask(SPDesktop * /*dt*/, bool /*clip*/) +void ObjectSet::editMask(bool /*clip*/) { return; /*if (!dt) return; @@ -2590,26 +2560,24 @@ void scroll_to_show_item(SPDesktop *desktop, SPItem *item) } } - -void sp_selection_clone(SPDesktop *desktop) +void ObjectSet::clone() { - if (desktop == NULL) { + if (document() == NULL) { return; } - Inkscape::Selection *selection = desktop->getSelection(); - - Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); + Inkscape::XML::Document *xml_doc = document()->getReprDoc(); // check if something is selected - if (selection->isEmpty()) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select an object to clone.")); + if (isEmpty()) { + if(desktop()) + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select an object to clone.")); return; } - std::vector reprs(selection->xmlNodes().begin(), selection->xmlNodes().end()); + std::vector reprs(xmlNodes().begin(), xmlNodes().end()); - selection->clear(); + clear(); // sorting items from different parents sorts each parent's subset without possibly mixing them, just what we need sort(reprs.begin(),reprs.end(),sp_repr_compare_position_bool); @@ -2637,37 +2605,33 @@ void sp_selection_clone(SPDesktop *desktop) Inkscape::GC::release(clone); } - DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_CLONE, + DocumentUndo::done(document(), SP_VERB_EDIT_CLONE, C_("Action", "Clone")); - selection->setReprList(newsel); + setReprList(newsel); } -void -sp_selection_relink(SPDesktop *desktop) +void ObjectSet::relink() { - if (!desktop) - return; - - Inkscape::Selection *selection = desktop->getSelection(); - - if (selection->isEmpty()) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select clones to relink.")); + if (isEmpty()) { + if(desktop()) + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select clones to relink.")); return; } Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); const gchar *newid = cm->getFirstObjectID(); if (!newid) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Copy an object to clipboard to relink clones to.")); + if(desktop()) + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Copy an object to clipboard to relink clones to.")); return; } gchar *newref = g_strdup_printf("#%s", newid); // Get a copy of current selection. bool relinked = false; - auto items= selection->items(); - for (auto i=items.begin();i!=items.end();++i){ + auto items_= items(); + for (auto i=items_.begin();i!=items_.end();++i){ SPItem *item = *i; if (dynamic_cast(item)) { @@ -2680,33 +2644,29 @@ sp_selection_relink(SPDesktop *desktop) g_free(newref); if (!relinked) { - desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("No clones to relink in the selection.")); + if(desktop()) + desktop()->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("No clones to relink in the selection.")); } else { - DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_UNLINK_CLONE, + DocumentUndo::done(document(), SP_VERB_EDIT_UNLINK_CLONE, _("Relink clone")); } } -void -sp_selection_unlink(SPDesktop *desktop) +void ObjectSet::unlink() { - if (!desktop) - return; - - Inkscape::Selection *selection = desktop->getSelection(); - - if (selection->isEmpty()) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select clones to unlink.")); + if (isEmpty()) { + if(desktop()) + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select clones to unlink.")); return; } // Get a copy of current selection. std::vector new_select; bool unlinked = false; - std::vector items(selection->items().begin(), selection->items().end()); + std::vector items_(items().begin(), items().end()); - for (auto i=items.rbegin();i!=items.rend();++i){ + for (auto i=items_.rbegin();i!=items_.rend();++i){ SPItem *item = *i; if (dynamic_cast(item)) { @@ -2747,34 +2707,30 @@ sp_selection_unlink(SPDesktop *desktop) } if (!new_select.empty()) { // set new selection - selection->clear(); - selection->setList(new_select); + clear(); + setList(new_select); } if (!unlinked) { - desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("No clones to unlink in the selection.")); + if(desktop()) + desktop()->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("No clones to unlink in the selection.")); } - DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_UNLINK_CLONE, + DocumentUndo::done(document(), SP_VERB_EDIT_UNLINK_CLONE, _("Unlink clone")); } -void -sp_select_clone_original(SPDesktop *desktop) +void ObjectSet::cloneOriginal() { - if (desktop == NULL) - return; - - Inkscape::Selection *selection = desktop->getSelection(); - - SPItem *item = selection->singleItem(); + SPItem *item = singleItem(); gchar const *error = _("Select a clone to go to its original. Select a linked offset to go to its source. Select a text on path to go to the path. Select a flowed text to go to its frame."); // Check if other than two objects are selected - auto items= selection->items(); - if (boost::distance(items) != 1 || !item) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, error); + auto items_= items(); + if (boost::distance(items_) != 1 || !item) { + if(desktop()) + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, error); return; } @@ -2813,18 +2769,21 @@ sp_select_clone_original(SPDesktop *desktop) } if (original == NULL) { // it's an object that we don't know what to do with - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, error); + if(desktop()) + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, error); return; } if (!original) { - desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Cannot find the object to select (orphaned clone, offset, textpath, flowed text?)")); + if(desktop()) + desktop()->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("Cannot find the object to select (orphaned clone, offset, textpath, flowed text?)")); return; } for (SPObject *o = original; o && !dynamic_cast(o); o = o->parent) { if (dynamic_cast(o)) { - desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("The object you're trying to select is not visible (it is in <defs>)")); + if(desktop()) + desktop()->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("The object you're trying to select is not visible (it is in <defs>)")); return; } } @@ -2835,24 +2794,24 @@ sp_select_clone_original(SPDesktop *desktop) if (highlight) { Geom::OptRect a = item->desktopVisualBounds(); Geom::OptRect b = original->desktopVisualBounds(); - if ( a && b ) { + if ( a && b && desktop()) { // draw a flashing line between the objects SPCurve *curve = new SPCurve(); curve->moveto(a->midpoint()); curve->lineto(b->midpoint()); - SPCanvasItem * canvasitem = sp_canvas_bpath_new(desktop->getTempGroup(), curve); + SPCanvasItem * canvasitem = sp_canvas_bpath_new(desktop()->getTempGroup(), curve); sp_canvas_bpath_set_stroke(SP_CANVAS_BPATH(canvasitem), 0x0000ddff, 1.0, SP_STROKE_LINEJOIN_MITER, SP_STROKE_LINECAP_BUTT, 5, 3); sp_canvas_item_show(canvasitem); curve->unref(); - desktop->add_temporary_canvasitem(canvasitem, 1000); + desktop()->add_temporary_canvasitem(canvasitem, 1000); } } - selection->clear(); - selection->set(original); - if (SP_CYCLING == SP_CYCLE_FOCUS) { - scroll_to_show_item(desktop, original); + clear(); + set(original); + if (SP_CYCLING == SP_CYCLE_FOCUS && desktop()) { + scroll_to_show_item(desktop(), original); } } } @@ -2860,18 +2819,13 @@ sp_select_clone_original(SPDesktop *desktop) /** * This creates a new path, applies the Original Path LPE, and has it refer to the selection. */ -void sp_selection_clone_original_path_lpe(SPDesktop *desktop) +void ObjectSet::cloneOriginalPathLPE() { - if (desktop == NULL) { - return; - } - - Inkscape::Selection *selection = desktop->getSelection(); Inkscape::SVGOStringStream os; SPObject * firstItem = NULL; - auto items= selection->items(); - for (auto i=items.begin();i!=items.end();++i){ + auto items_= items(); + for (auto i=items_.begin();i!=items_.end();++i){ if (SP_IS_SHAPE(*i) || SP_IS_TEXT(*i)) { if (firstItem) { os << "|"; @@ -2882,7 +2836,7 @@ void sp_selection_clone_original_path_lpe(SPDesktop *desktop) } } if (firstItem) { - Inkscape::XML::Document *xml_doc = desktop->doc()->getReprDoc(); + Inkscape::XML::Document *xml_doc = document()->getReprDoc(); SPObject *parent = firstItem->parent; // create the LPE @@ -2890,7 +2844,7 @@ void sp_selection_clone_original_path_lpe(SPDesktop *desktop) { lpe_repr->setAttribute("effect", "fill_between_many"); lpe_repr->setAttribute("linkedpaths", os.str()); - desktop->doc()->getDefs()->getRepr()->addChild(lpe_repr, NULL); // adds to and assigns the 'id' attribute + document()->getDefs()->getRepr()->addChild(lpe_repr, NULL); // adds to and assigns the 'id' attribute } std::string lpe_id_href = std::string("#") + lpe_repr->attribute("id"); Inkscape::GC::release(lpe_repr); @@ -2901,44 +2855,44 @@ void sp_selection_clone_original_path_lpe(SPDesktop *desktop) clone->setAttribute("d", "M 0 0", false); // add the new clone to the top of the original's parent parent->appendChildRepr(clone); - SPObject *clone_obj = desktop->doc()->getObjectById(clone->attribute("id")); + SPObject *clone_obj = document()->getObjectById(clone->attribute("id")); SPLPEItem *clone_lpeitem = dynamic_cast(clone_obj); if (clone_lpeitem) { clone_lpeitem->addPathEffect(lpe_id_href, false); } } - DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_CLONE_ORIGINAL_PATH_LPE, _("Fill between many")); + DocumentUndo::done(document(), SP_VERB_EDIT_CLONE_ORIGINAL_PATH_LPE, _("Fill between many")); // select the new object: - selection->set(clone); + set(clone); Inkscape::GC::release(clone); } else { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select path(s) to fill.")); + if(desktop()) + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select path(s) to fill.")); } } -void sp_selection_to_marker(SPDesktop *desktop, bool apply) +void ObjectSet::toMarker(bool apply) { // sp_selection_tile has similar code - if (desktop == NULL) { + if (desktop() == NULL) { // TODO: We should not need desktop for that. + // Someone get rid of the dt2doc() call. return; } - SPDocument *doc = desktop->getDocument(); + SPDocument *doc = document(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = desktop->getSelection(); - // check if something is selected - if (selection->isEmpty()) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to convert to marker.")); + if (isEmpty()) { + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to convert to marker.")); return; } doc->ensureUpToDate(); - Geom::OptRect r = selection->visualBounds(); - boost::optional c = selection->center(); + Geom::OptRect r = visualBounds(); + boost::optional c = center(); if ( !r || !c ) { return; } @@ -2955,12 +2909,10 @@ void sp_selection_to_marker(SPDesktop *desktop, bool apply) Geom::Point center( *c - corner ); // As defined by rotation center center[Geom::Y] = -center[Geom::Y]; - std::vector items(selection->items().begin(), selection->items().end()); - - //items = g_slist_sort(items, (GCompareFunc) sp_object_compare_position); // Why needed? + std::vector items_(items().begin(), items().end()); // bottommost object, after sorting - SPObject *parent = items.front()->parent; + SPObject *parent = items_.front()->parent; Geom::Affine parent_transform; { @@ -2974,17 +2926,17 @@ void sp_selection_to_marker(SPDesktop *desktop, bool apply) // Create a list of duplicates, to be pasted inside marker element. std::vector repr_copies; - for (std::vector::const_reverse_iterator i=items.rbegin();i!=items.rend();++i){ + for (std::vector::const_reverse_iterator i=items_.rbegin();i!=items_.rend();++i){ Inkscape::XML::Node *dup = (*i)->getRepr()->duplicate(xml_doc); repr_copies.push_back(dup); } - Geom::Rect bbox(desktop->dt2doc(r->min()), desktop->dt2doc(r->max())); + Geom::Rect bbox(desktop()->dt2doc(r->min()), desktop()->dt2doc(r->max())); if (apply) { // Delete objects so that their clones don't get alerted; // the objects will be restored inside the marker element. - for (std::vector::const_iterator i=items.begin();i!=items.end();++i){ + for (std::vector::const_iterator i=items_.begin();i!=items_.end();++i){ SPObject *item = *i; item->deleteObject(false); } @@ -3021,18 +2973,15 @@ static void sp_selection_to_guides_recursive(SPItem *item, bool wholegroups) { } } -void sp_selection_to_guides(SPDesktop *desktop) +void ObjectSet::toGuides() { - if (desktop == NULL) - return; - - SPDocument *doc = desktop->getDocument(); - Inkscape::Selection *selection = desktop->getSelection(); + SPDocument *doc = document(); // we need to copy the list because it gets reset when objects are deleted - std::vector items(selection->items().begin(), selection->items().end()); + std::vector items_(items().begin(), items().end()); - if (items.empty()) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to convert to guides.")); + if (isEmpty()) { + if(desktop()) + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to convert to guides.")); return; } @@ -3044,13 +2993,13 @@ void sp_selection_to_guides(SPDesktop *desktop) // and its entry in the selection list is invalid (crash). // Therefore: first convert all, then delete all. - for (std::vector::const_iterator i=items.begin();i!=items.end();++i){ + for (std::vector::const_iterator i=items_.begin();i!=items_.end();++i){ sp_selection_to_guides_recursive(*i, wholegroups); } if (deleteitems) { - selection->clear(); - sp_selection_delete_impl(items); + clear(); + sp_selection_delete_impl(items_); } DocumentUndo::done(doc, SP_VERB_EDIT_SELECTION_2_GUIDES, _("Objects to guides")); @@ -3076,38 +3025,34 @@ void sp_selection_to_guides(SPDesktop *desktop) * For SVG2, set 'refX' 'refY' to object center (with compensating shift in * transformation). */ -void sp_selection_symbol(SPDesktop *desktop, bool /*apply*/ ) +void ObjectSet::toSymbol() { - if (desktop == NULL) { - return; - } - SPDocument *doc = desktop->getDocument(); + SPDocument *doc = document(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = desktop->getSelection(); - // Check if something is selected. - if (selection->isEmpty()) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select objects to convert to symbol.")); + if (isEmpty()) { + if (desktop()) + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select objects to convert to symbol.")); return; } doc->ensureUpToDate(); - std::vector items(selection->objects().begin(), selection->objects().end()); - sort(items.begin(),items.end(),sp_object_compare_position_bool); + std::vector items_(objects().begin(), objects().end()); + sort(items_.begin(),items_.end(),sp_object_compare_position_bool); // Keep track of parent, this is where will be inserted. - Inkscape::XML::Node *the_first_repr = items[0]->getRepr(); + Inkscape::XML::Node *the_first_repr = items_[0]->getRepr(); Inkscape::XML::Node *the_parent_repr = the_first_repr->parent(); // Find out if we have a single group bool single_group = false; SPGroup *the_group = NULL; Geom::Affine transform; - if( items.size() == 1 ) { - SPObject *object = items[0]; + if( items_.size() == 1 ) { + SPObject *object = items_[0]; the_group = dynamic_cast(object); if ( the_group ) { single_group = true; @@ -3118,7 +3063,7 @@ void sp_selection_symbol(SPDesktop *desktop, bool /*apply*/ ) if( transform.isTranslation() ) { // Create new list from group children. - items = object->childList(false); + items_ = object->childList(false); // Hack: Temporarily set clone compensation to unmoved, so that we can move clone-originals // without disturbing clones. @@ -3162,7 +3107,7 @@ void sp_selection_symbol(SPDesktop *desktop, bool /*apply*/ ) } // Move selected items to new - for (std::vector::const_reverse_iterator i=items.rbegin();i!=items.rend();++i){ + for (std::vector::const_reverse_iterator i=items_.rbegin();i!=items_.rend();++i){ Inkscape::XML::Node *repr = (*i)->getRepr(); repr->parent()->removeChild(repr); symbol_repr->addChild(repr,NULL); @@ -3185,7 +3130,7 @@ void sp_selection_symbol(SPDesktop *desktop, bool /*apply*/ ) } // Change selection to new element. - selection->set(clone); + set(clone); // Clean up Inkscape::GC::release(symbol_repr); @@ -3196,29 +3141,25 @@ void sp_selection_symbol(SPDesktop *desktop, bool /*apply*/ ) /* * Convert to . All elements referencing symbol remain unchanged. */ -void sp_selection_unsymbol(SPDesktop *desktop) +void ObjectSet::unSymbol() { - if (desktop == NULL) { - return; - } - - SPDocument *doc = desktop->getDocument(); + SPDocument *doc = document(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = desktop->getSelection(); - // Check if something is selected. - if (selection->isEmpty()) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select a symbol to extract objects from.")); + if (isEmpty()) { + if(desktop()) + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select a symbol to extract objects from.")); return; } - SPObject* symbol = selection->single(); + SPObject* symbol = single(); // Make sure we have only one object in selection. // Require that we really have a . if( symbol == NULL || !dynamic_cast( symbol )) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select only one symbol in Symbol dialog to convert to group.")); + if(desktop()) + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select only one symbol in Symbol dialog to convert to group.")); return; } @@ -3226,7 +3167,7 @@ void sp_selection_unsymbol(SPDesktop *desktop) // Create new and insert in current layer Inkscape::XML::Node *group = xml_doc->createElement("svg:g"); - desktop->currentLayer()->getRepr()->appendChild(group); + symbol->parent->getRepr()->appendChild(group); // Move all children of symbol to group std::vector children = symbol->childList(false); @@ -3268,8 +3209,8 @@ void sp_selection_unsymbol(SPDesktop *desktop) symbol->deleteObject(true); // Change selection to new element. - SPItem *group_item = static_cast(desktop->getDocument()->getObjectByRepr(group)); - selection->set(group_item); + SPItem *group_item = static_cast(document()->getObjectByRepr(group)); + set(group_item); // Clean up Inkscape::GC::release(group); @@ -3277,27 +3218,24 @@ void sp_selection_unsymbol(SPDesktop *desktop) DocumentUndo::done(doc, SP_VERB_EDIT_UNSYMBOL, _("Group from symbol")); } -void -sp_selection_tile(SPDesktop *desktop, bool apply) +void ObjectSet::tile(bool apply) { - // sp_selection_to_marker has similar code - if (desktop == NULL) { + // toMarker has similar code + if (desktop() == NULL) { //same remark as in toMarker: no good reason to have this. return; } - SPDocument *doc = desktop->getDocument(); + SPDocument *doc = document(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = desktop->getSelection(); - // check if something is selected - if (selection->isEmpty()) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to convert to pattern.")); + if (isEmpty()) { + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to convert to pattern.")); return; } doc->ensureUpToDate(); - Geom::OptRect r = selection->visualBounds(); + Geom::OptRect r = visualBounds(); if ( !r ) { return; } @@ -3307,12 +3245,12 @@ sp_selection_tile(SPDesktop *desktop, bool apply) move_p[Geom::Y] = -move_p[Geom::Y]; Geom::Affine move = Geom::Affine(Geom::Translate(move_p)); - std::vector items(selection->items().begin(), selection->items().end()); + std::vector items_(items().begin(), items().end()); - sort(items.begin(),items.end(),sp_object_compare_position_bool); + sort(items_.begin(),items_.end(),sp_object_compare_position_bool); // bottommost object, after sorting - SPObject *parent = items[0]->parent; + SPObject *parent = items_[0]->parent; Geom::Affine parent_transform; @@ -3326,20 +3264,20 @@ sp_selection_tile(SPDesktop *desktop, bool apply) } // remember the position of the first item - gint pos = items[0]->getRepr()->position(); + gint pos = items_[0]->getRepr()->position(); // create a list of duplicates std::vector repr_copies; - for (std::vector::const_iterator i=items.begin();i!=items.end();++i){ + for (std::vector::const_iterator i=items_.begin();i!=items_.end();++i){ Inkscape::XML::Node *dup = (*i)->getRepr()->duplicate(xml_doc); repr_copies.push_back(dup); } - Geom::Rect bbox(desktop->dt2doc(r->min()), desktop->dt2doc(r->max())); + Geom::Rect bbox(desktop()->dt2doc(r->min()), desktop()->dt2doc(r->max())); if (apply) { // delete objects so that their clones don't get alerted; this object will be restored shortly - for (std::vector::const_iterator i=items.begin();i!=items.end();++i){ + for (std::vector::const_iterator i=items_.begin();i!=items_.end();++i){ SPObject *item = *i; item->deleteObject(false); } @@ -3353,7 +3291,7 @@ sp_selection_tile(SPDesktop *desktop, bool apply) prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); gchar const *pat_id = SPPattern::produce(repr_copies, bbox, doc, - ( Geom::Affine(Geom::Translate(desktop->dt2doc(Geom::Point(r->min()[Geom::X], + ( Geom::Affine(Geom::Translate(desktop()->dt2doc(Geom::Point(r->min()[Geom::X], r->max()[Geom::Y])))) * parent_transform.inverse() ), parent_transform * move); @@ -3378,12 +3316,12 @@ sp_selection_tile(SPDesktop *desktop, bool apply) // restore parent and position parent->getRepr()->appendChild(rect); rect->setPosition(pos > 0 ? pos : 0); - SPItem *rectangle = static_cast(desktop->getDocument()->getObjectByRepr(rect)); + SPItem *rectangle = static_cast(document()->getObjectByRepr(rect)); Inkscape::GC::release(rect); - selection->clear(); - selection->set(rectangle); + clear(); + set(rectangle); } @@ -3391,20 +3329,16 @@ sp_selection_tile(SPDesktop *desktop, bool apply) _("Objects to pattern")); } -void sp_selection_untile(SPDesktop *desktop) +void ObjectSet::untile() { - if (desktop == NULL) { - return; - } - SPDocument *doc = desktop->getDocument(); + SPDocument *doc = document(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = desktop->getSelection(); - // check if something is selected - if (selection->isEmpty()) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select an object with pattern fill to extract objects from.")); + if (isEmpty()) { + if(desktop()) + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select an object with pattern fill to extract objects from.")); return; } @@ -3412,8 +3346,8 @@ void sp_selection_untile(SPDesktop *desktop) bool did = false; - std::vector items(selection->items().begin(), selection->items().end()); - for (std::vector::const_reverse_iterator i=items.rbegin();i!=items.rend();++i){ + std::vector items_(items().begin(), items().end()); + for (std::vector::const_reverse_iterator i=items_.rbegin();i!=items_.rend();++i){ SPItem *item = *i; SPStyle *style = item->style; @@ -3438,7 +3372,7 @@ void sp_selection_untile(SPDesktop *desktop) for (auto& child: pattern->children) { if (dynamic_cast(&child)) { Inkscape::XML::Node *copy = child.getRepr()->duplicate(xml_doc); - SPItem *i = dynamic_cast(desktop->currentLayer()->appendChildRepr(copy)); + SPItem *i = dynamic_cast(item->parent->appendChildRepr(copy)); // FIXME: relink clones to the new canvas objects // use SPObject::setid when mental finishes it to steal ids of @@ -3463,21 +3397,22 @@ void sp_selection_untile(SPDesktop *desktop) } if (!did) { - desktop->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("No pattern fills in the selection.")); + if(desktop()) + desktop()->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("No pattern fills in the selection.")); } else { - DocumentUndo::done(desktop->getDocument(), SP_VERB_EDIT_UNTILE, + DocumentUndo::done(document(), SP_VERB_EDIT_UNTILE, _("Pattern to objects")); - selection->setList(new_select); + setList(new_select); } } -void sp_object_set_get_export_hints(ObjectSet *set, Glib::ustring &filename, float *xdpi, float *ydpi) +void ObjectSet::getExportHints(Glib::ustring &filename, float *xdpi, float *ydpi) { - if (set->isEmpty()) { + if (isEmpty()) { return; } - auto reprlst = set->xmlNodes(); + auto reprlst = xmlNodes(); bool filename_search = TRUE; bool xdpi_search = TRUE; bool ydpi_search = TRUE; @@ -3539,40 +3474,38 @@ void sp_document_get_export_hints(SPDocument *doc, Glib::ustring &filename, floa } } -void sp_selection_create_bitmap_copy(SPDesktop *desktop) +void ObjectSet::createBitmapCopy() { - if (desktop == NULL) { - return; - } - SPDocument *document = desktop->getDocument(); - Inkscape::XML::Document *xml_doc = document->getReprDoc(); - - Inkscape::Selection *selection = desktop->getSelection(); + SPDocument *doc = document(); + Inkscape::XML::Document *xml_doc = doc->getReprDoc(); // check if something is selected - if (selection->isEmpty()) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to make a bitmap copy.")); + if (isEmpty()) { + if(desktop()) + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to make a bitmap copy.")); return; } - - desktop->messageStack()->flash(Inkscape::IMMEDIATE_MESSAGE, _("Rendering bitmap...")); - // set "busy" cursor - desktop->setWaitingCursor(); + if(desktop()){ + desktop()->messageStack()->flash(Inkscape::IMMEDIATE_MESSAGE, _("Rendering bitmap...")); + // set "busy" cursor + desktop()->setWaitingCursor(); + } // Get the bounding box of the selection - document->ensureUpToDate(); - Geom::OptRect bbox = selection->visualBounds(); + doc->ensureUpToDate(); + Geom::OptRect bbox = visualBounds(); if (!bbox) { - desktop->clearWaitingCursor(); + if(desktop()) + desktop()->clearWaitingCursor(); return; // exceptional situation, so not bother with a translatable error message, just quit quietly } // List of the items to show; all others will be hidden - std::vector items(selection->items().begin(), selection->items().end()); + std::vector items_(items().begin(), items().end()); // Sort items so that the topmost comes last - sort(items.begin(),items.end(),sp_item_repr_compare_position_bool); + sort(items_.begin(),items_.end(),sp_item_repr_compare_position_bool); // Generate a random value from the current time (you may create bitmap from the same object(s) // multiple times, and this is done so that they don't clash) @@ -3582,8 +3515,8 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop) // Create the filename. gchar *const basename = g_strdup_printf("%s-%s-%u.png", - document->getName(), - items[0]->getRepr()->attribute("id"), + doc->getName(), + items_[0]->getRepr()->attribute("id"), current); // Imagemagick is known not to handle spaces in filenames, so we replace anything but letters, // digits, and a few other chars, with "_" @@ -3591,8 +3524,8 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop) // Build the complete path by adding document base dir, if set, otherwise home dir gchar *directory = NULL; - if ( document->getURI() ) { - directory = g_path_get_dirname( document->getURI() ); + if ( doc->getURI() ) { + directory = g_path_get_dirname( doc->getURI() ); } if (directory == NULL) { directory = INKSCAPE.homedir_path(NULL); @@ -3603,8 +3536,8 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop) //g_print("%s\n", filepath); // Remember parent and z-order of the topmost one - gint pos = items.back()->getRepr()->position(); - SPObject *parent_object = items.back()->parent; + gint pos = items_.back()->getRepr()->position(); + SPObject *parent_object = items_.back()->parent; Inkscape::XML::Node *parent = parent_object->getRepr(); // Calculate resolution @@ -3622,12 +3555,12 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop) float hint_xdpi = 0, hint_ydpi = 0; Glib::ustring hint_filename; // take resolution hint from the selected objects - sp_object_set_get_export_hints(selection, hint_filename, &hint_xdpi, &hint_ydpi); + getExportHints(hint_filename, &hint_xdpi, &hint_ydpi); if (hint_xdpi != 0) { res = hint_xdpi; } else { // take resolution hint from the document - sp_document_get_export_hints(document, hint_filename, &hint_xdpi, &hint_ydpi); + sp_document_get_export_hints(doc, hint_filename, &hint_xdpi, &hint_ydpi); if (hint_xdpi != 0) { res = hint_xdpi; } else { @@ -3687,14 +3620,14 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop) // TODO: avoid roundtrip via file // Do the export - sp_export_png_file(document, filepath, + sp_export_png_file(doc, filepath, bbox->min()[Geom::X], bbox->min()[Geom::Y], bbox->max()[Geom::X], bbox->max()[Geom::Y], width, height, res, res, (guint32) 0xffffff00, NULL, NULL, true, /*bool force_overwrite,*/ - items); + items_); // Run filter, if any if (run) { @@ -3732,19 +3665,19 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop) repr->setPosition(pos > 0 ? pos + 1 : 1); // Set selection to the new image - selection->clear(); - selection->add(repr); + clear(); + add(repr); // Clean up Inkscape::GC::release(repr); g_object_unref(pb); // Complete undoable transaction - DocumentUndo::done(document, SP_VERB_SELECTION_CREATE_BITMAP, + DocumentUndo::done(doc, SP_VERB_SELECTION_CREATE_BITMAP, _("Create bitmap")); } - - desktop->clearWaitingCursor(); + if(desktop()) + desktop()->clearWaitingCursor(); g_free(basename); g_free(filepath); @@ -3756,25 +3689,22 @@ void sp_selection_create_bitmap_copy(SPDesktop *desktop) * to clip the entire group using a few s and generally irritating me. */ -void sp_selection_set_clipgroup(SPDesktop *desktop) +void ObjectSet::setClipGroup() { - if (desktop == NULL) { - return; - } - SPDocument* doc = desktop->getDocument(); + SPDocument* doc = document(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = desktop->getSelection(); - if (selection->isEmpty()) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to create clippath or mask from.")); + if (isEmpty()) { + if(desktop()) + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to create clippath or mask from.")); return; } - std::vector p(selection->xmlNodes().begin(), selection->xmlNodes().end()); + std::vector p(xmlNodes().begin(), xmlNodes().end()); sort(p.begin(),p.end(),sp_repr_compare_position_bool); - selection->clear(); + clear(); int topmost = (p.back())->position(); Inkscape::XML::Node *topmost_parent = (p.back())->parent(); @@ -3851,7 +3781,7 @@ void sp_selection_set_clipgroup(SPDesktop *desktop) Inkscape::GC::release(clone); - selection->set(outer); + set(outer); DocumentUndo::done(doc, SP_VERB_OBJECT_SET_CLIPPATH, _("Create Clip Group")); } @@ -3864,30 +3794,29 @@ void sp_selection_set_clipgroup(SPDesktop *desktop) * If \a apply_clip_path parameter is true, clipPath is created, otherwise mask * */ -void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_to_layer, bool skip_undo) + void ObjectSet::setMask(bool apply_clip_path, bool apply_to_layer, bool skip_undo) { - if (desktop == NULL) { + if(!desktop() && apply_to_layer) return; - } - SPDocument *doc = desktop->getDocument(); + SPDocument *doc = document(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = desktop->getSelection(); - // check if something is selected - bool is_empty = selection->isEmpty(); + bool is_empty = isEmpty(); if ( apply_to_layer && is_empty) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to create clippath or mask from.")); + if(desktop()) + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to create clippath or mask from.")); return; - } else if (!apply_to_layer && ( is_empty || boost::distance(selection->items())==1 )) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select mask object and object(s) to apply clippath or mask to.")); + } else if (!apply_to_layer && ( is_empty || boost::distance(items())==1 )) { + if(desktop()) + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select mask object and object(s) to apply clippath or mask to.")); return; } // FIXME: temporary patch to prevent crash! // Remove this when bboxes are fixed to not blow up on an item clipped/masked with its own clone - bool clone_with_original = object_set_contains_both_clone_and_original(selection); + bool clone_with_original = object_set_contains_both_clone_and_original(this); if (clone_with_original) { return; // in this version, you cannot clip/mask an object with its own clone } @@ -3895,12 +3824,12 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ doc->ensureUpToDate(); - std::vector items(selection->items().begin(), selection->items().end()); + std::vector items_(items().begin(), items().end()); - sort(items.begin(),items.end(),sp_object_compare_position_bool); + sort(items_.begin(),items_.end(),sp_object_compare_position_bool); // See lp bug #542004 - selection->clear(); + clear(); // create a list of duplicates std::vector mask_items; @@ -3915,12 +3844,12 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ if (apply_to_layer) { // all selected items are used for mask, which is applied to a layer - apply_to_items.push_back(SP_ITEM(desktop->currentLayer())); + apply_to_items.push_back(SP_ITEM(desktop()->currentLayer())); } - for (std::vector::const_iterator i=items.begin();i!=items.end();++i) { - if((!topmost && !apply_to_layer && *i == items.front()) - || (topmost && !apply_to_layer && *i == items.back()) + for (std::vector::const_iterator i=items_.begin();i!=items_.end();++i) { + if((!topmost && !apply_to_layer && *i == items_.front()) + || (topmost && !apply_to_layer && *i == items_.back()) || apply_to_layer){ Geom::Affine oldtr=(*i)->transform; @@ -3942,17 +3871,17 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ } } - items.clear(); + items_.clear(); if (grouping == PREFS_MASKOBJECT_GROUPING_ALL) { // group all those objects into one group // and apply mask to that - ObjectSet* set = new ObjectSet(selection->desktop()); + ObjectSet* set = new ObjectSet(document()); set->add(apply_to_items.begin(), apply_to_items.end()); items_to_select.clear(); - Inkscape::XML::Node *group = sp_object_set_group(set); + Inkscape::XML::Node *group = set->group(); group->setAttribute("inkscape:groupmode", "maskhelper"); // apply clip/mask only to newly created group @@ -4018,10 +3947,10 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ for (std::vector::const_iterator i = items_to_delete.begin(); i != items_to_delete.end(); ++i) { SPObject *item = reinterpret_cast(*i); item->deleteObject(false); - items_to_select.erase(remove(items_to_select.begin(), items_to_select.end(), item), items_to_select.end()); + items_to_select.erase(std::remove(items_to_select.begin(), items_to_select.end(), item), items_to_select.end()); } - selection->addList(items_to_select); + addList(items_to_select); if (!skip_undo) { if (apply_clip_path) { DocumentUndo::done(doc, SP_VERB_OBJECT_SET_CLIPPATH, _("Set clipping path")); @@ -4031,18 +3960,14 @@ void sp_selection_set_mask(SPDesktop *desktop, bool apply_clip_path, bool apply_ } } -void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) { - if (desktop == NULL) { - return; - } - - SPDocument *doc = desktop->getDocument(); +void ObjectSet::unsetMask(bool apply_clip_path) { + SPDocument *doc = document(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); - Inkscape::Selection *selection = desktop->getSelection(); // check if something is selected - if (selection->isEmpty()) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to remove clippath or mask from.")); + if (isEmpty()) { + if(desktop()) + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to remove clippath or mask from.")); return; } @@ -4054,16 +3979,16 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) { gchar const *attributeName = apply_clip_path ? "clip-path" : "mask"; std::map referenced_objects; - std::vector items(selection->items().begin(), selection->items().end()); - selection->clear(); + std::vector items_(items().begin(), items().end()); + clear(); GSList *items_to_ungroup = NULL; - std::vector items_to_select(items); + std::vector items_to_select(items_); // SPObject* refers to a group containing the clipped path or mask itself, // whereas SPItem* refers to the item being clipped or masked - for (std::vector::const_iterator i=items.begin();i!=items.end();++i){ + for (std::vector::const_iterator i=items_.begin();i!=items_.end();++i){ if (remove_original) { // remember referenced mask/clippath, so orphaned masks can be moved back to document SPItem *item = *i; @@ -4127,7 +4052,7 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) { parent->appendChild(repr); repr->setPosition((pos + 1) > 0 ? (pos + 1) : 0); - SPItem *mask_item = static_cast(desktop->getDocument()->getObjectByRepr(repr)); + SPItem *mask_item = static_cast(document()->getObjectByRepr(repr)); items_to_select.push_back(mask_item); // transform mask, so it is moved the same spot where mask was applied @@ -4143,7 +4068,7 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) { for (GSList *i = items_to_ungroup ; NULL != i ; i = i->next) { SPGroup *group = dynamic_cast(static_cast(i->data)); if (group) { - items_to_select.erase(remove(items_to_select.begin(), items_to_select.end(), group), items_to_select.end()); + items_to_select.erase(std::remove(items_to_select.begin(), items_to_select.end(), group), items_to_select.end()); std::vector children; sp_item_group_ungroup(group, children, false); items_to_select.insert(items_to_select.end(),children.rbegin(),children.rend()); @@ -4155,7 +4080,7 @@ void sp_selection_unset_mask(SPDesktop *desktop, bool apply_clip_path) { g_slist_free(items_to_ungroup); // rebuild selection - selection->addList(items_to_select); + addList(items_to_select); if (apply_clip_path) { DocumentUndo::done(doc, SP_VERB_OBJECT_UNSET_CLIPPATH, _("Release clipping path")); -- cgit v1.2.3 From 3649ef4c620b9eae5132d89a39ebd280d9dc50a8 Mon Sep 17 00:00:00 2001 From: Alexander Brock Date: Thu, 27 Oct 2016 19:13:05 +0200 Subject: Add recursive clone unlink feature (bzr r15191.1.1) --- src/selection-chemistry.cpp | 276 ++++++++++++++++++++++++++++---------------- 1 file changed, 178 insertions(+), 98 deletions(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 2f9e72e2c..b4654909a 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -124,8 +124,8 @@ selection_display_message(SPDesktop *desktop, Inkscape::MessageType msgType, Gli desktop->messageStack()->flash(msgType, msg); } else { if (msgType == Inkscape::IMMEDIATE_MESSAGE || - msgType == Inkscape::WARNING_MESSAGE || - msgType == Inkscape::ERROR_MESSAGE) { + msgType == Inkscape::WARNING_MESSAGE || + msgType == Inkscape::ERROR_MESSAGE) { g_printerr("%s\n", msg.c_str()); } } @@ -273,8 +273,8 @@ void SelectionHelper::fixSelection(SPDesktop *dt) for(auto i = boost::rbegin(selList); i != boost::rend(selList); ++i) { SPItem *item = *i; if( item && - !dt->isLayer(item) && - (!item->isLocked())) + !dt->isLayer(item) && + (!item->isLocked())) { items.push_back(item); } @@ -378,19 +378,19 @@ static void sp_selection_delete_impl(std::vector const &items, bool pro void ObjectSet::deleteItems() { if(desktop() && tools_isactive(desktop(), TOOLS_TEXT)){ - if (Inkscape::UI::Tools::sp_text_delete_selection(desktop()->event_context)) { + if (Inkscape::UI::Tools::sp_text_delete_selection(desktop()->event_context)) { DocumentUndo::done(desktop()->getDocument(), SP_VERB_CONTEXT_TEXT, _("Delete text")); return; - } + } } - if (isEmpty()) { - selection_display_message(desktop(),Inkscape::WARNING_MESSAGE, _("Nothing was deleted.")); + if (isEmpty()) { + selection_display_message(desktop(),Inkscape::WARNING_MESSAGE, _("Nothing was deleted.")); return; } std::vector selected(items().begin(), items().end()); - clear(); + clear(); sp_selection_delete_impl(selected); if(SPDesktop *d = desktop()){ d->currentLayer()->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); @@ -404,7 +404,7 @@ void ObjectSet::deleteItems() tools_switch( d, tools_active( d ) ); } if(document()) - DocumentUndo::done(document(), SP_VERB_EDIT_DELETE, + DocumentUndo::done(document(), SP_VERB_EDIT_DELETE, _("Delete")); } @@ -430,7 +430,7 @@ void ObjectSet::duplicate(bool suppressDone, bool duplicateLayer) //TODO: understand why layer management is tied to desktop and not to document. return; } - + SPDocument *doc = document(); if(!doc) @@ -586,11 +586,11 @@ std::vector &get_all_items(std::vector &list, SPObject *from, for (auto& child: from->children) { SPItem *item = dynamic_cast(&child); if (item && - !desktop->isLayer(item) && - (!onlysensitive || !item->isLocked()) && - (!onlyvisible || !desktop->itemIsHidden(item)) && - (exclude.empty() || exclude.end() == std::find(exclude.begin(), exclude.end(), &child)) - ) + !desktop->isLayer(item) && + (!onlysensitive || !item->isLocked()) && + (!onlyvisible || !desktop->itemIsHidden(item)) && + (exclude.empty() || exclude.end() == std::find(exclude.begin(), exclude.end(), &child)) + ) { list.insert(list.begin(),item); } @@ -628,10 +628,10 @@ static void sp_edit_select_all_full(SPDesktop *dt, bool force_all_layers, bool i inlayer = PREFS_SELECTION_ALL; switch (inlayer) { - case PREFS_SELECTION_LAYER: { + case PREFS_SELECTION_LAYER: { if ( (onlysensitive && dynamic_cast(dt->currentLayer())->isLocked()) || (onlyvisible && dt->itemIsHidden(dynamic_cast(dt->currentLayer()))) ) - return; + return; std::vector all_items = sp_item_group_item_list(dynamic_cast(dt->currentLayer())); @@ -649,17 +649,17 @@ static void sp_edit_select_all_full(SPDesktop *dt, bool force_all_layers, bool i } } - break; - } - case PREFS_SELECTION_LAYER_RECURSIVE: { - std::vector x; - items = get_all_items(x, dt->currentLayer(), dt, onlyvisible, onlysensitive, FALSE, exclude); - break; - } - default: { - std::vector x; - items = get_all_items(x, dt->currentRoot(), dt, onlyvisible, onlysensitive, FALSE, exclude); - break; + break; + } + case PREFS_SELECTION_LAYER_RECURSIVE: { + std::vector x; + items = get_all_items(x, dt->currentLayer(), dt, onlyvisible, onlysensitive, FALSE, exclude); + break; + } + default: { + std::vector x; + items = get_all_items(x, dt->currentRoot(), dt, onlyvisible, onlysensitive, FALSE, exclude); + break; } } @@ -787,7 +787,7 @@ void ObjectSet::popFromGroup(){ } auto item = items().begin(); // leaving this because it will be useful for - // future implementation of complex pop ungrouping + // future implementation of complex pop ungrouping SPItem *obj = *item; SPItem *parent_group = static_cast(obj->parent); if (!SP_IS_GROUP(parent_group) || SP_IS_LAYER(parent_group)) { @@ -806,7 +806,7 @@ void ObjectSet::popFromGroup(){ if(document()) DocumentUndo::done(document(), SP_VERB_SELECTION_UNGROUP_POP_SELECTION, - _("Pop selection from group")); + _("Pop selection from group")); } @@ -883,7 +883,7 @@ void ObjectSet::ungroup() ungroup_impl(this); if(document()) DocumentUndo::done(document(), SP_VERB_SELECTION_UNGROUP, - _("Ungroup")); + _("Ungroup")); } // TODO replace it with ObjectSet::degroup_list @@ -964,7 +964,7 @@ static SPObject *prev_sibling(SPObject *child) bool sp_item_repr_compare_position_bool(SPObject const *first, SPObject const *second) { return sp_repr_compare_position(((SPItem*)first)->getRepr(), - ((SPItem*)second)->getRepr())<0; + ((SPItem*)second)->getRepr())<0; } void ObjectSet::raise(bool skip_undo){ @@ -1015,8 +1015,8 @@ void ObjectSet::raise(bool skip_undo){ } if(document() && !skip_undo) DocumentUndo::done(document(), SP_VERB_SELECTION_RAISE, - //TRANSLATORS: "Raise" means "to raise an object" in the undo history - C_("Undo action", "Raise")); + //TRANSLATORS: "Raise" means "to raise an object" in the undo history + C_("Undo action", "Raise")); } @@ -1042,7 +1042,7 @@ void ObjectSet::raiseToTop(bool skip_undo) { } if (document() && !skip_undo) { DocumentUndo::done(document(), SP_VERB_SELECTION_TO_FRONT, - _("Raise to top")); + _("Raise to top")); } } @@ -1096,8 +1096,8 @@ void ObjectSet::lower(bool skip_undo){ } if(document() && !skip_undo) DocumentUndo::done(document(), SP_VERB_SELECTION_LOWER, - //TRANSLATORS: "Lower" means "to lower an object" in the undo history - C_("Undo action", "Lower")); + //TRANSLATORS: "Lower" means "to lower an object" in the undo history + C_("Undo action", "Lower")); } @@ -1183,7 +1183,7 @@ take_style_from_item(SPObject *object) return NULL; if ((dynamic_cast(object) && object->firstChild()) || - (dynamic_cast(object) && object->firstChild() && object->firstChild()->getNext() == NULL)) { + (dynamic_cast(object) && object->firstChild() && object->firstChild()->getNext() == NULL)) { // if this is a text with exactly one tspan child, merge the style of that tspan as well // If this is a group, merge the style of its topmost (last) child with style auto list = object->children | boost::adaptors::reversed; @@ -1268,7 +1268,7 @@ void ObjectSet::removeLPE() // check if something is selected if (isEmpty()) { if(desktop()) - desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to remove live path effects from.")); + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to remove live path effects from.")); return; } auto list= items(); @@ -1281,7 +1281,7 @@ void ObjectSet::removeLPE() if(document()) DocumentUndo::done(document(), SP_VERB_EDIT_REMOVE_LIVEPATHEFFECT, - _("Remove live path effect")); + _("Remove live path effect")); } void ObjectSet::removeFilter() @@ -1300,7 +1300,7 @@ void ObjectSet::removeFilter() sp_repr_css_attr_unref(css); if(document()) DocumentUndo::done(document(), SP_VERB_EDIT_REMOVE_FILTER, - _("Remove filter")); + _("Remove filter")); } @@ -1334,8 +1334,8 @@ void sp_selection_change_layer_maintain_clones(std::vector const &items SPItem *oldparent = dynamic_cast(item->parent); SPItem *newparent = dynamic_cast(where); sp_item_group_ungroup_handle_clones(item, - (oldparent->i2doc_affine()) - *((newparent->i2doc_affine()).inverse())); + (oldparent->i2doc_affine()) + *((newparent->i2doc_affine()).inverse())); } } } @@ -1345,7 +1345,7 @@ void ObjectSet::toNextLayer(bool skip_undo) if(!desktop()) return; SPDesktop *dt=desktop(); //TODO make it desktop-independent - + // check if something is selected if (isEmpty()) { dt->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to move to the layer above.")); @@ -1515,7 +1515,7 @@ then simply updates the repr from item->transform. */ void ObjectSet::applyAffine(Geom::Affine const &affine, bool set_i2d, bool compensate, - bool adjust_transf_center) + bool adjust_transf_center) { if (isEmpty()) return; @@ -1559,7 +1559,7 @@ void ObjectSet::applyAffine(Geom::Affine const &affine, bool set_i2d, bool compe old_center = item->getCenter(); #if 0 /* Re-enable this once persistent guides have a graphical indication. - At the time of writing, this is the only place to re-enable. */ + At the time of writing, this is the only place to re-enable. */ sp_item_update_cns(*item, desktop()); #endif @@ -1716,7 +1716,7 @@ void ObjectSet::removeTransform() if(document()) DocumentUndo::done(document(), SP_VERB_OBJECT_FLATTEN, - _("Remove transform")); + _("Remove transform")); } void ObjectSet::setScaleAbsolute(double x0, double x1,double y0, double y1) @@ -1955,20 +1955,20 @@ std::vector sp_get_same_fill_or_stroke_color(SPItem *sel, std::vectorstyle->fill) : &(iter->style->stroke); match = false; if (sel_paint->isColor() && iter_paint->isColor() // color == color comparision doesnt seem to work here. - && (sel_paint->value.color.toRGBA32(1.0) == iter_paint->value.color.toRGBA32(1.0))) { + && (sel_paint->value.color.toRGBA32(1.0) == iter_paint->value.color.toRGBA32(1.0))) { match = true; } else if (sel_paint->isPaintserver() && iter_paint->isPaintserver()) { SPPaintServer *sel_server = - (type == SP_FILL_COLOR) ? sel->style->getFillPaintServer() : sel->style->getStrokePaintServer(); + (type == SP_FILL_COLOR) ? sel->style->getFillPaintServer() : sel->style->getStrokePaintServer(); SPPaintServer *iter_server = - (type == SP_FILL_COLOR) ? iter->style->getFillPaintServer() : iter->style->getStrokePaintServer(); + (type == SP_FILL_COLOR) ? iter->style->getFillPaintServer() : iter->style->getStrokePaintServer(); if ((dynamic_cast(sel_server) || dynamic_cast(sel_server) || (dynamic_cast(sel_server) && dynamic_cast(sel_server)->getVector()->isSwatch())) - && - (dynamic_cast(iter_server) || dynamic_cast(iter_server) || - (dynamic_cast(iter_server) && dynamic_cast(iter_server)->getVector()->isSwatch()))) { + && + (dynamic_cast(iter_server) || dynamic_cast(iter_server) || + (dynamic_cast(iter_server) && dynamic_cast(iter_server)->getVector()->isSwatch()))) { SPGradient *sel_vector = dynamic_cast(sel_server)->getVector(); SPGradient *iter_vector = dynamic_cast(iter_server)->getVector(); if (sel_vector == iter_vector) { @@ -2119,7 +2119,7 @@ std::vector sp_get_same_style(SPItem *sel, std::vector &src, S for (int i = 0; i < len; i++) { match = (sel_style->marker_ptrs[i]->set == iter_style->marker_ptrs[i]->set); if (sel_style->marker_ptrs[i]->set && iter_style->marker_ptrs[i]->set && - (strcmp(sel_style->marker_ptrs[i]->value, iter_style->marker_ptrs[i]->value))) { + (strcmp(sel_style->marker_ptrs[i]->value, iter_style->marker_ptrs[i]->value))) { match = false; break; } @@ -2652,13 +2652,88 @@ void ObjectSet::relink() } } +bool ObjectSet::unlinkRecursive() { + bool unlinked = false; + // Main part when called from the GUI. + ObjectSet tmp_set(document()); + if (desktop() || size() > 1) { + if (isEmpty()) { + if (desktop()) { + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select clones to unlink.")); + } + return false; + } + + std::vector items_(items().begin(), items().end()); + for (auto& it : items_) { + tmp_set.set(it); + if (tmp_set.unlinkRecursive()) { + unlinked = true; + } + it = tmp_set.singleItem(); + assert(it); + } + + if (!unlinked && desktop()) { + desktop()->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("No clones to unlink in the selection.")); + } + + DocumentUndo::done(document(), SP_VERB_EDIT_UNLINK_CLONE, + _("Unlink resursively clone")); + return unlinked; + } + // Part when called recursively + assert(NULL == desktop()); + assert (1 == size()); + if (unlink(true)) { + unlinked = true; + } + SPItem* item = singleItem(); + // Check if a clip is set, in that case unset the clip, unlink all clones and set the clip again. + Inkscape::URIReference *clip = item->clip_ref; + if ((NULL != clip) && (NULL != clip->getObject())) { + tmp_set.set(item); + tmp_set.unsetMask(true, true); + std::vector items(tmp_set.items().begin(), tmp_set.items().end()); + std::vector new_items; + for (SPItem * it : items) { + tmp_set.set(it); + if (tmp_set.unlinkRecursive()) { + unlinked = true; + } + it = tmp_set.singleItem(); + assert(it); + new_items.push_back(it); + } + tmp_set.setList(new_items); + tmp_set.setMask(true, false, true); + item = tmp_set.singleItem(); + g_assert(item); + } + + if (SP_IS_GROUP(item)) { + for (SPObject *o = item->firstChild(); o != NULL; ) { + SPObject* next = o->getNext(); + SPItem * child_item = dynamic_cast(o); + if (child_item) { + tmp_set.set(child_item); + if(tmp_set.unlinkRecursive()) { + unlinked = true; + } + } + o = next; + } + } + + return unlinked; +} -void ObjectSet::unlink() +bool ObjectSet::unlink(bool skip_undo) { if (isEmpty()) { if(desktop()) desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select clones to unlink.")); - return; + return false; } // Get a copy of current selection. @@ -2715,8 +2790,11 @@ void ObjectSet::unlink() desktop()->messageStack()->flash(Inkscape::ERROR_MESSAGE, _("No clones to unlink in the selection.")); } - DocumentUndo::done(document(), SP_VERB_EDIT_UNLINK_CLONE, - _("Unlink clone")); + if (!skip_undo) { + DocumentUndo::done(document(), SP_VERB_EDIT_UNLINK_CLONE, + _("Unlink clone")); + } + return unlinked; } void ObjectSet::cloneOriginal() @@ -2876,8 +2954,8 @@ void ObjectSet::cloneOriginalPathLPE() void ObjectSet::toMarker(bool apply) { // sp_selection_tile has similar code - if (desktop() == NULL) { // TODO: We should not need desktop for that. - // Someone get rid of the dt2doc() call. + if (desktop() == NULL) { // TODO: We should not need desktop for that. + // Someone get rid of the dt2doc() call. return; } @@ -2901,7 +2979,7 @@ void ObjectSet::toMarker(bool apply) Geom::Point doc_height( 0, doc->getHeight().value("px")); // calculate the transform to be applied to objects to move them to 0,0 - Geom::Point corner( r->min()[Geom::X], r->max()[Geom::Y] ); // FIXME: Inverted Y coodinate + Geom::Point corner( r->min()[Geom::X], r->max()[Geom::Y] ); // FIXME: Inverted Y coodinate Geom::Point move_p = doc_height - corner; move_p[Geom::Y] = -move_p[Geom::Y]; Geom::Affine move = Geom::Affine(Geom::Translate(move_p)); @@ -3007,7 +3085,7 @@ void ObjectSet::toGuides() /* * Convert objects to . How that happens depends on what is selected: - * + * * 1) A random selection of objects will be embedded into a single element. * * 2) Except, a single will have its content directly embedded into a ; the 'id' and @@ -3033,9 +3111,9 @@ void ObjectSet::toSymbol() // Check if something is selected. if (isEmpty()) { - if (desktop()) - desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select objects to convert to symbol.")); - return; + if (desktop()) + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select objects to convert to symbol.")); + return; } doc->ensureUpToDate(); @@ -3108,9 +3186,9 @@ void ObjectSet::toSymbol() // Move selected items to new for (std::vector::const_reverse_iterator i=items_.rbegin();i!=items_.rend();++i){ - Inkscape::XML::Node *repr = (*i)->getRepr(); - repr->parent()->removeChild(repr); - symbol_repr->addChild(repr,NULL); + Inkscape::XML::Node *repr = (*i)->getRepr(); + repr->parent()->removeChild(repr); + symbol_repr->addChild(repr,NULL); } if( single_group && transform.isTranslation() ) { @@ -3154,7 +3232,7 @@ void ObjectSet::unSymbol() } SPObject* symbol = single(); - + // Make sure we have only one object in selection. // Require that we really have a . if( symbol == NULL || !dynamic_cast( symbol )) { @@ -3179,14 +3257,14 @@ void ObjectSet::unSymbol() SPObject *object = children[0]; if ( dynamic_cast( object ) ) { if( object->getAttribute("style") == NULL || - object->getAttribute("class") == NULL ) { + object->getAttribute("class") == NULL ) { group->setAttribute("transform", object->getAttribute("transform")); children = object->childList(false); } } } - + for (std::vector::const_reverse_iterator i=children.rbegin();i!=children.rend();++i){ Inkscape::XML::Node *repr = (*i)->getRepr(); repr->parent()->removeChild(repr); @@ -3291,10 +3369,10 @@ void ObjectSet::tile(bool apply) prefs->setInt("/options/clonecompensation/value", SP_CLONE_COMPENSATION_UNMOVED); gchar const *pat_id = SPPattern::produce(repr_copies, bbox, doc, - ( Geom::Affine(Geom::Translate(desktop()->dt2doc(Geom::Point(r->min()[Geom::X], - r->max()[Geom::Y])))) - * parent_transform.inverse() ), - parent_transform * move); + ( Geom::Affine(Geom::Translate(desktop()->dt2doc(Geom::Point(r->min()[Geom::X], + r->max()[Geom::Y])))) + * parent_transform.inverse() ), + parent_transform * move); // restore compensation setting prefs->setInt("/options/clonecompensation/value", saved_compensation); @@ -3374,8 +3452,8 @@ void ObjectSet::untile() Inkscape::XML::Node *copy = child.getRepr()->duplicate(xml_doc); SPItem *i = dynamic_cast(item->parent->appendChildRepr(copy)); - // FIXME: relink clones to the new canvas objects - // use SPObject::setid when mental finishes it to steal ids of + // FIXME: relink clones to the new canvas objects + // use SPObject::setid when mental finishes it to steal ids of // this is needed to make sure the new item has curve (simply requestDisplayUpdate does not work) doc->ensureUpToDate(); @@ -3517,7 +3595,7 @@ void ObjectSet::createBitmapCopy() gchar *const basename = g_strdup_printf("%s-%s-%u.png", doc->getName(), items_[0]->getRepr()->attribute("id"), - current); + current); // Imagemagick is known not to handle spaces in filenames, so we replace anything but letters, // digits, and a few other chars, with "_" g_strcanon(basename, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.=+~$#@^&!?", '_'); @@ -3622,12 +3700,12 @@ void ObjectSet::createBitmapCopy() // Do the export sp_export_png_file(doc, filepath, bbox->min()[Geom::X], bbox->min()[Geom::Y], - bbox->max()[Geom::X], bbox->max()[Geom::Y], - width, height, res, res, - (guint32) 0xffffff00, - NULL, NULL, - true, /*bool force_overwrite,*/ - items_); + bbox->max()[Geom::X], bbox->max()[Geom::Y], + width, height, res, res, + (guint32) 0xffffff00, + NULL, NULL, + true, /*bool force_overwrite,*/ + items_); // Run filter, if any if (run) { @@ -3699,7 +3777,7 @@ void ObjectSet::setClipGroup() desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to create clippath or mask from.")); return; } - + std::vector p(xmlNodes().begin(), xmlNodes().end()); sort(p.begin(),p.end(),sp_repr_compare_position_bool); @@ -3794,7 +3872,7 @@ void ObjectSet::setClipGroup() * If \a apply_clip_path parameter is true, clipPath is created, otherwise mask * */ - void ObjectSet::setMask(bool apply_clip_path, bool apply_to_layer, bool skip_undo) +void ObjectSet::setMask(bool apply_clip_path, bool apply_to_layer, bool skip_undo) { if(!desktop() && apply_to_layer) return; @@ -3960,7 +4038,7 @@ void ObjectSet::setClipGroup() } } -void ObjectSet::unsetMask(bool apply_clip_path) { +void ObjectSet::unsetMask(const bool apply_clip_path, const bool skip_undo) { SPDocument *doc = document(); Inkscape::XML::Document *xml_doc = doc->getReprDoc(); @@ -4010,13 +4088,13 @@ void ObjectSet::unsetMask(bool apply_clip_path) { SPGroup *group = dynamic_cast(*i); if (ungroup_masked && group) { - // if we had previously enclosed masked object in group, - // add it to list so we can ungroup it later + // if we had previously enclosed masked object in group, + // add it to list so we can ungroup it later - // ungroup only groups we created when setting clip/mask - if (group->layerMode() == SPGroup::MASK_HELPER) { - items_to_ungroup = g_slist_prepend(items_to_ungroup, group); - } + // ungroup only groups we created when setting clip/mask + if (group->layerMode() == SPGroup::MASK_HELPER) { + items_to_ungroup = g_slist_prepend(items_to_ungroup, group); + } } } @@ -4082,10 +4160,12 @@ void ObjectSet::unsetMask(bool apply_clip_path) { // rebuild selection addList(items_to_select); - if (apply_clip_path) { - DocumentUndo::done(doc, SP_VERB_OBJECT_UNSET_CLIPPATH, _("Release clipping path")); - } else { - DocumentUndo::done(doc, SP_VERB_OBJECT_UNSET_MASK, _("Release mask")); + if (!skip_undo) { + if (apply_clip_path) { + DocumentUndo::done(doc, SP_VERB_OBJECT_UNSET_CLIPPATH, _("Release clipping path")); + } else { + DocumentUndo::done(doc, SP_VERB_OBJECT_UNSET_MASK, _("Release mask")); + } } } -- cgit v1.2.3 From 6162cf1a9f6953319e0e3d6b56354c5cb0f26352 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Thu, 3 Nov 2016 00:08:41 +0100 Subject: Add some unit tests for object-set cppification (bzr r15203) --- src/selection-chemistry.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 2f9e72e2c..2db059afe 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -946,7 +946,7 @@ enclose_items(std::vector const &items) Geom::OptRect r; for (std::vector::const_iterator i = items.begin();i!=items.end();++i) { - r.unionWith((*i)->desktopVisualBounds()); + r.unionWith((*i)->documentVisualBounds()); } return r; } @@ -1000,7 +1000,7 @@ void ObjectSet::raise(bool skip_undo){ // if the sibling is an item AND overlaps our selection, SPItem *newItem = dynamic_cast(newref); if (newItem) { - Geom::OptRect newref_bbox = newItem->desktopVisualBounds(); + Geom::OptRect newref_bbox = newItem->documentVisualBounds(); if ( newref_bbox && selected->intersects(*newref_bbox) ) { // AND if it's not one of our selected objects, if ( std::find(items_copy.begin(),items_copy.end(),newref)==items_copy.end()) { @@ -1077,7 +1077,7 @@ void ObjectSet::lower(bool skip_undo){ // if the sibling is an item AND overlaps our selection, SPItem *newItem = dynamic_cast(newref); if (newItem) { - Geom::OptRect ref_bbox = newItem->desktopVisualBounds(); + Geom::OptRect ref_bbox = newItem->documentVisualBounds(); if ( ref_bbox && selected->intersects(*ref_bbox) ) { // AND if it's not one of our selected objects, if (items_copy.end()==std::find(items_copy.begin(),items_copy.end(),newref)) { -- cgit v1.2.3 From 428acb542d830f86b6f506d762d9b15bb2b7beeb Mon Sep 17 00:00:00 2001 From: Alexander Brock Date: Fri, 4 Nov 2016 16:04:31 +0100 Subject: Preserve clips when unlinking clones (bzr r15204.1.2) --- src/selection-chemistry.cpp | 79 +++++++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 27 deletions(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 8639486d5..0b99fd7c4 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -2669,41 +2669,66 @@ bool ObjectSet::unlink(const bool skip_undo) for (auto i=items_.rbegin();i!=items_.rend();++i){ SPItem *item = *i; - if (dynamic_cast(item)) { - SPObject *tspan = sp_tref_convert_to_tspan(item); - - if (tspan) { - item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); - } - - // Set unlink to true, and fall into the next if which - // will include this text item in the new selection - unlinked = true; + ObjectSet tmp_set(document()); + tmp_set.set(item); + bool has_clip = false; + bool has_mask = false; + Inkscape::URIReference *clip = item->clip_ref; + Inkscape::URIReference *mask = item->mask_ref; + if ((NULL != clip) && (NULL != clip->getObject())) { + tmp_set.unsetMask(true,true); + has_clip = true; + } + if ((NULL != mask) && (NULL != mask->getObject())) { + tmp_set.unsetMask(false,true); + has_mask = true; } - if (!(dynamic_cast(item) || dynamic_cast(item))) { - // keep the non-use item in the new selection - new_select.push_back(item); - continue; + if (has_mask || has_clip) { + unlinked = tmp_set.unlink(true) || unlinked; + if (has_mask) + tmp_set.setMask(false,false,true); + if (has_clip) + tmp_set.setMask(true,false,true); + new_select.push_back(tmp_set.singleItem()); } + else { + if (dynamic_cast(item)) { + SPObject *tspan = sp_tref_convert_to_tspan(item); + + if (tspan) { + item->requestDisplayUpdate(SP_OBJECT_MODIFIED_FLAG); + } - SPItem *unlink = NULL; - SPUse *use = dynamic_cast(item); - if (use) { - unlink = use->unlink(); - // Unable to unlink use (external or invalid href?) - if (!unlink) { + // Set unlink to true, and fall into the next if which + // will include this text item in the new selection + unlinked = true; + } + + if (!(dynamic_cast(item) || dynamic_cast(item))) { + // keep the non-use item in the new selection new_select.push_back(item); continue; } - } else /*if (SP_IS_TREF(use))*/ { - unlink = dynamic_cast(sp_tref_convert_to_tspan(item)); - g_assert(unlink != NULL); - } - unlinked = true; - // Add ungrouped items to the new selection. - new_select.push_back(unlink); + SPItem *unlink = NULL; + SPUse *use = dynamic_cast(item); + if (use) { + unlink = use->unlink(); + // Unable to unlink use (external or invalid href?) + if (!unlink) { + new_select.push_back(item); + continue; + } + } else /*if (SP_IS_TREF(use))*/ { + unlink = dynamic_cast(sp_tref_convert_to_tspan(item)); + g_assert(unlink != NULL); + } + + unlinked = true; + // Add ungrouped items to the new selection. + new_select.push_back(unlink); + } } if (!new_select.empty()) { // set new selection -- cgit v1.2.3 From f5a7ab4571dd994c1b02ab774b48a7bb5d61dd8f Mon Sep 17 00:00:00 2001 From: Alexander Brock Date: Fri, 4 Nov 2016 19:17:12 +0100 Subject: Make ObjectSet::unlink() work for clones which are both clipped and masked (bzr r15204.1.3) --- src/selection-chemistry.cpp | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 0b99fd7c4..dbad56b13 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -2671,25 +2671,18 @@ bool ObjectSet::unlink(const bool skip_undo) ObjectSet tmp_set(document()); tmp_set.set(item); - bool has_clip = false; - bool has_mask = false; Inkscape::URIReference *clip = item->clip_ref; Inkscape::URIReference *mask = item->mask_ref; if ((NULL != clip) && (NULL != clip->getObject())) { tmp_set.unsetMask(true,true); - has_clip = true; + unlinked = tmp_set.unlink(true) || unlinked; + tmp_set.setMask(true,false,true); + new_select.push_back(tmp_set.singleItem()); } - if ((NULL != mask) && (NULL != mask->getObject())) { + else if ((NULL != mask) && (NULL != mask->getObject())) { tmp_set.unsetMask(false,true); - has_mask = true; - } - - if (has_mask || has_clip) { unlinked = tmp_set.unlink(true) || unlinked; - if (has_mask) - tmp_set.setMask(false,false,true); - if (has_clip) - tmp_set.setMask(true,false,true); + tmp_set.setMask(false,false,true); new_select.push_back(tmp_set.singleItem()); } else { -- cgit v1.2.3 From 68c305f169dfe9a273e29dd2aa587f0d59071483 Mon Sep 17 00:00:00 2001 From: Marc Jeanmougin Date: Sun, 6 Nov 2016 16:33:01 +0100 Subject: further cppification Fixed bugs: - https://launchpad.net/bugs/1306662 (bzr r15218) --- src/selection-chemistry.cpp | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 2db059afe..cd61ffba3 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -4094,39 +4094,27 @@ void ObjectSet::unsetMask(bool apply_clip_path) { * "fit-margin-..." attributes. See SPDocument::fitToRect. * \return true if an undoable change should be recorded. */ -bool -fit_canvas_to_selection(SPDesktop *desktop, bool with_margins) +bool ObjectSet::fitCanvas(bool with_margins, bool skip_undo) { - g_return_val_if_fail(desktop != NULL, false); - SPDocument *doc = desktop->getDocument(); - - g_return_val_if_fail(doc != NULL, false); - g_return_val_if_fail(desktop->selection != NULL, false); + g_return_val_if_fail(document() != NULL, false); - if (desktop->selection->isEmpty()) { - desktop->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to fit canvas to.")); + if (isEmpty()) { + if(desktop()) + desktop()->messageStack()->flash(Inkscape::WARNING_MESSAGE, _("Select object(s) to fit canvas to.")); return false; } - Geom::OptRect const bbox(desktop->selection->visualBounds()); + Geom::OptRect const bbox(visualBounds()); if (bbox) { - doc->fitToRect(*bbox, with_margins); + document()->fitToRect(*bbox, with_margins); + if(!skip_undo) + DocumentUndo::done(document(), SP_VERB_FIT_CANVAS_TO_SELECTION, + _("Fit Page to Selection")); return true; } else { return false; } } -/** - * Fit canvas to the bounding box of the selection, as an undoable action. - */ -void -verb_fit_canvas_to_selection(SPDesktop *const desktop) -{ - if (fit_canvas_to_selection(desktop)) { - DocumentUndo::done(desktop->getDocument(), SP_VERB_FIT_CANVAS_TO_SELECTION, - _("Fit Page to Selection")); - } -} /** * \param with_margins margins defined in the xml under @@ -4171,7 +4159,7 @@ void fit_canvas_to_selection_or_drawing(SPDesktop *desktop) { bool const changed = ( desktop->selection->isEmpty() ? fit_canvas_to_drawing(doc, true) - : fit_canvas_to_selection(desktop, true) ); + : desktop->selection->fitCanvas(true,true)); if (changed) { DocumentUndo::done(desktop->getDocument(), SP_VERB_FIT_CANVAS_TO_SELECTION_OR_DRAWING, _("Fit Page to Selection or Drawing")); -- cgit v1.2.3 From 250986a5113de9c1fbe4444247ffa94535c79e26 Mon Sep 17 00:00:00 2001 From: Alexander Brock Date: Sun, 6 Nov 2016 20:02:31 +0100 Subject: Remove duplicate code from unlinkRecursive() and fix issue with clones of groups (bzr r15204.1.4) --- src/selection-chemistry.cpp | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index dbad56b13..694e12f55 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -2749,30 +2749,15 @@ bool ObjectSet::unlinkRecursive(const bool skip_undo) { bool unlinked = false; ObjectSet tmp_set(document()); std::vector items_(items().begin(), items().end()); - for (auto& it:items_){ + for (auto& it:items_) { + tmp_set.set(it); + unlinked = tmp_set.unlink(true) || unlinked; + it = tmp_set.singleItem(); if (SP_IS_GROUP(it)) { std::vector c = it->childList(false); tmp_set.setList(c); unlinked = tmp_set.unlinkRecursive(true) || unlinked; } - tmp_set.set(it); - bool has_clip = false; - bool has_mask = false; - Inkscape::URIReference *clip = it->clip_ref; - Inkscape::URIReference *mask = it->mask_ref; - if ((NULL != clip) && (NULL != clip->getObject())) { - tmp_set.unsetMask(true,true); - has_clip = true; - } - if ((NULL != mask) && (NULL != mask->getObject())) { - tmp_set.unsetMask(false,true); - has_mask = true; - } - unlinked = tmp_set.unlink(true) || unlinked; - if (has_mask) - tmp_set.setMask(false,false,true); - if (has_clip) - tmp_set.setMask(true,false,true); } if (!unlinked) { if(desktop()) -- cgit v1.2.3 From d7b2a527bbc557855b96e2ac01c1d8554c124019 Mon Sep 17 00:00:00 2001 From: Alexander Brock Date: Sun, 6 Nov 2016 22:36:33 +0100 Subject: Fix selection issue with ObjectSet::unlinkRecursive() and add tests for it. (bzr r15204.1.5) --- src/selection-chemistry.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 694e12f55..2cfc8aa16 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -2767,6 +2767,7 @@ bool ObjectSet::unlinkRecursive(const bool skip_undo) { DocumentUndo::done(document(), SP_VERB_EDIT_UNLINK_CLONE_RECURSIVE, _("Unlink clone recursively")); } + setList(items_); return unlinked; } -- cgit v1.2.3 From e8dcb5062f6114a9fb06d496ab5d906aec405c78 Mon Sep 17 00:00:00 2001 From: "alexandru.roman" Date: Sat, 21 Jan 2017 23:28:05 +0100 Subject: Fix "swap fill and stroke" for multiple objects in selection Add verb and shortcut possibility Fixed bugs: - https://launchpad.net/bugs/367360 - https://launchpad.net/bugs/675690 (bzr r15428) --- src/selection-chemistry.cpp | 71 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 70 insertions(+), 1 deletion(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index f8ab33ac4..67972cabb 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -97,6 +97,7 @@ SPCycleType SP_CYCLING = SP_CYCLE_FOCUS; #include "live_effects/parameter/originalpath.h" #include "layer-manager.h" #include "object-set.h" +#include "svg/svg-color.h" // For clippath editing #include "ui/tools/node-tool.h" @@ -1242,7 +1243,6 @@ void ObjectSet::pasteStyle() } } - void ObjectSet::pastePathEffect() { Inkscape::UI::ClipboardManager *cm = Inkscape::UI::ClipboardManager::get(); @@ -4169,6 +4169,75 @@ bool ObjectSet::fitCanvas(bool with_margins, bool skip_undo) } } +void ObjectSet::swapFillStroke() +{ + if (desktop() == NULL) { + return; + } + + SPIPaint *paint; + SPPaintServer *server; + Glib::ustring _paintserver_id; + + auto list= items(); + for (auto itemlist=list.begin();itemlist!=list.end();++itemlist) { + SPItem *item = *itemlist; + + SPCSSAttr *css = sp_repr_css_attr_new (); + + _paintserver_id.clear(); + paint = &(item->style->fill); + if (paint->set && paint->isNone()) + sp_repr_css_set_property (css, "stroke", "none"); + else if (paint->set && paint->isColor()) { + guint32 color = paint->value.color.toRGBA32(SP_SCALE24_TO_FLOAT (item->style->fill_opacity.value)); + gchar c[64]; + sp_svg_write_color (c, sizeof(c), color); + sp_repr_css_set_property (css, "stroke", c); + } + else if (!paint->set) + sp_repr_css_unset_property (css, "stroke"); + else if (paint->set && paint->isPaintserver()) { + server = SP_STYLE_FILL_SERVER(item->style); + if (server) { + Inkscape::XML::Node *srepr = server->getRepr(); + _paintserver_id += "url(#"; + _paintserver_id += srepr->attribute("id"); + _paintserver_id += ")"; + sp_repr_css_set_property (css, "stroke", _paintserver_id.c_str()); + } + } + + _paintserver_id.clear(); + paint = &(item->style->stroke); + if (paint->set && paint->isNone()) + sp_repr_css_set_property (css, "fill", "none"); + else if (paint->set && paint->isColor()) { + guint32 color = paint->value.color.toRGBA32(SP_SCALE24_TO_FLOAT (item->style->stroke_opacity.value)); + gchar c[64]; + sp_svg_write_color (c, sizeof(c), color); + sp_repr_css_set_property (css, "fill", c); + } + else if (!paint->set) + sp_repr_css_unset_property (css, "fill"); + else if (paint->set && paint->isPaintserver()) { + server = SP_STYLE_STROKE_SERVER(item->style); + if (server) { + Inkscape::XML::Node *srepr = server->getRepr(); + _paintserver_id += "url(#"; + _paintserver_id += srepr->attribute("id"); + _paintserver_id += ")"; + sp_repr_css_set_property (css, "fill", _paintserver_id.c_str()); + } + } + + sp_desktop_apply_css_recursive(item, css, true); + sp_repr_css_attr_unref (css); + } + + DocumentUndo::done(document(), SP_VERB_EDIT_SWAP_FILL_STROKE, + _("Swap fill and stroke of an object")); +} /** * \param with_margins margins defined in the xml under -- cgit v1.2.3 From 2ab9a0e690f4505871f7457a3169acc357d961c2 Mon Sep 17 00:00:00 2001 From: Jabiertxof Date: Sat, 4 Feb 2017 22:08:57 +0100 Subject: Fix for bug #1655156 Object -> Clip -> Apply distorts objects properties. Fixed bugs: - https://launchpad.net/bugs/1655156 (bzr r15473) --- src/selection-chemistry.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 67972cabb..70307579f 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -3905,6 +3905,7 @@ void ObjectSet::setClipGroup() || apply_to_layer){ Geom::Affine oldtr=(*i)->transform; + oldtr *= SP_ITEM((*i)->parent)->i2doc_affine().inverse(); (*i)->doWriteTransform((*i)->getRepr(), (*i)->i2doc_affine()); Inkscape::XML::Node *dup = (*i)->getRepr()->duplicate(xml_doc); (*i)->doWriteTransform((*i)->getRepr(), oldtr); -- cgit v1.2.3 From f418c74c99b9621c111a8f89eae096b29255b4b2 Mon Sep 17 00:00:00 2001 From: Nicolas Dufour Date: Thu, 16 Feb 2017 18:20:39 +0100 Subject: [Bug #1426613] moving a selection of frame and text-flowed-into-frame displaces text. Fixed bugs: - https://launchpad.net/bugs/1426613 (bzr r15522) --- src/selection-chemistry.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 70307579f..f2bdeba4e 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -1618,7 +1618,7 @@ void ObjectSet::applyAffine(Geom::Affine const &affine, bool set_i2d, bool compe for (auto& itm: region.children) { SPUse *use = dynamic_cast(&itm); if ( use ) { - use->doWriteTransform(use->getRepr(), use->transform.inverse(), NULL, compensate); + use->doWriteTransform(use->getRepr(), item->transform.inverse(), NULL, compensate); } } } -- cgit v1.2.3 From 014489163050d8abe9e5c4949fb80f3c21b1c17b Mon Sep 17 00:00:00 2001 From: Tavmjong Bah Date: Mon, 13 Mar 2017 15:22:22 +0100 Subject: Replace rectangle based zooming by affine based zooming. This allows a rotation to be included in the drawing to window mapping. General code cleanup. Added documentation. Any change to zooming behavior is probably a bug. (bzr r15592) --- src/selection-chemistry.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index f2bdeba4e..5d585ab5d 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -2554,9 +2554,7 @@ void scroll_to_show_item(SPDesktop *desktop, SPItem *item) Geom::Point const d_dt = dbox.midpoint(); Geom::Point const d_w = desktop->d2w(d_dt); Geom::Point const moved_w( d_w - s_w ); - gint const dx = (gint) moved_w[X]; - gint const dy = (gint) moved_w[Y]; - desktop->scroll_world(dx, dy); + desktop->scroll_relative(moved_w); } } -- cgit v1.2.3 From 6c05c1c14cb8d29fb06d6779ec9817615c518ab5 Mon Sep 17 00:00:00 2001 From: chr Date: Thu, 18 May 2017 19:58:59 +0200 Subject: fix a brunch of memory leaks (bzr r15698.1.2) --- src/selection-chemistry.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 5d585ab5d..39846ba2c 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -3175,8 +3175,11 @@ void ObjectSet::toSymbol() the_parent_repr->appendChild(clone); if( single_group && transform.isTranslation() ) { - if( !transform.isIdentity() ) - clone->setAttribute("transform", sp_svg_transform_write( transform )); + if( !transform.isIdentity() ) { + gchar *c = sp_svg_transform_write( transform ); + clone->setAttribute("transform", c); + g_free(c); + } } // Change selection to new element. -- cgit v1.2.3 From dc80e5d0bf82f005628881134b929aa4838308d5 Mon Sep 17 00:00:00 2001 From: chr Date: Tue, 23 May 2017 21:48:22 +0200 Subject: selection chemistry: implement z-stack order Bug #1395452 "raise and lower objects" used to stack objects above/below the next overlapping object, which makes it impossible to change the z-order of objects that don't overlap. Fixes also the object manager panel Conflicts: src/selection-chemistry.cpp src/selection-chemistry.h src/sp-item.cpp (bzr r15698.1.7) --- src/selection-chemistry.cpp | 39 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 39846ba2c..7d5d921b0 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -1140,6 +1140,45 @@ void ObjectSet::lowerToBottom(bool skip_undo){ } } +void ObjectSet::stackUp(bool skip_undo) { + if (isEmpty()) { + selection_display_message(desktop(), Inkscape::WARNING_MESSAGE, _("Select object(s) to stack up.")); + return; + } + + std::vector selection(items().begin(), items().end()); + sort(selection.begin(), selection.end(), sp_item_repr_compare_position_bool); + + for (auto item: selection | boost::adaptors::reversed) { + if (!item->raiseOne()) // stop if top was reached + break; + } + + if(document() && !skip_undo) + DocumentUndo::done(document(), SP_VERB_SELECTION_STACK_UP, + //TRANSLATORS: undo history: "stack up" means to raise an object of its ordinal position by 1 + C_("Undo action", "stack up")); +} + +void ObjectSet::stackDown(bool skip_undo) { + if (isEmpty()) { + selection_display_message(desktop(), Inkscape::WARNING_MESSAGE, _("Select object(s) to stack down.")); + return; + } + + std::vector selection(items().begin(), items().end()); + sort(selection.begin(), selection.end(), sp_item_repr_compare_position_bool); + + for (auto item: selection) { + if (!item->lowerOne()) // stop if bottom was reached + break; + } + + if(document() && !skip_undo) + DocumentUndo::done(document(), SP_VERB_SELECTION_STACK_DOWN, + //TRANSLATORS: undo history: "stack down" means to lower an object of its ordinal position by 1 + C_("Undo action", "stack down")); +} void sp_undo(SPDesktop *desktop, SPDocument *) -- cgit v1.2.3 From a2e04c5fb43ae6331ac34e6ea809cbb7a0a1136a Mon Sep 17 00:00:00 2001 From: chr Date: Tue, 23 May 2017 21:48:27 +0200 Subject: selection chemistry: cancel if we hit top/bottom avoid unpredictable results in multi selections (bzr r15698.1.13) --- src/selection-chemistry.cpp | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'src/selection-chemistry.cpp') diff --git a/src/selection-chemistry.cpp b/src/selection-chemistry.cpp index 7d5d921b0..b3d910700 100644 --- a/src/selection-chemistry.cpp +++ b/src/selection-chemistry.cpp @@ -1150,8 +1150,12 @@ void ObjectSet::stackUp(bool skip_undo) { sort(selection.begin(), selection.end(), sp_item_repr_compare_position_bool); for (auto item: selection | boost::adaptors::reversed) { - if (!item->raiseOne()) // stop if top was reached - break; + if (!item->raiseOne()) { // stop if top was reached + if(document() && !skip_undo) + DocumentUndo::cancel(document()); + selection_display_message(desktop(), Inkscape::WARNING_MESSAGE, _("We hit top.")); + return; + } } if(document() && !skip_undo) @@ -1170,8 +1174,12 @@ void ObjectSet::stackDown(bool skip_undo) { sort(selection.begin(), selection.end(), sp_item_repr_compare_position_bool); for (auto item: selection) { - if (!item->lowerOne()) // stop if bottom was reached - break; + if (!item->lowerOne()) { // stop if bottom was reached + if(document() && !skip_undo) + DocumentUndo::cancel(document()); + selection_display_message(desktop(), Inkscape::WARNING_MESSAGE, _("We hit bottom.")); + return; + } } if(document() && !skip_undo) -- cgit v1.2.3