An EffectExtension can iterate over all selected objects with self.svg.selection. But how can it iterate over all selectable ShapeElements? Essentially, I'd like the equivalent of self.svg.selection if it were run after a Select All.
The closest I've come so far is
for child in self.svg:
if isinstance(child, inkex.ShapeElement):
but that seems also to return things like the g element that represents the layer—something that would not be selected by a Select All. (I do want to select ordinary g elements, though.)
I don't think I can make the self.svg.xpath approach work because it will match all shapes, even those nested within groups. For example, if you grouped a couple of circles, grouped a couple of squares, and then grouped the two of those together, self.svg.xpath would return the two circles, the two squares, and the three groups (plus the layer group). In contrast, if a user had previously done a Select All, self.svg.selection would return only the top-level group.
Assuming layers are the only unexpected direct children of self.svg—I need to do more testing to check—I can indeed check and reject groupmode="layer" groups. String matching is a bit kludgy, though. I just tried, and
if my_object.get('inkscape:groupmode') == 'layer':
seems to work without relying on a particular string representation.
def top_level_shapes(self):
'Return a list of all top-level ShapeElements.'
# Find all ShapeElements whose parent is a layer.
shapes = []
layers = {g
for g in self.svg.xpath('//svg:g')
if g.get('inkscape:groupmode') == 'layer'}
shapes = [obj
for l in layers
for obj in l
if isinstance(obj, inkex.ShapeElement)]
# Find all ShapeElements whose parent is the root.
root_shapes = [obj
for obj in self.svg
if isinstance(obj, inkex.ShapeElement) and \
obj not in layers]
shapes.extend(root_shapes)
return shapes
An
EffectExtension
can iterate over all selected objects withself.svg.selection
. But how can it iterate over all selectableShapeElement
s? Essentially, I'd like the equivalent ofself.svg.selection
if it were run after a Select All.The closest I've come so far is
but that seems also to return things like the
g
element that represents the layer—something that would not be selected by a Select All. (I do want to select ordinaryg
elements, though.)Hello Scott,
This might be the wrong way to do it ?
Could you rejected an item from a list before based on a simple string match ?
Thanks for the suggestion.
I don't think I can make the
self.svg.xpath
approach work because it will match all shapes, even those nested within groups. For example, if you grouped a couple of circles, grouped a couple of squares, and then grouped the two of those together,self.svg.xpath
would return the two circles, the two squares, and the three groups (plus the layer group). In contrast, if a user had previously done a Select All,self.svg.selection
would return only the top-level group.Assuming layers are the only unexpected direct children of
self.svg
—I need to do more testing to check—I can indeed check and rejectgroupmode="layer"
groups. String matching is a bit kludgy, though. I just tried, andseems to work without relying on a particular string representation.
Here's what I've come up with so far: