Impress text cursor macro out-of-date after edit

I am using the following macro to edit text in my presentation using a text cursor from getCurrentSelection(). For example, it will let you edit the text inside a rectangle object.

' First select some text in a text object (like a rectangle), then run this:
Sub Main
	' Get an XTextCursor for the selected text in your text object.
	' NOTE: If it gives an error, you likely did not have any text selected.
	dim oSel as Object, oTextCursor as Object
	oSel = ThisComponent.getCurrentSelection()
	oTextCursor = oSel.getText().CreateTextCursorByRange(oSel.getStart())

	' Insert into the text object a new string.
	dim oText as Object
	oText = oSel.getText()
	oText.insertString(oTextCursor, " [Hi] ", false)		
End Sub

However, this code has two problems:

  1. If the user has edited the text since they last clicked out of the object, the TextCursor does not correctly access the current text.
  2. The Impress UI does not refresh and show the edited text (after the macro runs) until after the user clicks out of the text box.

How can both access the correct currently selected text (even if there was an edit), and update the UI without clicking out of the object?

Brian

I found the answer with the help of an experienced LibreOffice developer (THANKS!).

The solution is to make a call to setCurrentPage() before and after editing with the TextCursor because it triggers Impress to sync the contents of the view (the front-end part of what is being edited) with the model (the back-end part storing the data).

Sub Main
	' Get an XTextCursor for the selected text in your text object.
	' NOTE: If it gives an error, you likely didn't have any text selected.
	dim oSel as Object, oTextCursor as Object
	oSel = ThisComponent.getCurrentSelection()
	oTextCursor = oSel.getText().CreateTextCursorByRange(oSel.getStart())

	SyncTextUiAndModel()

	' Insert into the text object a new string.
	dim oText as Object
	oText = oSel.getText()
	oText.insertString(oTextCursor, " [Hi] ", false)
	
	SyncTextUiAndModel()	
End Sub

Sub SyncTextUiAndModel
	' Trigger Impress to apply any pending changes in the view back to the model
	' Do this *after* getting the cursors because this will change the selection.
	dim oCurrentPage
	oCurrentPage = ThisComponent.getCurrentController().getCurrentPage()
	ThisComponent.getCurrentController().setCurrentPage(oCurrentPage)	
End Sub

For those interested in the LibreOffice internal, SdUnoDrawView::SetCurrentPage executes DrawViewShell::WriteFrameViewData, which syncs frame view data with the draw view data which syncs to the model when insertString is done in the macro.

Brian.