positionmousecopy-pastebasicopenoffice-basic

How to get Document-Coordinates from a Mouse Click in an OpenOffice BASIC Macro


Background:

I want to paste (like [CTRL+V]) anything (preferably image, shape) at the position I click or hover with the mouse (when using a key to activate). I don't know how to get the position on the document (X, Y) I clicked.

(Apache OpenOffice, SDraw-Document, OpenOffice BASIC Macro)

What I need:

Notes: Something like a com.sun.star.awt.XMouseClickHandler would be perfect, if the given oEvent gave me the X+Y of the document, where I clicked. (Maybe you know how to "activate" PopupTrigger? (com.sun.star.awt.MouseEvent))

My code so far:

I tried using the mentioned XMouseClickHandler to get X+Y. Sadly, X+Y refer to the relative position of the window and not the actual position a shape or text would have on the document.

Execution: My Sub Main is executed via a Menu-Button at the top. Then clicking anywhere will output (via MsgBox) the coordinates of that click.

Only Problem: Coordinates are relative to the corner of the window, not the corner of the document.

Global gListener As Object

Sub Main
  gListener = CreateUnoListener("Listener_","com.sun.star.awt.XMouseClickHandler")
  ThisComponent.CurrentController.addMouseClickHandler(gListener) 
End Sub

Sub Listener_mousePressed(oMouseEvent) As Boolean
   ThisComponent.CurrentController.removeMouseClickHandler(gListener)

   Msg = "Position: "
   Msg = Msg & oMouseEvent.X & "/" & oMouseEvent.Y
   MsgBox(Msg)

   REM :: I want something like:
   REM :: Msg = "Position: " & oMouseEvent.PositionOnDocument.X
   REM :: Msg = Msg & "/" & oMouseEvent.PositionOnDocument.Y
   REM :: MsgBox(Msg)
End Sub

My references:

All my information come from the official references/docs so far, since all my searches did not find anything helpful.

Thanks in advance.


Solution

  • I finally found a way to get the exact coordinates of a mouse click (relative to the document). I managed to get the information from the StatusBar at the bottom, which usually shows the coordinates (for me in centimeters).

    Here is the function I now use to get the position (X / Y):

    REM // Warning: If there is currently a selection, the returning Point will instead show the coordinates of the selection!
    Sub GetMousePositionOnDocument as com.sun.star.awt.Point
      Dim aPosition As New com.sun.star.awt.Point
      Dim o1, o2, o3, o4, o5, o6
    
      REM // First get AccessibleContext of the Window of the active Frame of the Application
      o1 = StarDesktop.ActiveFrame.ContainerWindow.AccessibleContext
    
      REM // 7th AC of o1 is the StatusBar at the bottom;
      o2 = o1.GetAccessibleChild(6).AccessibleContext
    
      REM // 2nd AC of o2 is the Position + Size of the Selection (e.g: "10,95 / 14,980,00 x 0,00") 
      o3 = o2.GetAccessibleChild(1)
      o4 = o3.GetText()
    
      REM // Taking out only the coordinates from o4
      REM // TODO: Check for negatives (longer)
      o5 = LEFT(o4, 4)
      o6 = MID(o4, 8, 5)
    
      aPosition.X = o5
      aPosition.Y = o6
    
      REM // Return
      GetMousePositionOnDocument = aPosition
    End Sub
    

    Note: This function is called inside my previous Listener_mousePressed from above.

    Hopefully this will work for others, too.

    How I found it?

    I spent very much time on checking every single ApplicationContext of the Window(s) of ThisComponent and StarDesktop manually in the debugger.

    This is the starting point for iterating through ThisDesktop if needed for other values. ThisComponent.CurrentController.Frame.ComponentWindow.AccessibleContext

    Future Improvements

    I "know" the indexes for the GetAccessibleChild()-Function because I inspected the debugger. There certainly are better ways to get to o3 and you should not expect everyone to have the same AccessibleContext's.