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(&quot;XCellRange&quot;, RangeName)
 End Property   &apos;  SFDocuments.SF_Calc.XCellRange
 
+REM 
-----------------------------------------------------------------------------
+Property Get XRectangle(Optional ByVal RangeName As Variant) As Variant
+&apos;&apos;&apos;     Returns a UNO structure of type 
com.sun.star.awt.Rectangle
+&apos;&apos;&apos;     describing the area in pixels on the screen where the 
range is located.
+&apos;&apos;&apos;     Useful in the context of running mouse events and 
widgets like popup menus
+       XRectangle = _PropertyGet(&quot;XRectangle&quot;, RangeName)
+End Property   &apos;  SFDocuments.SF_Calc.XRectangle
+
 REM 
-----------------------------------------------------------------------------
 Property Get XSheetCellCursor(Optional ByVal RangeName As Variant) As Variant
 &apos;&apos;&apos;     Returns a UNO object of type 
com.sun.star.sheet.XSheetCellCursor
@@ -2582,6 +2590,7 @@ Public Function Properties() As Variant
                                        , &quot;XCellRange&quot; _
                                        , &quot;XComponent&quot; _
                                        , &quot;XDocumentSettings&quot; _
+                                       , &quot;XRectangle&quot; _
                                        , &quot;XSheetCellCursor&quot; _
                                        , &quot;XSpreadsheet&quot; _
                                        )
@@ -4493,6 +4502,13 @@ Const cstSubArgs = &quot;&quot;
                                If Not ScriptForge.SF_Utils._Validate(pvArg, 
&quot;Range&quot;, V_STRING) Then GoTo Finally
                                Set _PropertyGet = 
_ParseAddress(pvArg).XCellRange
                        End If
+               Case UCase(&quot;XRectangle&quot;)
+                       If IsMissing(pvArg) Or IsEmpty(pvArg) Then
+                               Set _PropertyGet = Nothing
+                       Else
+                               If Not ScriptForge.SF_Utils._Validate(pvArg, 
&quot;Range&quot;, V_STRING) Then GoTo Finally
+                               Set _PropertyGet = _RangePosition(pvArg)
+                       End If
                Case UCase(&quot;XSheetCellCursor&quot;)
                        If IsMissing(pvArg) Or IsEmpty(pvArg) Then
                                Set _PropertyGet = Nothing
@@ -4550,6 +4566,54 @@ Finally:
        Exit Function
 End Function   &apos;  SFDocuments.SF_Calc._QuoteSheetName
 
+REM 
-----------------------------------------------------------------------------
+Private Function _RangePosition(ByVal psRange As String) As Object
+&apos;&apos;&apos;     Determine a best guess of the coordinates (in pixels) 
of the given range
+&apos;&apos;&apos;     Inspired (and enhanced) from 
https://forum.openoffice.org/en/forum/viewtopic.php?p=308693#p308693
+&apos;&apos;&apos;     Args:
+&apos;&apos;&apos;             psRange: the range as a string
+&apos;&apos;&apos;     Returns:
+&apos;&apos;&apos;             a com.sun.star.awt.Rectangle UNO structure
+
+Dim oRectOnScreen As New com.sun.star.awt.Rectangle    &apos;  Range position 
versus top-left screen corner (return value)
+Dim oRect As New com.sun.star.awt.Rectangle                    &apos;  Range 
position versus the A1 cell
+Dim oLocation As Object                                                        
        &apos;  com.sun.star.awt.Rectangle
+Dim oController As Object                                                      
&apos;  Current controller
+Dim oXRange As Object                                                          
&apos;  com.sun.star.Table.CellRange
+
+Check:
+       On Local Error GoTo Finally
+
+Try:
+       Set oController = _Component.CurrentController
+       Set oXRange = _ParseAddress(psRange).XCellRange
+       &apos;  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
+
+       &apos;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   &apos;  SFDocuments.SF_Calc._RangePosition
+
 REM 
-----------------------------------------------------------------------------
 Private Function _Repr() As String
 &apos;&apos;&apos;     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

Reply via email to