wizards/source/scriptforge/python/scriptforge.py | 3 + wizards/source/scriptforge/python/scriptforge.pyi | 6 ++ wizards/source/sfdocuments/SF_Calc.xba | 64 ++++++++++++++++++++++ wizards/source/sfdocuments/script.xlb | 8 +- 4 files changed, 77 insertions(+), 4 deletions(-)
New commits: commit b86e078d791e337fed2e42fb79fa3c58ff413d83 Author: Jean-Pierre Ledure <j...@ledure.be> AuthorDate: Sun Jan 12 15:08:44 2025 +0100 Commit: Jean-Pierre Ledure <j...@ledure.be> CommitDate: Sun Jan 12 16:15:38 2025 +0100 ScriptForge (SF_Calc new XRectangle property The XReetangle(rangename) property returns a com.sun.star.awt.Rectangle structure describing the coordinates (in pixels) on the screen where the given range is located. This opens the door to effective interactivity in calc sheets with the use of popup menus. Example: r = calc.XRectangle("B2") menu = CreateScriptService("PopupMenu", , _ X := r.X + r.Width/2, Y := r.Y + r.Height/2) initializes a popup menu centered on the given cell. The property exists in Basic and Python. The SF_Calc help page should be updated according to the actual patch. Change-Id: I2a97c5c7b5bf84d36a2aab5e4b822e30c9d53d8e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180140 Reviewed-by: Jean-Pierre Ledure <j...@ledure.be> Tested-by: Jenkins diff --git a/wizards/source/scriptforge/python/scriptforge.py b/wizards/source/scriptforge/python/scriptforge.py index 056694f61908..d558cc0bbd2c 100644 --- a/wizards/source/scriptforge/python/scriptforge.py +++ b/wizards/source/scriptforge/python/scriptforge.py @@ -2502,6 +2502,9 @@ class SFDocuments: def XCellRange(self, rangename): return self.ExecMethod(self.vbGet + self.flgUno, 'XCellRange', rangename) + def XRectangle(self, rangename): + return self.ExecMethod(self.vbGet + self.flgUno, 'XRectangle', rangename) + def XSheetCellCursor(self, rangename): return self.ExecMethod(self.vbGet + self.flgUno, 'XSheetCellCursor', rangename) diff --git a/wizards/source/scriptforge/python/scriptforge.pyi b/wizards/source/scriptforge/python/scriptforge.pyi index 0fe33b7fef46..d35ee2304fb0 100644 --- a/wizards/source/scriptforge/python/scriptforge.pyi +++ b/wizards/source/scriptforge/python/scriptforge.pyi @@ -164,6 +164,7 @@ try: from com.sun.star.sheet import XSheetCellCursor from com.sun.star.sheet import XSpreadsheet from com.sun.star.table import XCellRange + from com.sun.star.awt import XRectangle from com.sun.star.table import XTableChart from com.sun.star.uno import XComponentContext from com.sun.star.uno import XInterface @@ -194,6 +195,7 @@ except ImportError: XSheetCellCursor = NewType('XSheetCellCursor', UNO) XSpreadsheet = NewType('XSpreadsheet', UNO) XCellRange = NewType('XCellRange', UNO) + XRectangle = NewType('XRectangle', UNO) XTableChart = NewType('XTableChart', UNO) XComponentContext = NewType('XComponentContext', UNO) XInterface = NewType('XInterface', UNO) @@ -5040,6 +5042,10 @@ class SFDocuments: def XCellRange(self, rangename: RANGE) -> XCellRange: """ A ``com.sun.star.Table.XCellRange`` UNO object. """ ... + def XRectangle(self, rangename: RANGE) -> XRectangle: + """ A ``com.sun.star.awt.XRectangle`` UNO structure describing the area in pixels on the screen + where the range is located. """ + ... def XSheetCellCursor(self, rangename: str) -> XSheetCellCursor: """ A ``com.sun.star.sheet.XSheetCellCursor`` UNO object. """ ... diff --git a/wizards/source/sfdocuments/SF_Calc.xba b/wizards/source/sfdocuments/SF_Calc.xba index b644f66c8120..8b3b7101ed40 100644 --- a/wizards/source/sfdocuments/SF_Calc.xba +++ b/wizards/source/sfdocuments/SF_Calc.xba @@ -313,6 +313,14 @@ Property Get XCellRange(Optional ByVal RangeName As Variant) As Variant XCellRange = _PropertyGet("XCellRange", RangeName) End Property ' SFDocuments.SF_Calc.XCellRange +REM ----------------------------------------------------------------------------- +Property Get XRectangle(Optional ByVal RangeName As Variant) As Variant +''' Returns a UNO structure of type com.sun.star.awt.Rectangle +''' describing the area in pixels on the screen where the range is located. +''' Useful in the context of running mouse events and widgets like popup menus + XRectangle = _PropertyGet("XRectangle", RangeName) +End Property ' SFDocuments.SF_Calc.XRectangle + REM ----------------------------------------------------------------------------- Property Get XSheetCellCursor(Optional ByVal RangeName As Variant) As Variant ''' Returns a UNO object of type com.sun.star.sheet.XSheetCellCursor @@ -2582,6 +2590,7 @@ Public Function Properties() As Variant , "XCellRange" _ , "XComponent" _ , "XDocumentSettings" _ + , "XRectangle" _ , "XSheetCellCursor" _ , "XSpreadsheet" _ ) @@ -4493,6 +4502,13 @@ Const cstSubArgs = "" If Not ScriptForge.SF_Utils._Validate(pvArg, "Range", V_STRING) Then GoTo Finally Set _PropertyGet = _ParseAddress(pvArg).XCellRange End If + Case UCase("XRectangle") + If IsMissing(pvArg) Or IsEmpty(pvArg) Then + Set _PropertyGet = Nothing + Else + If Not ScriptForge.SF_Utils._Validate(pvArg, "Range", V_STRING) Then GoTo Finally + Set _PropertyGet = _RangePosition(pvArg) + End If Case UCase("XSheetCellCursor") If IsMissing(pvArg) Or IsEmpty(pvArg) Then Set _PropertyGet = Nothing @@ -4550,6 +4566,54 @@ Finally: Exit Function End Function ' SFDocuments.SF_Calc._QuoteSheetName +REM ----------------------------------------------------------------------------- +Private Function _RangePosition(ByVal psRange As String) As Object +''' Determine a best guess of the coordinates (in pixels) of the given range +''' Inspired (and enhanced) from https://forum.openoffice.org/en/forum/viewtopic.php?p=308693#p308693 +''' Args: +''' psRange: the range as a string +''' Returns: +''' a com.sun.star.awt.Rectangle UNO structure + +Dim oRectOnScreen As New com.sun.star.awt.Rectangle ' Range position versus top-left screen corner (return value) +Dim oRect As New com.sun.star.awt.Rectangle ' Range position versus the A1 cell +Dim oLocation As Object ' com.sun.star.awt.Rectangle +Dim oController As Object ' Current controller +Dim oXRange As Object ' com.sun.star.Table.CellRange + +Check: + On Local Error GoTo Finally + +Try: + Set oController = _Component.CurrentController + Set oXRange = _ParseAddress(psRange).XCellRange + ' Grab the window location on the screen + Set oLocation = oController.ComponentWindow.AccessibleContext.LocationOnScreen + + With oRect + .X = oXRange.Position.X + .Y = oXRange.Position.Y + .Width = oXRange.Size.Width + .Height = oXRange.Size.Height + End With + + 'Compute the rectangle in pixels (empirical computation) + With oController + oRectOnScreen.X = .VisibleAreaOnScreen.X _ + + .VisibleAreaOnScreen.Width * (oRect.X - .VisibleArea.X) / .VisibleArea.Width _ + - oLocation.X + oRectOnScreen.Y = .VisibleAreaOnScreen.Y _ + + .VisibleAreaOnScreen.Height * (oRect.Y - .VisibleArea.Y) / .VisibleArea.Height _ + - oLocation.Y + oRectOnScreen.Width = oRect.Width * .VisibleAreaOnScreen.Width / .VisibleArea.Width + oRectOnScreen.Height = oRect.Height * .VisibleAreaOnScreen.Height / .VisibleArea.Height + End With + +Finally: + Set _RangePosition = oRectOnScreen + Exit Function +End Function ' SFDocuments.SF_Calc._RangePosition + REM ----------------------------------------------------------------------------- Private Function _Repr() As String ''' Convert the SF_Calc instance to a readable string, typically for debugging purposes (DebugPrint ...) diff --git a/wizards/source/sfdocuments/script.xlb b/wizards/source/sfdocuments/script.xlb index 6945460dda77..3d2264bd3f6d 100644 --- a/wizards/source/sfdocuments/script.xlb +++ b/wizards/source/sfdocuments/script.xlb @@ -2,14 +2,14 @@ <!DOCTYPE library:library PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "library.dtd"> <library:library xmlns:library="http://openoffice.org/2000/library" library:name="SFDocuments" library:readonly="false" library:passwordprotected="false"> <library:element library:name="__License"/> + <library:element library:name="SF_Form"/> + <library:element library:name="SF_DocumentListener"/> <library:element library:name="SF_Document"/> <library:element library:name="SF_Calc"/> + <library:element library:name="SF_Writer"/> <library:element library:name="SF_Register"/> <library:element library:name="SF_Base"/> - <library:element library:name="SF_Form"/> <library:element library:name="SF_FormControl"/> - <library:element library:name="SF_Writer"/> - <library:element library:name="SF_Chart"/> - <library:element library:name="SF_DocumentListener"/> <library:element library:name="SF_FormDocument"/> + <library:element library:name="SF_Chart"/> </library:library> \ No newline at end of file