summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdrian Boguszewski <adrbogus1@student.pg.gda.pl>2016-07-20 09:01:17 +0000
committerAdrian Boguszewski <adrbogus1@student.pg.gda.pl>2016-07-20 09:01:17 +0000
commit3c593bb8da3357514ff5b4f3154d08c4508ad47e (patch)
treeb6f8b8a12882dee4979d42630af44aa90c046f3d
parentRenamed children list in SPObject (diff)
downloadinkscape-3c593bb8da3357514ff5b4f3154d08c4508ad47e.tar.gz
inkscape-3c593bb8da3357514ff5b4f3154d08c4508ad47e.zip
Changed arguments and names of selection chemistry functions
(bzr r14954.1.22)
-rw-r--r--src/object-set.h43
-rw-r--r--src/persp3d.cpp4
-rw-r--r--src/persp3d.h2
-rw-r--r--src/selection-chemistry.cpp289
-rw-r--r--src/selection-chemistry.h34
-rw-r--r--src/selection.cpp5
-rw-r--r--src/selection.h10
-rw-r--r--src/ui/interface.cpp2
-rw-r--r--src/verbs.cpp12
9 files changed, 217 insertions, 184 deletions
diff --git a/src/object-set.h b/src/object-set.h
index 0f06e373b..a0bca7889 100644
--- a/src/object-set.h
+++ b/src/object-set.h
@@ -26,11 +26,14 @@
#include <boost/type_traits.hpp>
#include <boost/utility/enable_if.hpp>
#include <sigc++/connection.h>
+#include <inkgc/gc-soft-ptr.h>
#include "sp-object.h"
#include "sp-item.h"
+#include "sp-item-group.h"
class SPBox3D;
class Persp3D;
+class SPDesktop;
namespace Inkscape {
@@ -47,6 +50,12 @@ struct is_item {
}
};
+struct is_group {
+ bool operator()(SPObject* obj) {
+ return SP_IS_GROUP(obj);
+ }
+};
+
struct object_to_item {
typedef SPItem* result_type;
SPItem* operator()(SPObject* obj) const {
@@ -61,6 +70,13 @@ struct object_to_node {
}
};
+struct object_to_group {
+ typedef SPGroup* result_type;
+ SPGroup* operator()(SPObject* obj) const {
+ return SP_GROUP(obj);
+ }
+};
+
typedef boost::multi_index_container<
SPObject*,
boost::multi_index::indexed_by<
@@ -82,9 +98,10 @@ class ObjectSet {
public:
enum CompareSize {HORIZONTAL, VERTICAL, AREA};
typedef decltype(multi_index_container().get<random_access>() | boost::adaptors::filtered(is_item()) | boost::adaptors::transformed(object_to_item())) SPItemRange;
+ typedef decltype(multi_index_container().get<random_access>() | boost::adaptors::filtered(is_group()) | boost::adaptors::transformed(object_to_group())) SPGroupRange;
typedef decltype(multi_index_container().get<random_access>() | boost::adaptors::filtered(is_item()) | boost::adaptors::transformed(object_to_node())) XMLNodeRange;
- ObjectSet() {};
+ ObjectSet(SPDesktop* desktop): _desktop(desktop) {};
virtual ~ObjectSet();
/**
@@ -177,18 +194,25 @@ public:
/** Returns the list of selected objects. */
SPObjectRange objects();
- /** Returns the list of selected SPItems. */
+ /** Returns a range of selected SPItems. */
SPItemRange items() {
return SPItemRange(container.get<random_access>()
| boost::adaptors::filtered(is_item())
| boost::adaptors::transformed(object_to_item()));
};
- /** Returns a list of the xml nodes of all selected objects. */
+ /** Returns a range of selected groups. */
+ SPGroupRange groups() {
+ return SPGroupRange (container.get<random_access>()
+ | boost::adaptors::filtered(is_group())
+ | boost::adaptors::transformed(object_to_group()));
+ }
+
+ /** Returns a range of the xml nodes of all selected objects. */
XMLNodeRange xmlNodes() {
return XMLNodeRange(container.get<random_access>()
- | boost::adaptors::filtered(is_item())
- | boost::adaptors::transformed(object_to_node()));
+ | boost::adaptors::filtered(is_item())
+ | boost::adaptors::transformed(object_to_node()));
}
/**
@@ -254,6 +278,13 @@ public:
*/
std::list<SPBox3D *> const box3DList(Persp3D *persp = NULL);
+ /**
+ * Returns the desktop the selection is bound to
+ *
+ * @return the desktop the selection is bound to, or NULL if in console mode
+ */
+ SPDesktop *desktop() { return _desktop; }
+
protected:
virtual void _connectSignals(SPObject* object) {};
virtual void _releaseSignals(SPObject* object) {};
@@ -270,12 +301,14 @@ protected:
virtual void _remove_3D_boxes_recursively(SPObject *obj);
multi_index_container container;
+ GC::soft_ptr<SPDesktop> _desktop;
std::list<SPBox3D *> _3dboxes;
std::unordered_map<SPObject*, sigc::connection> releaseConnections;
};
typedef ObjectSet::SPItemRange SPItemRange;
+typedef ObjectSet::SPGroupRange SPGroupRange;
typedef ObjectSet::XMLNodeRange XMLNodeRange;
} // namespace Inkscape
diff --git a/src/persp3d.cpp b/src/persp3d.cpp
index e260af8e5..7d79d3ab5 100644
--- a/src/persp3d.cpp
+++ b/src/persp3d.cpp
@@ -494,10 +494,10 @@ persp3d_on_repr_attr_changed ( Inkscape::XML::Node * /*repr*/,
/* checks whether all boxes linked to this perspective are currently selected */
bool
-persp3d_has_all_boxes_in_selection (Persp3D *persp, Inkscape::Selection *selection) {
+persp3d_has_all_boxes_in_selection (Persp3D *persp, Inkscape::ObjectSet *set) {
Persp3DImpl *persp_impl = persp->perspective_impl;
- std::list<SPBox3D *> selboxes = selection->box3DList();
+ std::list<SPBox3D *> selboxes = set->box3DList();
for (std::vector<SPBox3D *>::iterator i = persp_impl->boxes.begin(); i != persp_impl->boxes.end(); ++i) {
if (std::find(selboxes.begin(), selboxes.end(), *i) == selboxes.end()) {
diff --git a/src/persp3d.h b/src/persp3d.h
index be5680bcb..ce0e3c120 100644
--- a/src/persp3d.h
+++ b/src/persp3d.h
@@ -107,7 +107,7 @@ void persp3d_absorb(Persp3D *persp1, Persp3D *persp2);
Persp3D * persp3d_create_xml_element (SPDocument *document, Persp3DImpl *dup = NULL);
Persp3D * persp3d_document_first_persp (SPDocument *document);
-bool persp3d_has_all_boxes_in_selection (Persp3D *persp, Inkscape::Selection *selection);
+bool persp3d_has_all_boxes_in_selection (Persp3D *persp, Inkscape::ObjectSet *set);
void persp3d_print_debugging_info (Persp3D *persp);
void persp3d_print_debugging_info_all(SPDocument *doc);
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 <Kris.DeGussem@gmail.com>
* Tavmjong Bah <tavmjong@free.fr> (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<Inkscape::XML::Node*> 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<Inkscape::XML::Node*> 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<Inkscape::XML::Node*> 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 <b>some objects</b> to group."));
return;
}
+ Inkscape::XML::Node* group = sp_selection_group(selection);
- std::vector<Inkscape::XML::Node*> 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 <b>group</b> to ungroup."));
- }
-
- // first check whether there is anything to ungroup
- auto old_select = selection->items();
- std::vector<SPItem*> new_select;
GSList *groups = NULL;
- for (auto item = old_select.begin(); item!=old_select.end(); ++item) {
- SPItem *obj = *item;
- if (dynamic_cast<SPGroup *>(obj)) {
- groups = g_slist_prepend(groups, obj);
- }
- }
-
- if (groups == NULL) {
- selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("<b>No groups</b> to ungroup in the selection."));
- g_slist_free(groups);
- return;
+ for (auto g: set->groups()) {
+ groups = g_slist_prepend(groups, g);
}
+ std::vector<SPItem*> new_select;
+ auto old_select = set->items();
std::vector<SPItem*> 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 <b>group</b> to ungroup."));
+ }
+
+ if (boost::distance(selection->groups()) == 0) {
+ selection_display_message(desktop, Inkscape::ERROR_MESSAGE, _("<b>No groups</b> 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<SPItem*> &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<SPItem*> 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 <svg> from Inkscape::XML editor
if (!dynamic_cast<SPGroup *>(parent)) {
return NULL;
}
- for (std::vector<SPItem*>::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<SPItem*> items(selection->items().begin(), selection->items().end());
-
- if (items.empty()) {
- selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> 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 <b>different groups</b> or <b>layers</b>."));
- return;
- }
-
- Inkscape::XML::Node *grepr = const_cast<Inkscape::XML::Node *>(group->getRepr());
+void sp_selection_raise(ObjectSet* set) {
+ std::vector<SPItem*> items(set->items().begin(), set->items().end());
+ Inkscape::XML::Node *grepr = const_cast<Inkscape::XML::Node *>(items.front()->parent->getRepr());
/* Construct reverse-ordered list of selected children. */
std::vector<SPItem*> 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 <b>object(s)</b> to raise to top."));
+ if (selection->items().empty()) {
+ selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to raise."));
return;
}
- std::vector<SPItem*> 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 <b>different groups</b> or <b>layers</b>."));
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<Inkscape::XML::Node*> rl(selection->xmlNodes().begin(), selection->xmlNodes().end());
+void sp_selection_raise_to_top(ObjectSet* set) {
+ std::vector<Inkscape::XML::Node*> rl(set->xmlNodes().begin(), set->xmlNodes().end());
sort(rl.begin(),rl.end(),sp_repr_compare_position_bool);
for (std::vector<Inkscape::XML::Node*>::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<SPItem*> items(selection->items().begin(), selection->items().end());
- if (items.empty()) {
- selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to lower."));
+ SPDocument *document = selection->layers()->getDocument();
+
+ if (selection->isEmpty()) {
+ selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> 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 <b>different groups</b> or <b>layers</b>."));
return;
}
- Inkscape::XML::Node *grepr = const_cast<Inkscape::XML::Node *>(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<SPItem*> items(set->items().begin(), set->items().end());
+ Inkscape::XML::Node *grepr = const_cast<Inkscape::XML::Node *>(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 <b>object(s)</b> to lower to bottom."));
+ if (selection->items().empty()) {
+ selection_display_message(desktop, Inkscape::WARNING_MESSAGE, _("Select <b>object(s)</b> to lower."));
return;
}
- std::vector<SPItem*> 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 <b>different groups</b> or <b>layers</b>."));
return;
}
- std::vector<Inkscape::XML::Node*> 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<Inkscape::XML::Node*> rl(set->xmlNodes().begin(), set->xmlNodes().end());
sort(rl.begin(),rl.end(),sp_repr_compare_position_bool);
for (std::vector<Inkscape::XML::Node*>::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<SPGroup *>(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 <b>object(s)</b> 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 <b>different groups</b> or <b>layers</b>."));
+ 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<SPUse *>(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<SPTRef *>(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<Persp3D *> plist = selection->perspList();
+ std::list<Persp3D *> plist = set->perspList();
for (std::list<Persp3D *>::iterator i = plist.begin(); i != plist.end(); ++i) {
persp = (Persp3D *) (*i);
- if (!persp3d_has_all_boxes_in_selection (persp, selection)) {
- std::list<SPBox3D *> selboxes = selection->box3DList(persp);
+ if (!persp3d_has_all_boxes_in_selection (persp, set)) {
+ std::list<SPBox3D *> 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<SPRoot *>(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<SPText *>(item) && item->firstChild() && dynamic_cast<SPTextPath *>(item->firstChild()))
- && selection->includes( sp_textpath_get_path_item(dynamic_cast<SPTextPath *>(item->firstChild())) ));
+ && set->includes( sp_textpath_get_path_item(dynamic_cast<SPTextPath *>(item->firstChild())) ));
// ...both a flowtext and its frame?
- bool transform_flowtext_with_frame = (dynamic_cast<SPFlowtext *>(item) && selection->includes( dynamic_cast<SPFlowtext *>(item)->get_frame(NULL))); // (only the first frame is checked so far)
+ bool transform_flowtext_with_frame = (dynamic_cast<SPFlowtext *>(item) && set->includes( dynamic_cast<SPFlowtext *>(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<SPOffset *>(item) && dynamic_cast<SPOffset *>(item)->sourceHref) && selection->includes( sp_offset_get_source(dynamic_cast<SPOffset *>(item)) );
+ bool transform_offset_with_source = (dynamic_cast<SPOffset *>(item) && dynamic_cast<SPOffset *>(item)->sourceHref) && set->includes( sp_offset_get_source(dynamic_cast<SPOffset *>(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 &center, gdouble const angle_degrees)
+sp_selection_rotate_relative(ObjectSet *set, Geom::Point const &center, 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<Inkscape::XML::Node*> reprs_to_group;
- for (std::vector<SPItem*>::const_iterator i = apply_to_items.begin(); i != apply_to_items.end(); ++i) {
- reprs_to_group.push_back(static_cast<SPObject*>(*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) {
diff --git a/src/selection-chemistry.h b/src/selection-chemistry.h
index 82b91c617..cfae84eef 100644
--- a/src/selection-chemistry.h
+++ b/src/selection-chemistry.h
@@ -26,6 +26,7 @@ class SPDesktop;
namespace Inkscape {
class Selection;
+class ObjectSet;
namespace LivePathEffect {
class PathParam;
@@ -74,14 +75,19 @@ void sp_selection_unsymbol(SPDesktop *desktop);
void sp_selection_tile(SPDesktop *desktop, bool apply = true);
void sp_selection_untile(SPDesktop *desktop);
-void sp_selection_group(Inkscape::Selection *selection, SPDesktop *desktop);
-void sp_selection_ungroup(Inkscape::Selection *selection, SPDesktop *desktop);
+void sp_selection_group_ui(Inkscape::Selection *selection, SPDesktop *desktop);
+void sp_selection_ungroup_ui(Inkscape::Selection *selection, SPDesktop *desktop);
void sp_selection_ungroup_pop_selection(Inkscape::Selection *selection, SPDesktop *desktop);
-void sp_selection_raise(Inkscape::Selection *selection, SPDesktop *desktop);
-void sp_selection_raise_to_top(Inkscape::Selection *selection, SPDesktop *desktop);
-void sp_selection_lower(Inkscape::Selection *selection, SPDesktop *desktop);
-void sp_selection_lower_to_bottom(Inkscape::Selection *selection, SPDesktop *desktop);
+void sp_selection_raise(Inkscape::ObjectSet* set);
+void sp_selection_raise_to_top(Inkscape::ObjectSet* set);
+void sp_selection_lower(Inkscape::ObjectSet *set);
+void sp_selection_lower_to_bottom(Inkscape::ObjectSet *set);
+
+void sp_selection_raise_ui(Inkscape::Selection *selection, SPDesktop *desktop);
+void sp_selection_raise_to_top_ui(Inkscape::Selection *selection, SPDesktop *desktop);
+void sp_selection_lower_ui(Inkscape::Selection *selection, SPDesktop *desktop);
+void sp_selection_lower_to_bottom_ui(Inkscape::Selection *selection, SPDesktop *desktop);
SPCSSAttr *take_style_from_item (SPObject *object);
@@ -103,14 +109,14 @@ void sp_selection_to_next_layer( SPDesktop *desktop, bool suppressDone = false )
void sp_selection_to_prev_layer( SPDesktop *desktop, bool suppressDone = false );
void sp_selection_to_layer( SPDesktop *desktop, SPObject *layer, bool suppressDone = false );
-void sp_selection_apply_affine(Inkscape::Selection *selection, Geom::Affine const &affine, bool set_i2d = true, bool compensate = true, bool adjust_transf_center = true);
+void sp_selection_apply_affine(Inkscape::ObjectSet *selection, Geom::Affine const &affine, bool set_i2d = true, bool compensate = true, bool adjust_transf_center = true);
void sp_selection_remove_transform (SPDesktop *desktop);
-void sp_selection_scale_absolute (Inkscape::Selection *selection, double x0, double x1, double y0, double y1);
-void sp_selection_scale_relative(Inkscape::Selection *selection, Geom::Point const &align, Geom::Scale const &scale);
-void sp_selection_rotate_relative (Inkscape::Selection *selection, Geom::Point const &center, double angle);
-void sp_selection_skew_relative (Inkscape::Selection *selection, Geom::Point const &align, double dx, double dy);
-void sp_selection_move_relative (Inkscape::Selection *selection, Geom::Point const &move, bool compensate = true);
-void sp_selection_move_relative (Inkscape::Selection *selection, double dx, double dy);
+void sp_selection_scale_absolute (Inkscape::ObjectSet *set, double x0, double x1, double y0, double y1);
+void sp_selection_scale_relative(Inkscape::ObjectSet *set, Geom::Point const &align, Geom::Scale const &scale);
+void sp_selection_rotate_relative (Inkscape::ObjectSet *set, Geom::Point const &center, double angle);
+void sp_selection_skew_relative (Inkscape::ObjectSet *set, Geom::Point const &align, double dx, double dy);
+void sp_selection_move_relative (Inkscape::ObjectSet *set, Geom::Point const &move, bool compensate = true);
+void sp_selection_move_relative (Inkscape::ObjectSet *set, double dx, double dy);
void sp_selection_rotate_90 (SPDesktop *desktop, bool ccw);
void sp_selection_rotate (Inkscape::Selection *selection, double angle);
@@ -151,7 +157,7 @@ void scroll_to_show_item(SPDesktop *desktop, SPItem *item);
void sp_undo (SPDesktop *desktop, SPDocument *doc);
void sp_redo (SPDesktop *desktop, SPDocument *doc);
-void sp_selection_get_export_hints (Inkscape::Selection *selection, Glib::ustring &filename, float *xdpi, float *ydpi);
+void sp_selection_get_export_hints (Inkscape::ObjectSet* set, Glib::ustring &filename, float *xdpi, float *ydpi);
void sp_document_get_export_hints (SPDocument * doc, Glib::ustring &filename, float *xdpi, float *ydpi);
void sp_selection_create_bitmap_copy (SPDesktop *desktop);
diff --git a/src/selection.cpp b/src/selection.cpp
index 09eaf6c0e..bdd4f0dc7 100644
--- a/src/selection.cpp
+++ b/src/selection.cpp
@@ -27,15 +27,16 @@
#include "sp-shape.h"
#include "sp-path.h"
+#include "desktop.h"
#include "document.h"
#define SP_SELECTION_UPDATE_PRIORITY (G_PRIORITY_HIGH_IDLE + 1)
namespace Inkscape {
-Selection::Selection(LayerModel *layers, SPDesktop *desktop) :
+Selection::Selection(LayerModel *layers, SPDesktop *desktop):
+ ObjectSet(desktop),
_layers(layers),
- _desktop(desktop),
_selection_context(NULL),
_flags(0),
_idle(0)
diff --git a/src/selection.h b/src/selection.h
index 7027a388f..4ea70c38d 100644
--- a/src/selection.h
+++ b/src/selection.h
@@ -23,11 +23,9 @@
#include "inkgc/gc-managed.h"
#include "gc-finalized.h"
#include "gc-anchored.h"
-#include "inkgc/gc-soft-ptr.h"
#include "sp-item.h"
#include "object-set.h"
-class SPDesktop;
class SPItem;
namespace Inkscape {
@@ -80,12 +78,7 @@ public:
*/
LayerModel *layers() { return _layers; }
- /**
- * Returns the desktop the selection is bound to
- *
- * @return the desktop the selection is bound to, or NULL if in console mode
- */
- SPDesktop *desktop() { return _desktop; }
+
/**
* Returns active layer for selection (currentLayer or its parent).
@@ -228,7 +221,6 @@ private:
void _releaseContext(SPObject *obj);
LayerModel *_layers;
- GC::soft_ptr<SPDesktop> _desktop;
SPObject* _selection_context;
unsigned int _flags;
unsigned int _idle;
diff --git a/src/ui/interface.cpp b/src/ui/interface.cpp
index bcf055654..d19526105 100644
--- a/src/ui/interface.cpp
+++ b/src/ui/interface.cpp
@@ -1916,7 +1916,7 @@ void ContextMenu::MakeGroupMenu(void)
void ContextMenu::ActivateGroup(void)
{
- sp_selection_group(_desktop->selection, _desktop);
+ sp_selection_group_ui(_desktop->selection, _desktop);
}
void ContextMenu::ActivateUngroup(void)
diff --git a/src/verbs.cpp b/src/verbs.cpp
index 299cfe8e7..8255ea1ea 100644
--- a/src/verbs.cpp
+++ b/src/verbs.cpp
@@ -1133,22 +1133,22 @@ void SelectionVerb::perform(SPAction *action, void *data)
sp_selected_path_slice(selection, dt);
break;
case SP_VERB_SELECTION_TO_FRONT:
- sp_selection_raise_to_top(selection, dt);
+ sp_selection_raise_to_top_ui(selection, dt);
break;
case SP_VERB_SELECTION_TO_BACK:
- sp_selection_lower_to_bottom(selection, dt);
+ sp_selection_lower_to_bottom_ui(selection, dt);
break;
case SP_VERB_SELECTION_RAISE:
- sp_selection_raise(selection, dt);
+ sp_selection_raise_ui(selection, dt);
break;
case SP_VERB_SELECTION_LOWER:
- sp_selection_lower(selection, dt);
+ sp_selection_lower_ui(selection, dt);
break;
case SP_VERB_SELECTION_GROUP:
- sp_selection_group(selection, dt);
+ sp_selection_group_ui(selection, dt);
break;
case SP_VERB_SELECTION_UNGROUP:
- sp_selection_ungroup(selection, dt);
+ sp_selection_ungroup_ui(selection, dt);
break;
case SP_VERB_SELECTION_UNGROUP_POP_SELECTION:
sp_selection_ungroup_pop_selection(selection, dt);