Macro to manipulate text within a text box

I have a number of basic macros to manipulate text, for example to swap the characters before and after the cursor. These macros fail if the text is inside a text box. There seem to be some Visual Cursor properties and methods that do not work in a text box. For example the text property. I presume the text is presumably a property of the text box. Is there a way of detecting that the cursor is in a text box (and perhaps determining its name). And how should the text in the box be handled?
TextBoxTest.odt (17.5 KB)

At request of @KamilLanda , a simple example attached.

(This is an opinion based on some experience.)
… …

This the simple thing if that TextBox is a shape: The CurrentSelection(0) then simply is the TextBox object supporting the service com.sun.star.drawing.TextShape, and it has a string property .Name .
… …
But:
There are (at least?) two object types called “TextBox”.
One is a shape, and the API merges the graphical services and the services concerning the (reduced) textual aspects into one object. You can’t separate both sides of the medal. In the navigator such an object is shown with an automatically assigned “name” not shown in any dialog, afaik. If you assign a different name to the object by user code, this is accepted and remembered, but the navigator will only show the new name after it was closed and opened again …
The ViewCursor doesn’t show the “subselection” inside.
In short: It’s a mess. Save your time.
The only way to work with parts of the contained text is to step through finding ranges by enumeration and/or using a TextCursor. But such a cursor you can’t select with the CurrentController by user code, and therefore you also can’t get it as a “transferable” object e.g.
… …
The other “TextBox” type is a FomControl. You may play with one. It’s completely different, of course.
… …
Save your time.

@Lupp That looks really helpful (thanks for your help) and unhelpful (because the result is a bit depressing). I’ll explore some of what you say, but I haven’t much time to give to it, so probably your conclusion will stand. Thanks anyway

@Pansmanser
Think twice before using TextBoxes. New users instinctively use them for lack of understanding 1) their real needs (relation of the information in the “box” with main text) and 2) the properties of TextBoxes.

Unless you’re designing a form, don’t use text boxes because they are graphical objects with not-immediately-understandable interaction with text. If what you want to enter into the “box” is some kind of comment or side note, prefer text frames which are in fact “sub-documents” and offer full formatting capabilities. But don’t use them for headings in funny locations because you’ll end up with a weird numbering sequence (there is no order relation between main text and text frames; therefore, text in frames is really independent from main flow and the order in which they are considered is unpredictable – or rather, it is predictable but don’t rely on it; any little change in the document alters this order).

For headings in margins or any unusual layout, learn how to master paragraph styles, in this case, the Heading n family.

I made the macro only for Textboxes in your example to see the work with Textboxes. Select the Textbox with one type of selection and run macro CHANGE_TextBox.
The macro uses the System clipboard via Uno commands to detect and modify the selected text in Textbox, and also the simulation of key pressing can be use.
If only Selection 1 is used, then it is also possible to use TextCursor for Textbox. But if you need the selection within Textbox like Selection 2 then I know only Copy/Paste to modify the selected text within Textbox.
TextBoxTest-edit2.odt (41.8 kB)

Thanks, @KamilLanda, I think you’ve cracked the basic problem. I’ll be able to fiddle other things from there. I also like your flexible uno subroutine.

I tried the detection via .getTransferable (that is safer than system clipboard) and it seems OK. .uno:InsertText replaces the selection inside the Textbox.

Sub CHANGE_TextBox 'change selected text in Textbox or Change all Text in Textbox if single Textbox is selected; if Visible Cursor is in Textbox but no text is selected then it shows the Name of Textbox
	dim oDoc as object, oSel as object, v as variant
	oDoc=ThisComponent
	oSel=oDoc.CurrentController.Selection.getByIndex(0) 'only 1st selection
	if oSel.supportsService("com.sun.star.drawing.TextShape") then 'selection is TextShape
		v=getStringFromCopy(oDoc)
		if IsNull(v) then 'SELECTION 1
			oSel.String=changeCase(oSel.String) 'change all Text in Textbox
		elseif v="" then 'SELECTION 3
			msgbox oSel.Name
		else 'SELECTION 2
			dim args0(0) as new com.sun.star.beans.PropertyValue, oCur as object
				args0(0).Name="Text"
				args0(0).Value=changeCase(v)
			uno(oDoc, "InsertText", args0) 'replace selection by changed text
		end if
	end if
End Sub

Function changeCase(sChange$)
	if UCase(sChange)=sChange then 'If in UPPER CASE
		sChange=LCase(sChange) 'change to lower case
	elseif LCase(sChange)=sChange then 'If lower case, make Title Case
		c1=UCase(Left(sChange, 1)) 'get the first character and convert to upper
		Mid(sChange, 1, 1, c1) 'replace that char in sChange
		for i=2 to Len(sChange) 'scan the string look for separators
			c1=Mid(sChange, i, 1)
			if (c1=" " OR c1=Chr(9)) then 'spaces and tabs
				c1=UCase(Mid(sChange, i+1, 1)) 'change next character.
				Mid(sChange, i+1, 1, c1) '(leave space alone and) put cap back in
			endif
		next
	else
		sChange=UCase(sChange) 'Otherwise it's mixed (eg title), change to UPPER
	end if
	changeCase=sChange
End Function

Function getStringFromCopy(oDoc as object) as variant 'Ctrl+C via .getTransferable() and return the copied text as string
	on local error goto bug
	dim data as object, aFlavor as new com.sun.star.datatransfer.DataFlavor
	data=oDoc.CurrentController.getTransferable()
	for each aFlavor in data.TransferDataFlavors
		if aFlavor.HumanPresentableName="Text" AND aFlavor.MimeType="text/plain;charset=utf-16" then 'there is Text in copied data
			getStringFromCopy=data.getTransferData(aFlavor)
			exit function
		end if
	next
	getStringFromCopy=Nothing
	exit function
bug:
	bug(Erl, Err, Error, "getStringFromCopy")
End Function

Sub bug(sErl$, sErr$, sError$, sFce$) 'show error message and stop macro
	msgbox("line: " & sErl & chr(13) & sErr & ": " & sError, 16, sFce)
	stop
End Sub

Sub uno(oDoc as object, s$, optional param()) 'Uno command in oDoc
	if isMissing(param) then param=array()
	s=".uno:" & s
	createUnoService("com.sun.star.frame.DispatchHelper").executeDispatch(oDoc.CurrentController.Frame, s, "", 0, param)
End Sub