wizards/source/scriptforge/python/scriptforge.py | 12 ++ wizards/source/scriptforge/python/scriptforge.pyi | 32 +++++-- wizards/source/sfwidgets/SF_ContextMenu.xba | 98 +++++++++++++++++++--- wizards/source/sfwidgets/SF_Register.xba | 2 wizards/source/sfwidgets/script.xlb | 12 +- 5 files changed, 128 insertions(+), 28 deletions(-)
New commits: commit ca1dca4f1df7ba4b0b74e4a378169c8f8cf690d0 Author: Jean-Pierre Ledure <j...@ledure.be> AuthorDate: Mon Jan 20 17:11:40 2025 +0100 Commit: Jean-Pierre Ledure <j...@ledure.be> CommitDate: Tue Jan 21 09:30:57 2025 +0100 ScriptForge (ContextMenu) new RemoveAllItems() method The contextmenu service handles the context menus stored in a document. So far, it provided only the AddItem() method to add new items at the bottom of the menu. The new method allows to forget the preconfigured menu and to replace it completely. Example: associate next Sub with the on-right-click event of sheet 'Sheet1' => The custom menu appears when right-clicking in column C, otherwise normal behaviour Sub OnRightClick1(Optional XRange) ' Xrange is a com.sun.star.table.XCellRange Dim calc, menu, bColumn Set calc = CreateScriptService("Calc", ThisComponent) Set menu = calc.ContextMenus("cell") menu.RemoveAllItems() bColumn = ( Len(calc.Intersect("Sheet1.$C:$C", _ XRange.AbsoluteName)) > 0 ) If bColumn Then menu.AddItem("A", Script := "vnd.sun.star.script:...&location=document") ... End If menu.Activate(bColumn) End Sub The function is available both for Basic and Python user scripts. The user documentation will have to be reviewed. Change-Id: I84ee8724bf99c37397a19d729133cc4686a63980 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/180520 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 3b8df9083ef6..3e3e91cfcde2 100644 --- a/wizards/source/scriptforge/python/scriptforge.py +++ b/wizards/source/scriptforge/python/scriptforge.py @@ -2929,14 +2929,17 @@ class SFWidgets: A context menu is usually predefined at LibreOffice installation. Customization is done statically with the Tools + Customize dialog. - The actual service provides a mean to make temporary additions at - the bottom of a context menu. Those changes are lost when the document is closed. + + The actual service provides means + - to make temporary additions at the bottom of a context menu, + - to replace entirely a context menu. + Those changes are lost when the document is closed. """ # Mandatory class properties for service registration serviceimplementation = 'basic' servicename = 'SFWidgets.ContextMenu' servicesynonyms = ('contextmenu', 'sfwidgets.contextmenu') - serviceproperties = dict(ShortcutCharacter = 0, SubmenuCharacter = 0) + serviceproperties = dict(ParentDocument = 0, ShortcutCharacter = 0, SubmenuCharacter = 0) def Activate(self, enable = True): return self.ExecMethod(self.vbMethod, 'Activate', enable) @@ -2944,6 +2947,9 @@ class SFWidgets: def AddItem(self, menuitem, command = '', script = ''): return self.ExecMethod(self.vbMethod, 'AddItem', menuitem, command, script) + def RemoveAllItems(self): + return self.ExecMethod(self.vbMethod, 'RemoveAllItems') + # ######################################################################### # SF_PopupMenu CLASS diff --git a/wizards/source/scriptforge/python/scriptforge.pyi b/wizards/source/scriptforge/python/scriptforge.pyi index 0c0bf92868b3..b04fa691b6ac 100644 --- a/wizards/source/scriptforge/python/scriptforge.pyi +++ b/wizards/source/scriptforge/python/scriptforge.pyi @@ -6926,15 +6926,18 @@ class SFWidgets: """ Complete a predefined context menu with new items. - A context menu is obtained by a right-click on several areas of a document. + A context menu is obtained by a right-click on specific areas of a document. Each area determines its own context menu. (Consider right-clicking on a cell or on a sheet tab in a Calc document). Each component model has its own set of context menus. A context menu is usually predefined at LibreOffice installation. Customization is done statically with the Tools + Customize dialog. - The actual service provides a mean to make temporary additions at - the bottom of a context menu in an active document. Those changes are lost when the document is closed. + + The actual service provides means + - to make temporary additions at the bottom of a context menu, + - to replace entirely a context menu. + Those changes are lost when the document is closed. The name of a context menu is the last component of the resource URL: "private:resource/popupmenu/the-name-here" @@ -6942,6 +6945,8 @@ class SFWidgets: Context menu items are either usual items or line separators. Checkboxes or radio buttons are not supported. """ + ParentDocument: Union[DOCUMENT, BASE, CALC, FORMDOCUMENT, WRITER] + """ Document class (or one of its subclasses) instance to which the context menu belongs to. """ ShortcutCharacter: str """ Character used to define the access key of a menu item. The default character is "~" (tilde). """ SubmenuCharacter: str @@ -6973,11 +6978,11 @@ class SFWidgets: def Activate(self, enable: bool = ...) -> None: """ - Make the added items of the context menu available for execution, or, at the opposite, - disable them, depending on the argument. + Make the added items of the context menu stored in the document available for execution, + or, at the opposite, disable them, depending on the argument. Args - ``enable``: when ``True`` (default), the new items of the context menu are made visible. - When ``False``, they are suppressed. + ``enable``: when ``True`` (default), the local menu stored in the document is made active. + When False, the global menu defined at LibreOffice level takes the precedence. Returns None """ @@ -7009,6 +7014,19 @@ class SFWidgets: """ ... + def RemoveAllItems(self) -> None: + """ + Remove all items, both + - predefined with ``Tools + Customize`` and saved in the document + - added by ``AddItem()`` + Adding custom items (``AddItem``) remains possible. + This action cannot be reverted except by closing and reopening the document. + + Returns + None + """ + ... + # ######################################################################### # SF_PopupMenu CLASS # ######################################################################### diff --git a/wizards/source/sfwidgets/SF_ContextMenu.xba b/wizards/source/sfwidgets/SF_ContextMenu.xba index 0694569cf9c0..49610cec32b2 100644 --- a/wizards/source/sfwidgets/SF_ContextMenu.xba +++ b/wizards/source/sfwidgets/SF_ContextMenu.xba @@ -14,7 +14,7 @@ Option Explicit ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ''' SF_ContextMenu ''' ============== -''' Complete a predefined context menu with new items. +''' Complete pr replace a predefined context menu with new items. ''' ''' A context menu is obtained by a right-click on several areas of a document. ''' Each area determines its own context menu. @@ -23,8 +23,13 @@ Option Explicit ''' ''' A context menu is usually predefined at LibreOffice installation. ''' Customization is done statically with the Tools + Customize dialog. -''' The actual service provides a mean to make temporary additions at -''' the bottom of a context menu. Those changes are lost when the document is closed. +''' The actual service provides tools to configure a context menu preset in an open document. +''' Context menus configured at LibreOffice installation level are not included. +''' The service provides a mean to +''' - make temporary additions at the bottom of a context menu +''' - replace a context menu. +''' The changes are lost when the document is closed. +''' The context menu may be emptied, which gives the illusion that the right-click is inactive. ''' ''' The name of a context menu is the last component of the resource URL: ''' "private:resource/popupmenu/the-name-here" @@ -36,10 +41,12 @@ Option Explicit ''' ''' A context menu is setup in next sequence: ''' 1. Define each menu item, submenu or line separator with AddItem(...) -''' 2. Activate() the menu to make it visible and active -''' 3. If meaningful, it can be temporarily deactivate with Activate(False) +''' 2. Activate() the local menu to make it visible and active +''' 3. If meaningful, it can be temporarily deactivated with Activate(False) +''' In that case, the menu defined at LibreOffice level takes the lead. ''' 4. Items can be optionally added, and the menu might be made active again -''' 5. Dispose() cleans the memory resources +''' 5, RemoveAllItems(...) optionally removes all standard and all added items +''' 6. Dispose() cleans the memory resources ''' ''' Definitions: ''' SubmenuCharacter: the character or the character string that identifies how menus are cascading @@ -112,6 +119,7 @@ Private ServiceName As String ' Menu descriptors Private Component As Object ' com.sun.star.lang.XComponent +Private DocumentType As String ' "Calc", "Writer", ... Private ResourceURL As String ' private:resource/popupmenu/... Private ConfigManager As Object ' com.sun.star.ui.XUIConfigurationManager Private MenuTree As Variant ' Dictionary nodename - com.sun.star.ui.ItemDescriptor pair @@ -133,6 +141,7 @@ Private Sub Class_Initialize() ObjectType = "ContextMenu" ServiceName = "SFWidgets.ContextMenu" Set Component = Nothing + DocumentType = "" Set ConfigManager = Nothing ResourceURL = "" Set MenuTree = Nothing @@ -154,6 +163,12 @@ End Function ' SFWidgets.SF_ContextMenu Explicit Destructor REM ================================================================== PROPERTIES +REM ----------------------------------------------------------------------------- +Property Get ParentDocument() As Variant +''' The ParentDocument property returns a document class (or one of its subclasses) instance + ParentDocument = _PropertyGet("ParentDocument") +End Property ' SFWidgets.SF_ContextMenu.ParentDocument (get) + REM ----------------------------------------------------------------------------- Property Get ShortcutCharacter() As Variant ''' The ShortcutCharacter property specifies character preceding the underline access key @@ -171,11 +186,11 @@ REM ===================================================================== METHOD REM ----------------------------------------------------------------------------- Public Sub Activate(Optional ByVal Enable As Variant) As Variant -''' Make the added items of the context menu available for execution, +''' Make the added items of the context menu stored in the document available for execution, ''' or, at the opposite, disable them, depending on the argument. ''' Args: -''' Enable: When True (default), the new items of the context menu are made visible. -''' When False, they are suppressed. +''' Enable: When True (default), the local menu stored in the document is made active. +''' When False, the global menu defined at LibreOffice level takes the precedence. ''' Returns: ''' None ''' Examples: @@ -346,8 +361,10 @@ Public Function Methods() As Variant ''' Return the list of public methods of the Model service as an array Methods = Array( _ - "AddItem" _ + "Activate" _ + , "AddItem" _ , "Execute" _ + , "RemoveAllItems" _ ) End Function ' SFWidgets.SF_ContextMenu.Methods @@ -357,12 +374,65 @@ Public Function Properties() As Variant ''' Return the list or properties of the Timer a.AddItem("B>B1")class as an array Properties = Array( _ - "ShortcutCharacter" _ + "ParentDocument" _ + , "ShortcutCharacter" _ , "SubmenuCharacter" _ ) End Function ' SFWidgets.SF_ContextMenu.Properties +REM ----------------------------------------------------------------------------- +Public Sub RemoveAllItems() +''' Remove all items, both +''' - predefined with Tools + Customize and saved in the document +''' - added by contextmenu.AddItem() +''' Adding custom items (AddItem) remains possible. +''' This action cannot be reverted except by closing and reopening the document. +''' Example: Associate next Sub with the on-right-click event of a sheet. +''' => The custom menu appears when right-clicking in column C, otherwise normal behaviour +''' Sub OnRightClick1(Optional XRange) ' Xrange is a com.sun.star.table.XCellRange +''' Dim calc, menu, bColumn +''' Set calc = CreateScriptService("Calc", ThisComponent) +''' Set menu = calc.ContextMenus("cell") +''' menu.RemoveAllItems() +''' bColumn = ( Len(calc.Intersect("Sheet1.$C:$C", XRange.AbsoluteName)) > 0 ) +''' If bColumn Then +''' menu.AddItem("A", Script := "vnd.sun.star.script:Standard.Module1.EnterA?language=Basic&location=document") +''' ... +''' End If +''' menu.Activate(bColumn) +''' End Sub + +Dim i As Long + +Const cstThisSub = "SFWidgets.ContextMenu.RemoveAllItems" +Const cstSubArgs = "" + +Check: + If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch + SF_Utils._EnterFunction(cstThisSub, cstSubArgs) + +Try: + For i = MenuContainer.Count - 1 To 0 Step -1 + MenuContainer.removeByIndex(i) + Next i + + With ConfigManager + If .hasSettings(ResourceURL) Then +' .removeSettings(ResourceURL) + .replaceSettings(ResourceURL, MenuContainer) + Else + .insertSettings(ResourceURL, MenuContainer) + End If + End With + +Finally: + SF_Utils._ExitFunction(cstThisSub) + Exit Sub +Catch: + GoTo Finally +End Sub ' SFWidgets.SF_ContextMenu.RemoveAllItems + REM ----------------------------------------------------------------------------- Public Function SetProperty(Optional ByVal PropertyName As Variant _ , Optional ByRef Value As Variant _ @@ -514,6 +584,7 @@ Private Function _PropertyGet(Optional ByVal psProperty As String) As Variant ''' psProperty: the name of the property Dim vGet As Variant ' Return value +Dim oWindow As Object ' SF_UI.Window object Dim cstThisSub As String Const cstSubArgs = "" @@ -524,6 +595,11 @@ Const cstSubArgs = "" _PropertyGet = Null Select Case UCase(psProperty) + Case UCase("ParentDocument") + If Not IsNull(Component) Then + Set oWindow = ScriptForge.SF_UI._IdentifyWindow(Component) + If Not IsNull(oWindow) Then Set _PropertyGet = CreateScriptService(oWindow.DocumentType, Component) Else Set _PropertyGet = Nothing + End If Case UCase("ShortcutCharacter") _PropertyGet = _UnderlineAccessKeyChar Case UCase("SubmenuCharacter") diff --git a/wizards/source/sfwidgets/SF_Register.xba b/wizards/source/sfwidgets/SF_Register.xba index 468d2f76b415..99c9dc9d0d8e 100644 --- a/wizards/source/sfwidgets/SF_Register.xba +++ b/wizards/source/sfwidgets/SF_Register.xba @@ -74,7 +74,7 @@ REM ---------------------------------------------------------------------------- Public Function _NewContextMenu(Optional ByVal pvArgs As Variant) As Object ''' Create a new instance of the SF_ContextMenu class ''' Args: -''' Component: the document's component requesting a context menu +''' Component: the document's Component requesting a context menu ''' ContextMenuName: a private:resource/popupmenu/... reference ''' SubmenuChar: Delimiter used in menu trees ''' Returns: the instance or Nothing diff --git a/wizards/source/sfwidgets/script.xlb b/wizards/source/sfwidgets/script.xlb index 8fb6343d86d4..e23174375536 100644 --- a/wizards/source/sfwidgets/script.xlb +++ b/wizards/source/sfwidgets/script.xlb @@ -1,12 +1,12 @@ <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE library:library PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "library.dtd"> <library:library xmlns:library="http://openoffice.org/2000/library" library:name="SFWidgets" library:readonly="false" library:passwordprotected="false"> - <library:element library:name="__License"/> - <library:element library:name="SF_Register"/> - <library:element library:name="SF_PopupMenu"/> - <library:element library:name="SF_Menu"/> - <library:element library:name="SF_MenuListener"/> - <library:element library:name="SF_Toolbar"/> <library:element library:name="SF_ToolbarButton"/> + <library:element library:name="SF_Toolbar"/> + <library:element library:name="SF_MenuListener"/> + <library:element library:name="SF_Menu"/> <library:element library:name="SF_ContextMenu"/> + <library:element library:name="SF_PopupMenu"/> + <library:element library:name="SF_Register"/> + <library:element library:name="__License"/> </library:library> \ No newline at end of file