How to Determine if the Cursor is Inside a Comment Box

So my problem is that I’ve got a number of icons on a custom toolbar a couple of which simply move the cursor to a bookmark in the Writer document. Each of the icons invoke a macro that passes the name of the bookmark to go to to this Sub:

Sub GoToNamedBookmark(BookmarkName)

Dim ViewCursor, AllBookmarks, BookmarkAnchor As Object

   ' We first check to see if the desired bookmark exists

    AllBookmarks = ThisComponent.getBookmarks()  
    If NOT AllBookmarks.hasByName(BookmarkName) Then
       MsgBox("The bookmark" + BookmarkName + " does not exist!", 16, "GoToNamedBookmark")
       Exit Sub
    End If

    ' At this point we can try to move the ViewCursor to the Bookmark
   ViewCursor = ThisComponent.CurrentController.getviewCursor()
   BookmarkAnchor = ThisComponent.Bookmarks.getByName(BookmarkName).Anchor
   ViewCursor.gotorange(BookmarkAnchor, False)

End Sub

It all works properly so long as the cursor is inside the main document window. But I get a runtime error – on the very last line – if the cursor is inside an actual comment box, also called an annotation.

CommentBox

So what I need is a way to determine if the cursor is actually inside a comment box, and how to give the main document the focus again. (I’m assuming that is the real problem here.)

In my tests, current selection inside comment box is always Null

selection = ThisComponent.CurrentController.Selection
MsgBox IsNull(selection)

but, I’m not sure if always is that.

1 Like

Thanks very much for this answer. This does appear to work as you say. In fact, I found that I could actually select text in the comment box, and ThisComponent.CurrentController.Selection still was null. I just wish I knew a bit more about why this works this way. I’ll do some more testing to see what happens if the cursor is in other oddball places, like some other kind of field, just to see what happens. Thanks again for this idea.

In Writer documents annotations (“comments”) are implemented as instances of a specialized type of TextField objects. They have an anchor (TextRange) and lots of additional properties.
Only the ViewCursor will provide access to such an object if it is placed inside.

Function tryGetCurrentAnnotationTextField(Optional pDoc) As Object
If IsMissing(pDoc) Then pDoc = ThisComponent
On Local Error Goto fail
tf = pDoc.CurrentController.ViewCursor.TextField
If tf.supportsService("com.sun.star.text.textfield.Annotation") Then
  tryGetCurrentAnnotationTextField = tf
EndIf
fail:
End Function

Sub tryIt()
anno = tryGetCurrentAnnotationTextField(ThisComponent)
If IsNull(anno) Then
  MsgBox("The ViewCursor is NOT inside a text annotation.")
Else
  MsgBox(anno.Author & " wrote in this annotation: " & Chr(10) & anno.Content)
EndIf
End Sub
3 Likes

Hello and thanks for this helpful reply. I was at one point using code very similar to what you propose, and I’ve gone back to it for now. The code I was using is this:

   ' Make sure the cursor is not in a Comment box!
   ViewCursor = ThisComponent.CurrentController.getviewCursor()
   If NOT IsEMpty(ViewCursor.TextField) Then
     If ViewCursor.TextField.supportsService("com.sun.star.text.textfield.Annotation") Then Exit Sub
   End If

This certainly works, but I remember that I dropped this approach because I found that I could place the cursor in the document area itself, and it could overlap the location where the Annotation TextField was inserted into the text and then the code wold think you were in the comment Box.

You can check this out yourself. Start a new paragraph. Type capital A and a period after it. Then select the “A” and press CTRL + ALT + C to make the annotation. Type anything into the comment box itself.
Now place the cursor in front of the A. Then press the Right Arrow key. The cursor moves to the right side of the “A”, but now the dashed line of the comment box turns solid.So the cursor is over the insertion point of the Annotation TextField and the code above again thinks that the cursor is inside a comment box.

Still, this is an unusual circumstance and the code does prevent a runtime error, so I’m going to stick with this for now. But I’m eager to experiment with elmau’s idea to see if can understand why it seems to work the way it does.

Once again thanks to you both for your very helpful replies. I really appreciate it.