Get Selected Text Boxes and Combine into One

Hello! I’d like to write a macro that combines the text boxes I’ve selected into one and remove the uncombined text boxes. This is using LO Draw.

I’m not new to Excel VBA or Python (preferred) but I am new to LO Basic. If I could just get started that’d be great. For instance, I don’t know how to get the current selection or make a new text box.

Or, even better, if someone wants to write up such a macro that’d be awesome! :slight_smile: Thanks in advance!

EDIT: An uncombined text box is a list of 2 or more selected text boxes in “viewing” order. i.e. top-to-bottom, left-to-right. Assume the text boxes do not overlap.

FURTHER CLARIFICATION:
My use case is to select multiple text boxes and combine them into a singular text box and then remove the original text boxes that were selected. The combined text box should have the aggregate of all the text contained by the original selected text boxes.

By viewing order I am talking about reading order. I wouldn’t want the aggregation of the text to be in the wrong order, after all. This is why I say “top-to-bottom, left-to-right” as this is the natural order in which I read English. Furthermore, you are right in that I cannot assure anything. However, if the solution comes close then I can potentially further refine it to be acceptable.

What do you mean by “combine … text boxes”? What is an uncombined text box? Unselected in this case?
It’s not difficult. Basically. If I assume you want the texts from the selected shapes accumulated into one, you may want to get these texts in a specific order. There are mainly two orders that may be different: The “logical order” in which the shapes originally were created, and the “order as viewed” after the shapes were moved into their current positions. What about overlapping (probably 100%)?
Programming often is simple - as long as you don’t worry about malfunctions probably occurring due to unsufficiently considered “exceptional” cases.

Added clarification. Also just realized that LO allows for Python scripts to be ran? That’d be preferred if it’s possible…

It’s strange. I used LibreOffice and (mostly) its predecessors a lot when I was still in office, but I never had need to program for it. The very few programming I did in the context of administration was in Pascal and Delphi.
Now I am long retired, and only due to contributing to some forums - and sometimes a bit for fun - I started to create user code now and then for AOO or LibO. If I do so, I use Basic - and, of course the uno-API which is needed in most cases independent of what language / IDE is used. In fact the API would be in the center of any solution for your task, and neither Python nor Basic nor C++ can do much for you beyond organising some loops and branchinjgs. These languages / implementations / run-time libraries … are useful if you need to to things that are not well supported by API means. The only task of this kind in the given context may be the sorting by coordinates you need if the visual order and the logical order are different…

Quoting @starryknight64: “EDIT: An uncombined text box is a list of 2 or more selected text boxes …”
I didn’t understand that. Are you sure you wanted to tell exactly this?
Quoting @starryknight64: “… in ‘viewing’ order i.e. top-to-bottom, left-to-right. Assume the text boxes do not overlap.”
I would see the two quoted text pieces as basically independent statements, the first one unclear in terms, the second one doubtable: You may assume as you like. If you cannot assure it, a solution should not rely on it.

Thanks for all your help so far, @Lupp! Here’s some further clarification:

My use case is to select multiple text boxes and combine them into a singular text box and then remove the original text boxes that were selected. The combined text box should have the aggregate of all the text contained by the original selected text boxes.

By viewing order I am talking about reading order. I wouldn’t want the aggregation of the text to be in the wrong order, after all. This is why I say “top-to-bottom, left-to-right” as this is the natural order in which I read English. Furthermore, you are right in that I cannot assure anything. However, if the solution comes close then I can potentially further refine it to be acceptable.

If you can not assure that the viewing-order = reading-order is identzivcal with the insertion-order = logical-order, you need to sort using the .Position coordinates (.X and .Y) as sort-keys.
This is done in the demonstration I already pointed you to.
A simplified vesrion omitting the sorting, but accumulating the texts into thelogically-last shape , and deleting all the other selected shapes is attached to my answer by editing.

To make this more substantial:
There was the thread Pdf to Draw to Writer to which I posted an answer first, and later amended a note doing the “pdf” from the original subject aside. This note is enriched by a demonstartion how text from graphical shapes (in a draw document) can be extracted and accumulated.

The output there is done to a newly created Writer document. Of course, it would also be possible to use another ShapeText for the output. Just do it if you want. The code in the mentioned demo is public domain. If you can assure that the visible order of your shapes is concordant with the logical order, you can omit the sorting (which is the only part for which I actually wrote code not related to the API, and which might be done more efficiently by some ready-made Python function). If you can assure that the shapes you want to assemble text from never are grouped, you also can omit the recursive functions resolving the groups. (This was the part I was mainly interested in when I wrote the code.)

===Edit1 2019-01-07 21:50 CET===
I attach this demonstration of a simplified solution announced in my recent comment on the question.
Please note that none of the examples I gave worries about internal formatting or contained textfields (links). Everything is prefixed to the content of the final shape taking the character properties set there.
If you need the sorting, see the older demo I already pointed you to.

The only thing I didn’t do in my solution was use text cursors. Any particular reason I should? Would doing so potentially preserve formatting options like bold for instance?

Hmmm. To do a next step after some years I prepared the example originally trying to find a way to also move TextPortions which may simply be differently formatted TextRanges or TextFields like text which represents a background URL (the only type of fields that also may occur in TextShape). For that purpose I would need to create TextContent and to insert it at a cursor position. In cases of uniformity and assured no links can occur, you can simply concatenate the strings.
However, I left the topic without a solution for the extended task. I “lost the impetus”. Again no progress insofar.

Thank you so much @Lupp! You got me what I needed!

Here’s what I ended up with after everything was said and done:

REM  *****  BASIC  *****

Sub doIt()
	If NOT ThisComponent.supportsService("com.sun.star.drawing.DrawingDocument") Then Exit Sub

	curSel = ThisComponent.CurrentSelection
	curSelCount = curSel.Count
	If curSelCount <= 0 Then Exit Sub

	firstSel = curSel(0)
	firstSel.TextAutoGrowWidth = False
	firstSel.TextAutoGrowHeight = True

	For i=1 to curSelCount - 1
		sel = curSel(i)
		firstSel.String = firstSel.String + " " + Trim(sel.String)

		if sel.Size.Width > firstSel.Size.Width then
			firstSel.Size.Width = sel.Size.Width
		end if

		sel.Parent.remove(sel)
	Next i
	
	while InStr(firstSel.String, "  ") <> 0:
		firstSel.String = Replace(firstSel.String, "  ", " ")
	wend
End Sub

Function Replace(Source As String, Search As String, NewPart As String)
	Dim Result As String  
	Result = join(split(Source, Search), NewPart)
	Replace = Result
End Function