Python macro to insert text at GUI cursor position

I’m trying to get a simple python macro working in Writer. It’s little more than a glorified “Hello World”, all it needs to do is insert some text in the current document, at the current GUI cursor position.

I’m finding it absurdly complicated to perform this trivial task. I’ve tried several approaches, all seem to hit some problem. I can insert the text at the beginning or end of the document, but haven’t found a way to insert text at the cursor position.

I’ve looked at the documentation, but I’ve not figured this out. I’ve seen something called TextCursor, which I’ve used, but this is not what I want. I’ve seen something called TextViewCursor, and this might be what I want, but I’ve not been able to get the code working, because apparently TextViewCursors are entirely different things from TextCursors and I can’t figure out how to create one.

So, anyone got pointers for a python “Hello World” macro that inserts the string at the current cursor position?

I have the same issue, but I am trying to write a javascript macro. The sparse examples I can find say invoke getViewCursor() on the CurrentController object, but both controllers from the document {oDoc = XSCRIPTCONTEXT.getDocument();} and the text document { xTextDoc = UnoRuntime.queryInterface(XTextDocument,oDoc) } do not recognize a getViewCursor() method.

To do this in Writer in Python, here is an adaptation from the HelloWorld.py script included in the standard LO distribution:

def HelloWorldPython( ):
    #get the doc from the scripting context which is made available to all scripts
    desktop = XSCRIPTCONTEXT.getDesktop()
    model = desktop.getCurrentComponent()
    #get the cursor
    ctrllr = model.CurrentController
    curview = ctrllr.ViewCursor
    curview.String = "Hello World (in Python at cursor)"
    return None

With the head start in the standard HelloWorld macro, it was easy to fill in the rest knowing how to do this in LO Basic is:

cntrllr = ThisComponent.CurrentController
vcur = cntrllr.ViewCursor
vcur.String = "Hello World "

Other useful methods of ViewCursor, which presumably are the same in Python are:

SbxSTRING getString ( void ) ; SbxVOID setString ( SbxSTRING ) ; 
SbxVOID collapseToStart ( void ) ; SbxVOID collapseToEnd ( void ) ; 
SbxBOOL isCollapsed ( void ) ; SbxBOOL goLeft ( SbxINTEGER, SbxBOOL ) ; 
SbxBOOL goRight ( SbxINTEGER, SbxBOOL ) ; SbxVOID gotoStart ( SbxBOOL ) ; 
SbxVOID gotoEnd ( SbxBOOL ) ; SbxVOID gotoRange ( SbxOBJECT, SbxBOOL ) ; 
SbxBOOL isVisible ( void ) ; SbxVOID setVisible ( SbxBOOL ) ; SbxOBJECT getPosition ( void );
SbxBOOL jumpToFirstPage ( void ) ; SbxBOOL jumpToLastPage ( void ) ; 
SbxBOOL jumpToPage ( SbxINTEGER ) ; SbxINTEGER getPage ( void ) ; 
SbxBOOL jumpToNextPage ( void ) ; SbxBOOL jumpToPreviousPage ( void ) ; 
SbxBOOL jumpToEndOfPage ( void ) ; SbxBOOL jumpToStartOfPage ( void ) ; 
SbxBOOL screenDown ( void ) ; SbxBOOL screenUp ( void ) ;
SbxBOOL goDown ( SbxINTEGER, SbxBOOL ) ; SbxBOOL goUp ( SbxINTEGER, SbxBOOL ) ;
SbxBOOL goLeft ( SbxINTEGER, SbxBOOL ) ; SbxBOOL goRight ( SbxINTEGER, SbxBOOL ) ;
SbxBOOL isAtStartOfLine ( void ) ; SbxBOOL isAtEndOfLine ( void ) ;
SbxVOID gotoEndOfLine ( SbxBOOL ) ; SbxVOID gotoStartOfLine ( SbxBOOL ) ; 

Other useful properties of ViewCursor: many formatting options and,

SbxOBJECT Start; SbxOBJECT End; SbxSTRING String; 
SbxOBJECT Position; SbxBOOL Visible; SbxINTEGER Page;

I found a way to do it in Javascript. I am a neophyte with python, so I did not attempt the changes there

// to the hello world script add imports -   

importClass(Packages.com.sun.star.container.XIndexAccess); 
importClass(Packages.com.sun.star.view.XSelectionSupplier);

//...

// replace xTextRange = xText.getEnd();  with -

// Get all selected regions of the document
xSelectionSupplier = UnoRuntime.queryInterface(XSelectionSupplier, oDoc.getCurrentController());
xIndexAccess = UnoRuntime.queryInterface(XIndexAccess, xSelectionSupplier.getSelection());
var xTextRange;

if ( 0 <  xIndexAccess.getCount() )  {
        xTextRange = UnoRuntime.queryInterface(XTextRange, xIndexAccess.getByIndex(0)); // first selection
} else {
 	xTextRange = xText.getEnd();
}