Is there a way to autoselect multiple objects with the same properties?

I have a complex diagram in Draw using many lines with different colours and widths.

Is there any way to create a selection by choosing one example of an object and automatically selecting all others which have the same properties? If there was, I could then change the colours/widths all at once instead of having to select each object one-by-one.

If there isn’t, I think this would be a useful feature to add.

Same properties? There are very many attributes you may need to compare. Any ordinary shape has a Text (supports the respective services) e.g, and though a Text in Draw is less complex than in Writer, there are lots of Char and of Paragraph properties.
If you can clearly specify what you consider “same properties”, the next question must be to what level you want/need to resolve groups. Then comes the question if/how to define the scope of the task: AllDocument, WhichSlide(s), WhichLayer(s)…
Assuming you wrote a function whose action is well described by equalShapeProperies(pShape1, pShepe2), and you can definitely answer the questions concerning the grouping levels and the scope, you can write a “macro” scanning all the shapes for equalShapeProperties, and change their properties in a given way.
How to do so might not allow for a description by a simple answer in a Q&A site.

Appreciate that the generally-phrased question requires a more complex answer, but two common properties that could be simply identified would be colour and width, across all layers.


You surely knew already that there not is a readymade tool for the purpose. User code can perform tasks of the kind in principle.
The code below shows a rough example how you might approach a solution depending on what you actually want/need.
Inspect the objects, and decide yourself what properties you need to compare.

Sub selectBasedOnSameAreaColor()
doc = ThisComponent
sel = doc.CurrentSelection
If sel.Count>1 Then Exit Sub
sh0 = sel(0)
REM Only shapes with area color are accpted here.
If NOT (sh0.FillStyle=1) Then Exit Sub 
fc = sh0.FillColor
dp = sh0.Parent REM Only the DrawPage of the CurrentSelection is scanned.
uDp = dp.Count - 1
For k = 0 To uDp
  k_sh = dp(k)
  If (k_sh.FillStyle=1) AND (k_sh.FillColor=fc) Then sel.add(k_sh)
Next k
End Sub

===Edit 2020-08-14 about 21:35 UTC===
This is my testfile: ask260190selectShapesByProperties.odg.
I tested with Draw of versions and
The simple test consisted in:

  1. Select a single shape with the mouse.
  2. Run the Sub selectBasedOnSameAreaColor() (from the menu e.g.)

Thanks, I’ll give this a go.

Hmm - OK, I can understand what this code is trying to do, but I don’t understand how uDp is being defined for the loop.

It should be the upperbound index of the array-like object giving access to all the shapes contained in the DrawPage. Lowver bound always is 0 in such cases. (Every slide has its own DrawPage in Draw.)
The code line uDp = dp.Count - 1 was missing in the code. I will update the answer with the respective correction. Sorry!

Aha - OK, that makes more sense.

k_sh.FillStyle is returning an error “BASIC runtime error. Property or method not found: FillStyle.”

I actually tried it, and I tried it just now once more in LibO Draw V (release). It worked as expected.
I will also try in some older versions if I find the time.
See also: LibreOffice: com::sun::star::drawing Module Reference

I meanwhile did another test. See my edited answer.

Right, so the issue is that because my test document contains lines as well as polygons, FillStyle isn’t a property of the first shape (a line) that it iterates over.

… and now I’ve found a way to test what kind of shape I’m looking at, I think I can make this work:

If (dp(k).ShapeType = “”) Then … etc

Thanks to Wolfgang’s example and a bit of delving into the API docs, I’ve managed to create a macro that does what I need it to do: select all lines in a document that are the same colour and width as a chosen example line. The code is as follows:

Sub selectSimilar()
	document = ThisComponent
	selection = document.CurrentSelection
	On Error Goto ERR
	If (selection.Count>1) Then 
		MsgBox "Select only one thing"
		Exit Sub
	End If
	exampleShape = selection(0)
	drawPage = exampleShape.Parent
	If (exampleShape.ShapeType = "") Then 
		selectLines(drawPage, selection, exampleShape)
	End If
	Exit Sub
	MsgBox "Select something"
	On Local Error Goto 0
End Sub

Function selectLines(drawPage, selection, exampleShape)
	numShapes = drawPage.Count - 1
	exampleWidth = exampleShape.LineWidth
	exampleColor = exampleShape.LineColor
	For k = 0 To numShapes
		thisShape = drawPage(k)
		If (thisShape.ShapeType = "") Then
			if (thisShape.LineWidth = exampleWidth AND thisShape.LineColor = exampleColor) Then
			End If
		End If
	Next k
End Function

Nice, clearly structured.
On thing: the name numShapes suggests the variable should contain the number of shapes. “high” or “ubound” in place of “num” might be preferable.
Same reason: The called Sub might better be named selectSimilarLineShapes.

Good points - I’ll amend the variable name in my local copy. The reason for selectSimilar is so I can extend this in the future to select other kinds of shapes. This’ll be done by adding to the condition in selectSimilar to call different Functions based on what kind of shape has been chosen as the exampleShape.

The reason for selectSimilar is so I can extend this in the future to select other kinds of shapes.

This was a faint suspicion with me, anyway.
However, I would see lots of reasons to control the action of the routine by additional parameters concerning which ones of the many properties should be checked. After all, also non-LineShape shapes have line properties. And today I may want to treat continuous lines and dotted ones the same way. Tomorrow I may not…
Did you already design a concept regarding this aspect of the task?
BTW: the CurrentSelection used above is a ShapeCollection. You can create as many instances of the ShapeCollection service as you want like in
shColl1 = CreateUnoService("").
(You may use to ungroup groups for inspection and treatment without losing them for later re-grouping. You may expect lots of fun with programmimg private extensions to Draw.)

Yes, lots of ways to improve, and thanks for the ShapeCollection pointer which’ll be useful. In this particular instance I had a specific itch I needed to scratch and the “quick n dirty” approach will do exactly what I need for now.