summaryrefslogtreecommitdiffstats
path: root/src/document.cpp
diff options
context:
space:
mode:
authorJabier Arraiza <jabier.arraiza@marker.es>2018-11-03 15:56:23 +0000
committerJabier Arraiza <jabier.arraiza@marker.es>2018-11-05 23:14:17 +0000
commitd9e1fb5db48f46e52dbb171e7bdcee1602d8eb14 (patch)
treee84adb8bf6f13e389aade356fa4e6c0abdd62dc3 /src/document.cpp
parentremove Inkscape::URI::toString (diff)
downloadinkscape-d9e1fb5db48f46e52dbb171e7bdcee1602d8eb14.tar.gz
inkscape-d9e1fb5db48f46e52dbb171e7bdcee1602d8eb14.zip
Improvemets to find items
Diffstat (limited to 'src/document.cpp')
-rw-r--r--src/document.cpp43
1 files changed, 29 insertions, 14 deletions
diff --git a/src/document.cpp b/src/document.cpp
index 35e57871f..450936d25 100644
--- a/src/document.cpp
+++ b/src/document.cpp
@@ -1381,25 +1381,39 @@ static bool overlaps(Geom::Rect const &area, Geom::Rect const &box)
return area.intersects(box);
}
-static std::vector<SPItem*> &find_items_in_area(std::vector<SPItem*> &s, SPGroup *group, unsigned int dkey, Geom::Rect const &area,
- bool (*test)(Geom::Rect const &, Geom::Rect const &), bool take_insensitive = false, bool into_groups = false)
+static std::vector<SPItem*> &find_items_in_area(std::vector<SPItem*> &s,
+ SPGroup *group, unsigned int dkey,
+ Geom::Rect const &area,
+ bool (*test)(Geom::Rect const &, Geom::Rect const &),
+ bool take_hidden = false,
+ bool take_insensitive = false,
+ bool take_groups = true,
+ bool take_into_groups = false,
+ bool take_into_filtered = true)
{
g_return_val_if_fail(SP_IS_GROUP(group), s);
for (auto& o: group->children) {
- if ( SP_IS_ITEM(&o) ) {
- if (SP_IS_GROUP(&o) && (SP_GROUP(&o)->effectiveLayerMode(dkey) == SPGroup::LAYER || into_groups)) {
- s = find_items_in_area(s, SP_GROUP(&o), dkey, area, test, take_insensitive, into_groups);
+ if (SPItem *item = dynamic_cast<SPItem *>(&o)) {
+ if (SPGroup * childgroup = dynamic_cast<SPGroup *>(item)) {
+ bool is_layer = childgroup->effectiveLayerMode(dkey) == SPGroup::LAYER;
+ if (is_layer || (take_into_groups && (!childgroup->isFiltered() || take_into_filtered))) {
+ s = find_items_in_area(s, childgroup, dkey, area, test, take_hidden, take_insensitive, take_groups, take_into_groups, take_into_filtered);
+ }
+ if (take_groups && !is_layer) {
+ Geom::OptRect box = childgroup->desktopVisualBounds();
+ if ( box && test(area, *box) && (!childgroup->isLocked() || take_insensitive) && (!childgroup->isHidden() || take_hidden) ) {
+ s.push_back(item);
+ }
+ }
} else {
- SPItem *child = SP_ITEM(&o);
- Geom::OptRect box = child->desktopVisualBounds();
- if ( box && test(area, *box) && (take_insensitive || child->isVisibleAndUnlocked(dkey))) {
- s.push_back(child);
+ Geom::OptRect box = item->desktopVisualBounds();
+ if ( box && test(area, *box) && (!item->isLocked() || take_insensitive) && (!item->isHidden() || take_hidden) ) {
+ s.push_back(item);
}
}
}
}
-
return s;
}
@@ -1456,6 +1470,7 @@ SPItem *SPDocument::getItemFromListAtPointBottom(unsigned int dkey, SPGroup *gro
Turn the SVG DOM into a flat list of nodes that can be searched from top-down.
The list can be persisted, which improves "find at multiple points" speed.
*/
+// TODO: study add `gboolean with_groups = false` as parameter.
void SPDocument::build_flat_item_list(unsigned int dkey, SPGroup *group, gboolean into_groups) const
{
for (auto& o: group->children) {
@@ -1554,10 +1569,10 @@ static SPItem *find_group_at_point(unsigned int dkey, SPGroup *group, Geom::Poin
* Assumes box is normalized (and g_asserts it!)
*
*/
-std::vector<SPItem*> SPDocument::getItemsInBox(unsigned int dkey, Geom::Rect const &box, bool take_insensitive, bool into_groups) const
+std::vector<SPItem*> SPDocument::getItemsInBox(unsigned int dkey, Geom::Rect const &box, bool take_hidden, bool take_insensitive, bool take_groups, bool take_into_groups, bool take_into_filtered) const
{
std::vector<SPItem*> x;
- return find_items_in_area(x, SP_GROUP(this->root), dkey, box, is_within, take_insensitive, into_groups);
+ return find_items_in_area(x, SP_GROUP(this->root), dkey, box, is_within, take_hidden, take_insensitive, take_groups, take_into_groups, take_into_filtered);
}
/*
@@ -1567,10 +1582,10 @@ std::vector<SPItem*> SPDocument::getItemsInBox(unsigned int dkey, Geom::Rect con
*
*/
-std::vector<SPItem*> SPDocument::getItemsPartiallyInBox(unsigned int dkey, Geom::Rect const &box, bool take_insensitive, bool into_groups) const
+std::vector<SPItem*> SPDocument::getItemsPartiallyInBox(unsigned int dkey, Geom::Rect const &box, bool take_hidden, bool take_insensitive, bool take_groups, bool take_into_groups, bool take_into_filtered) const
{
std::vector<SPItem*> x;
- return find_items_in_area(x, SP_GROUP(this->root), dkey, box, overlaps, take_insensitive, into_groups);
+ return find_items_in_area(x, SP_GROUP(this->root), dkey, box, overlaps, take_hidden, take_insensitive, take_groups, take_into_groups, take_into_filtered);
}
std::vector<SPItem*> SPDocument::getItemsAtPoints(unsigned const key, std::vector<Geom::Point> points, bool all_layers, size_t limit) const