Comparison ViewCursor and TextCursor

As a VBA programmer, I was having a bit of difficulty understanding the concepts of ViewCursor and TextCursor in LibreOffice object model. So I asked ChatGPT Code Copilot to compare the two. I would be very grateful if some knowledgeable person could have a look at the answer and tell me if it’s more or less accurate.

In the LibreOffice Writer object model, ViewCursor and TextCursor are both used to navigate and manipulate text, but they serve different purposes and have distinct characteristics:

ViewCursor

  • Purpose: The ViewCursor represents the position of the visible cursor in the document as seen by the user. It is tied to the user interface and reflects the user’s current position in the document.
  • Usage: It is used for tasks that require interaction with the visible part of the document, such as moving the cursor to a specific location that the user can see or selecting text that the user has highlighted.
  • Scope: The ViewCursor is specific to the view controller of the document. It is part of the view and not the underlying text content.
  • Example: Moving the visible cursor to the end of the document:
    Dim oDoc As Object
    Dim oViewCursor As Object
    oDoc = ThisComponent
    oViewCursor = oDoc.CurrentController.ViewCursor
    oViewCursor.gotoEnd(False)
    

TextCursor

  • Purpose: The TextCursor is used for navigating and manipulating the text content within the document. It operates on the underlying text, independent of the user interface.
  • Usage: It is used for tasks like inserting, deleting, or formatting text within the document. It can navigate through the text content and perform operations that affect the document’s text structure.
  • Scope: The TextCursor operates on the Text object of the document. It is not tied to the visible cursor or the user interface.
  • Example: Inserting text at the end of the document:
    Dim oDoc As Object
    Dim oText As Object
    Dim oTextCursor As Object
    oDoc = ThisComponent
    oText = oDoc.Text
    oTextCursor = oText.createTextCursor()
    oTextCursor.gotoEnd(False)
    oText.insertString(oTextCursor, "This is the end of the document.", False)
    

Key Differences

  • Interface vs. Content:

    • ViewCursor is linked to the user interface and represents what the user sees.
    • TextCursor is linked to the document content and can operate on text that might not be visible to the user.
  • Visibility:

    • Moving the ViewCursor affects the visible cursor position.
    • Moving the TextCursor does not affect the visible cursor position unless explicitly synchronized with the ViewCursor.
  • Functionality:

    • ViewCursor is used for tasks involving user interaction and visual feedback.
    • TextCursor is used for tasks involving text manipulation and document content changes.

Practical Example to Illustrate the Difference

Here’s an example where both cursors are used:

  • The ViewCursor moves to the start of the document.
  • The TextCursor inserts text at that position without moving the ViewCursor.
Sub ExampleUsingBothCursors()
    Dim oDoc As Object
    Dim oViewCursor As Object
    Dim oText As Object
    Dim oTextCursor As Object

    oDoc = ThisComponent
    oViewCursor = oDoc.CurrentController.ViewCursor
    oText = oDoc.Text

    ' Move the ViewCursor to the start of the document
    oViewCursor.gotoStart(False)

    ' Create a TextCursor at the ViewCursor position
    oTextCursor = oText.createTextCursorByRange(oViewCursor.getStart())

    ' Insert text at the TextCursor position
    oText.insertString(oTextCursor, "Inserted text at the start.", False)

    ' The ViewCursor remains at the start
End Sub

In this example, the ViewCursor is moved to the start of the document, and the TextCursor is used to insert text at that position. The ViewCursor does not move from the start position, demonstrating how the two cursors can operate independently.

definitely more or less accurate :wink:

probably more effective here (i.e. for human readers, potentially knowledgeable ones) to point more precisely YOUR difficulties, based on actual doc and samples.

random pick : Bring Writer macro cursor into view?

1 Like

@fpy Thank you very much for your response. If I understand correctly, you mean that I should explain my personal difficulties in understanding the difference? I will try.
.
I am currently not looking for help to solve any particular problem. Instead, I am trying to understand the concepts of “ViewCursor” and “TextCursor” from the perspective of a Microsoft VBA programmer who wants to learn the LibreOffice object model, as it is used in LibreOffice Basic. I am also not looking for tips or help that are based on other programming languages such as Python.
.
In the Microsoft Word object model, there exists the Selection object, which “represents either a selected (or highlighted) area in the document, or it represents the insertion point if nothing in the document is selected.”
.
The Selection object can be used for example in the following way to move the cursor to the end of the document and then insert a manual page break:
.

Selection.EndKey wdStory
Selection.InsertBreak Type:=wdPageBreak

.
In LibreOffice Basic, using the LibreOffice object model, my understanding is that these actions can be achieved as follows:
.
Move the insertion point to the end of the document using a ViewCursor:
.

ThisComponent.getCurrentController().getViewCursor().gotoEnd(False)

.
Insert a page break at the insertion point using a TextCursor:

Dim oText As Object
Dim oTextCursor As Object

oText = ThisComponent.Text
oTextCursor = oText.CreateTextCursor

' Move the text cursor to the end of the document
oTextCursor.gotoEnd(False)
    
' Set the break type to PAGE_AFTER
oTextCursor.BreakType = com.sun.star.style.BreakType.PAGE_AFTER
    
' Insert the control character for the page break
oText.insertControlCharacter(oTextCursor, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, False)

.
I am anything but an expert LibreOffice Basic programmer, so I am sure the code above can be improved in some way.
.
However, it illustrates the point that LibreOffice uses two different types of cursor for two actions that are both handled by the Selection object in Microsoft Word.
.
I have also read somewhere that there are quite a number of other types of cursor in the LibreOffice object model.
.
This is a bit confusing for someone migrating from Microsoft VBA and the Office object model to LibreOffice Basic and API.
.
This is why I am looking for a general explanation and comparison of at least the above mentioned LibreOffice cursor types (but possibly the other types as well), specifically from the point of view of LibreOffice Basic, i.e. why multiple cursor types exist, what the differences are, what the usages are, and so on.
.
Any guidance on where I could find this kind of information would be very appreciated.

https://wiki.documentfoundation.org/Documentation/SDKGuide/Text_API_Overview#1._An_Overview_of_the_Text_Document_API

1 Like

For python here are a few links related to Cursors.


OOO Development Tools has a number of classes related to cursors. The Selection class which is part of the Write class has many features that are related to Text Cursors and View cusrors. These are Static classes; However, many of the more dynamic implements can be seen in the write namespace.


Cursor and Text Enumeration Related Examples on Live LibreOffice Python UNO Examples

1 Like

Thanks, Mike!

Thank you, vib!

In general:

  1. If you do something that needs to know or change the visible cursor / selection, you use view cursor. This may include moving the cursor, selecting something, or getting the visible cursor position (as a starting point, e.g. when your program should respect user’s current position - say, when you search starting from current point).

  2. When your work doesn’t need the visible cursor changes, you use text cursor.

In your example case, it is not clear, if you really need the visible cursor to move to the place after the newly inserted page break. Since all visual changes are much more expensive than internal changes using text cursor, it is advisable to do the changes that involve view cursor like this: you get the starting point using view cursor, create text cursor using createTextCursorByRange, use that text cursor (or several of them) to navigate and manipulate text in the document (go to different parts by character, word, sentence, or paragraph; replace text fragments, insert text content objects, etc.); and finally, when you know where to move the visible cursor, you do it using the visible cursor instance and a text cursor range. Indeed, to improve performance (and maybe prevent edit conflicts during lengthy execution), you also need to lock the controllers for the execution period; since the code may potentially fail, it’s best to use fail-safe techniques for the lock/unlock pairs.

An important case when you use view cursor is when you navigate the layout of the document, or user interface details, as opposed to the document model. When you need to know pages ranges, or screens, you can’t use text cursor, only view cursor (that gives you access to XViewCursor, XLineCursor, XScreenCursor and XPageCursor interfaces).

This is very valuable information. Thank you very much for this.