docthemes: Save themes def. to a file when added to ColorSets
[LibreOffice.git] / wizards / source / sfwidgets / SF_PopupMenu.xba
blob467e3f74877618c3e7d3c27a6d722e4cf61f583c
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
3 <script:module xmlns:script="http://openoffice.org/2000/script" script:name="SF_PopupMenu" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
4 REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
5 REM === The SFWidgets library is one of the associated libraries. ===
6 REM === Full documentation is available on https://help.libreoffice.org/ ===
7 REM =======================================================================================================================
9 Option Compatible
10 Option ClassModule
12 Option Explicit
14 &apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
15 &apos;&apos;&apos; SF_PopupMenu
16 &apos;&apos;&apos; ============
17 &apos;&apos;&apos; Display a popup menu anywhere and any time
18 &apos;&apos;&apos;
19 &apos;&apos;&apos; A popup menu is usually triggered by a mouse action (typically a right-click) on a dialog, a form
20 &apos;&apos;&apos; or one of their controls. In this case the menu will be displayed below the clicked area.
21 &apos;&apos;&apos; When triggered by other events, including in the normal flow of a user script, the script should
22 &apos;&apos;&apos; provide the coordinates of the topleft edge of the menu versus the actual component.
23 &apos;&apos;&apos;
24 &apos;&apos;&apos; The menu is described from top to bottom. Each menu item receives a numeric and a string identifier.
25 &apos;&apos;&apos; The Execute() method returns the item selected by the user.
26 &apos;&apos;&apos;
27 &apos;&apos;&apos; Menu items are either:
28 &apos;&apos;&apos; - usual items
29 &apos;&apos;&apos; - checkboxes
30 &apos;&apos;&apos; - radio buttons
31 &apos;&apos;&apos; - a menu separator
32 &apos;&apos;&apos; Menu items can be decorated with icons and tooltips.
33 &apos;&apos;&apos;
34 &apos;&apos;&apos; Definitions:
35 &apos;&apos;&apos; SubmenuCharacter: the character or the character string that identifies how menus are cascading
36 &apos;&apos;&apos; Default = &quot;&gt;&quot;
37 &apos;&apos;&apos; Can be set when invoking the PopupMenu service
38 &apos;&apos;&apos; ShortcutCharacter: the underline access key character
39 &apos;&apos;&apos; Default = &quot;~&quot;
40 &apos;&apos;&apos;
41 &apos;&apos;&apos; Service invocation:
42 &apos;&apos;&apos; Sub OpenMenu(Optional poMouseEvent As Object)
43 &apos;&apos;&apos; Dim myMenu As Object
44 &apos;&apos;&apos; Set myMenu = CreateScriptService(&quot;SFWidgets.PopupMenu&quot;, poMouseEvent, , , &quot;&gt;&gt;&quot;) &apos; Usual case
45 &apos;&apos;&apos; &apos; or
46 &apos;&apos;&apos; Set myMenu = CreateScriptService(&quot;SFWidgets.PopupMenu&quot;, , X, Y, &quot; | &quot;) &apos; Use X and Y coordinates to place the menu
47 &apos;&apos;&apos;
48 &apos;&apos;&apos; Menus and submenus
49 &apos;&apos;&apos; To create a popup menu with submenus, use the character defined in the
50 &apos;&apos;&apos; SubmenuCharacter property while creating the menu entry to define where it will be
51 &apos;&apos;&apos; placed. For instance, consider the following menu/submenu hierarchy.
52 &apos;&apos;&apos; Item A
53 &apos;&apos;&apos; Item B &gt; Item B.1
54 &apos;&apos;&apos; Item B.2
55 &apos;&apos;&apos; ------ (line separator)
56 &apos;&apos;&apos; Item C &gt; Item C.1 &gt; Item C.1.1
57 &apos;&apos;&apos; Item C.1.2
58 &apos;&apos;&apos; Item C &gt; Item C.2 &gt; Item C.2.1
59 &apos;&apos;&apos; Item C.2.2
60 &apos;&apos;&apos; Next code will create the menu/submenu hierarchy
61 &apos;&apos;&apos; With myMenu
62 &apos;&apos;&apos; .AddItem(&quot;Item A&quot;)
63 &apos;&apos;&apos; .AddItem(&quot;Item B&gt;Item B.1&quot;)
64 &apos;&apos;&apos; .AddItem(&quot;Item B&gt;Item B.2&quot;)
65 &apos;&apos;&apos; .AddItem(&quot;---&quot;)
66 &apos;&apos;&apos; .AddItem(&quot;Item C&gt;Item C.1&gt;Item C.1.1&quot;)
67 &apos;&apos;&apos; .AddItem(&quot;Item C&gt;Item C.1&gt;Item C.1.2&quot;)
68 &apos;&apos;&apos; .AddItem(&quot;Item C&gt;Item C.2&gt;Item C.2.1&quot;)
69 &apos;&apos;&apos; .AddItem(&quot;Item C&gt;Item C.2&gt;Item C.2.2&quot;)
70 &apos;&apos;&apos; End With
71 &apos;&apos;&apos;
72 &apos;&apos;&apos; Example 1: simulate a subset of the View menu in the menubar of the Basic IDE
73 &apos;&apos;&apos; Sub OpenMenu(Optional poMouseEvent As Object)
74 &apos;&apos;&apos; Dim myMenu As Object, vChoice As Variant
75 &apos;&apos;&apos; Set myMenu = CreateScriptService(&quot;SFWidgets.PopupMenu&quot;, poMouseEvent)
76 &apos;&apos;&apos; With myMenu
77 &apos;&apos;&apos; .AddCheckBox(&quot;View&gt;Toolbars&gt;Dialog&quot;)
78 &apos;&apos;&apos; .AddCheckBox(&quot;View&gt;Toolbars&gt;Find&quot;, Status := True)
79 &apos;&apos;&apos; .AddCheckBox(&quot;View&gt;Status Bar&quot;, Status := True)
80 &apos;&apos;&apos; .AddItem(&quot;View&gt;Full Screen&quot;, Name := &quot;FULLSCREEN&quot;)
81 &apos;&apos;&apos; vChoice = .Execute(False) &apos; When 1st checkbox is clicked, return &quot;Dialog&quot;
82 &apos;&apos;&apos; &apos; When last item is clicked, return &quot;FULLSCREEN&quot;
83 &apos;&apos;&apos; .Dispose()
84 &apos;&apos;&apos; End With
85 &apos;&apos;&apos;
86 &apos;&apos;&apos; Example 2: jump to another sheet of a Calc document
87 &apos;&apos;&apos; &apos; Link next Sub to the &quot;Mouse button released&quot; event of a form control of a Calc sheet
88 &apos;&apos;&apos; Sub JumpToSheet(Optional poEvent As Object)
89 &apos;&apos;&apos; Dim myMenu As Object, sChoice As String, myDoc As Object, vSheets As Variant, sSheet As String
90 &apos;&apos;&apos; Set myMenu = CreateScriptService(&quot;SFWidgets.PopupMenu&quot;, poEvent)
91 &apos;&apos;&apos; Set myDoc = CreateScriptService(&quot;Calc&quot;, ThisComponent)
92 &apos;&apos;&apos; vSheets = myDoc.Sheets
93 &apos;&apos;&apos; For Each sSheet In vSheets
94 &apos;&apos;&apos; myMenu.AddItem(sSheet)
95 &apos;&apos;&apos; Next sSheet
96 &apos;&apos;&apos; sChoice = myMenu.Execute(False) &apos; Return sheet name, not sheet index
97 &apos;&apos;&apos; If sChoice &lt;&gt; &quot;&quot; Then myDoc.Activate(sChoice)
98 &apos;&apos;&apos; myDoc.Dispose()
99 &apos;&apos;&apos; myMenu.Dispose()
100 &apos;&apos;&apos; End Sub
101 &apos;&apos;&apos;
102 &apos;&apos;&apos;
103 &apos;&apos;&apos; Detailed user documentation:
104 &apos;&apos;&apos; https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03/sf_popupmenu.html?DbPAR=BASIC
105 &apos;&apos;&apos;
106 &apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
108 REM ================================================================== EXCEPTIONS
110 REM ============================================================= PRIVATE MEMBERS
112 Private [Me] As Object
113 Private ObjectType As String &apos; Must be POPUPMENU
114 Private ServiceName As String
117 &apos; Menu descriptors
118 Private MenuTree As Variant &apos; Dictionary treename - XPopupMenu pair
119 Private MenuIdentification As Variant &apos; Dictionary item ID - item name
120 Private SubmenuChar As String &apos; Delimiter in menu trees
121 Private MenuRoot As Object &apos; stardiv.vcl.PopupMenu or com.sun.star.awt.XPopupMenu
122 Private LastItem As Integer &apos; Every item has its entry number. This is the last one
123 Private Rectangle As Object &apos; com.sun.star.awt.Rectangle
124 Private PeerWindow As Object &apos; com.sun.star.awt.XWindowPeer
125 Private MenubarMenu As Boolean &apos; When True, the actual popup menu depends on a menubar item
127 REM ============================================================ MODULE CONSTANTS
129 Private Const _UnderlineAccessKeyChar = &quot;~&quot;
130 Private Const _DefaultSubmenuChar = &quot;&gt;&quot;
131 Private Const _SeparatorChar = &quot;---&quot;
132 Private Const _IconsDirectory = &quot;private:graphicrepository/&quot; &apos; Refers to &lt;install folder&gt;/share/config/images_*.zip.
133 Private Const cstUnoPrefix = &quot;.uno:&quot;
134 Private Const cstNormal = &quot;N&quot;
135 Private Const cstCheck = &quot;C&quot;
136 Private Const cstRadio = &quot;R&quot;
138 REM ====================================================== CONSTRUCTOR/DESTRUCTOR
140 REM -----------------------------------------------------------------------------
141 Private Sub Class_Initialize()
142 Set [Me] = Nothing
143 ObjectType = &quot;POPUPMENU&quot;
144 ServiceName = &quot;SFWidgets.PopupMenu&quot;
145 Set MenuTree = Nothing
146 Set MenuIdentification = Nothing
147 SubmenuChar = _DefaultSubmenuChar
148 Set MenuRoot = Nothing
149 LastItem = 0
150 Set Rectangle = Nothing
151 Set PeerWindow = Nothing
152 MenubarMenu = False
153 End Sub &apos; SFWidgets.SF_PopupMenu Constructor
155 REM -----------------------------------------------------------------------------
156 Private Sub Class_Terminate()
157 Call Class_Initialize()
158 End Sub &apos; SFWidgets.SF_PopupMenu Destructor
160 REM -----------------------------------------------------------------------------
161 Public Function Dispose() As Variant
162 If Not IsNull(MenuTree) Then Set MenuTree = MenuTree.Dispose()
163 If Not IsNull(MenuIdentification) Then Set MenuIdentification = MenuIdentification.Dispose()
164 Call Class_Terminate()
165 Set Dispose = Nothing
166 End Function &apos; SFWidgets.SF_PopupMenu Explicit Destructor
168 REM ================================================================== PROPERTIES
170 REM -----------------------------------------------------------------------------
171 Property Get ShortcutCharacter() As Variant
172 &apos;&apos;&apos; The ShortcutCharacter property specifies character preceding the underline access key
173 ShortcutCharacter = _PropertyGet(&quot;ShortcutCharacter&quot;)
174 End Property &apos; SFWidgets.SF_PopupMenu.ShortcutCharacter (get)
176 REM -----------------------------------------------------------------------------
177 Property Get SubmenuCharacter() As Variant
178 &apos;&apos;&apos; The SubmenuCharacter property specifies the character string indicating
179 &apos;&apos;&apos; a sub-menu in a popup menu item
180 SubmenuCharacter = _PropertyGet(&quot;SubmenuCharacter&quot;)
181 End Property &apos; SFWidgets.SF_PopupMenu.SubmenuCharacter (get)
183 REM ===================================================================== METHODS
185 REM -----------------------------------------------------------------------------
186 Public Function AddCheckBox(Optional ByVal MenuItem As Variant _
187 , Optional ByVal Name As Variant _
188 , Optional ByVal Status As Variant _
189 , Optional ByVal Icon As Variant _
190 , Optional ByVal Tooltip As Variant _
191 ) As Integer
192 &apos;&apos;&apos; Insert in the popup menu a new entry
193 &apos;&apos;&apos; Args:
194 &apos;&apos;&apos; MenuItem: The text to be displayed in the menu entry.
195 &apos;&apos;&apos; It determines also the hierarchy of the popup menu
196 &apos;&apos;&apos; It is made up of all the components (separated by the &quot;SubmenuCharacter&quot;) of the menu branch
197 &apos;&apos;&apos; Example: A&gt;B&gt;C means &quot;C&quot; is a new entry in submenu &quot;A =&gt; B =&gt;&quot;
198 &apos;&apos;&apos; If the last component is equal to the &quot;SeparatorCharacter&quot;, a line separator is inserted
199 &apos;&apos;&apos; Name: The name to be returned by the Execute() method if this item is clicked
200 &apos;&apos;&apos; Default = the last component of MenuItem
201 &apos;&apos;&apos; Status: when True the item is selected. Default = False
202 &apos;&apos;&apos; Icon: The path name of the icon to be displayed, without leading path separator
203 &apos;&apos;&apos; The icons are stored in one of the &lt;install folder&gt;/share/config/images_*.zip files
204 &apos;&apos;&apos; The exact file depends on the user options about the current icon set
205 &apos;&apos;&apos; Use the (normal) slash &quot;/&quot; as path separator
206 &apos;&apos;&apos; Example: &quot;cmd/sc_cut.png&quot;
207 &apos;&apos;&apos; Tooltip: The help text to be displayed as a tooltip
208 &apos;&apos;&apos; Returns:
209 &apos;&apos;&apos; The numeric identification of the newly inserted item
210 &apos;&apos;&apos; Examples:
211 &apos;&apos;&apos; Dim myMenu As Object, iId As Integer
212 &apos;&apos;&apos; Set myMenu = CreateScriptService(&quot;SFWidgets.PopupMenu&quot;, poEvent)
213 &apos;&apos;&apos; iId = myMenu.AddCheckBox(&quot;Menu top&gt;Checkbox item&quot;, Status := True)
215 Dim iId As Integer &apos; Return value
217 Const cstThisSub = &quot;SFWidgets.PopupMenu.AddCheckBox&quot;
218 Const cstSubArgs = &quot;MenuItem, [Name=&quot;&quot;&quot;&quot;], [Status=False], [Icon=&quot;&quot;&quot;&quot;], [Tooltip=&quot;&quot;&quot;&quot;]&quot;
220 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
221 iId = 0
223 Check:
224 If IsMissing(Name) Or IsEmpty(Name) Then Name = &quot;&quot;
225 If IsMissing(Status) Or IsEmpty(Status) Then Status = False
226 If IsMissing(Icon) Or IsEmpty(Icon) Then Icon = &quot;&quot;
227 If IsMissing(Tooltip) Or IsEmpty(Tooltip) Then Tooltip = &quot;&quot;
228 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
229 If Not ScriptForge.SF_Utils._Validate(MenuItem, &quot;MenuItem&quot;, V_STRING) Then GoTo Catch
230 If Not ScriptForge.SF_Utils._Validate(Name, &quot;Name&quot;, V_STRING) Then GoTo Catch
231 If Not ScriptForge.SF_Utils._Validate(Status, &quot;Status&quot;, ScriptForge.V_BOOLEAN) Then GoTo Catch
232 If Not ScriptForge.SF_Utils._Validate(Icon, &quot;Icon&quot;, V_STRING) Then GoTo Catch
233 If Not ScriptForge.SF_Utils._Validate(Tooltip, &quot;Tooltip&quot;, V_STRING) Then GoTo Catch
234 End If
236 Try:
237 iId = _AddItem(MenuItem, Name, cstCheck, Status, Icon, Tooltip)
239 Finally:
240 AddCheckBox = iId
241 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
242 Exit Function
243 Catch:
244 GoTo Finally
245 End Function &apos; SFWidgets.SF_PopupMenu.AddCheckBox
247 REM -----------------------------------------------------------------------------
248 Public Function AddItem(Optional ByVal MenuItem As Variant _
249 , Optional ByVal Name As Variant _
250 , Optional ByVal Icon As Variant _
251 , Optional ByVal Tooltip As Variant _
252 ) As Integer
253 &apos;&apos;&apos; Insert in the popup menu a new entry
254 &apos;&apos;&apos; Args:
255 &apos;&apos;&apos; MenuItem: The text to be displayed in the menu entry.
256 &apos;&apos;&apos; It determines also the hierarchy of the popup menu
257 &apos;&apos;&apos; It is made up of all the components (separated by the &quot;SubmenuCharacter&quot;) of the menu branch
258 &apos;&apos;&apos; Example: A&gt;B&gt;C means &quot;C&quot; is a new entry in submenu &quot;A =&gt; B =&gt;&quot;
259 &apos;&apos;&apos; If the last component is equal to &quot;---&quot;, a line separator is inserted and all other arguments are ignored
260 &apos;&apos;&apos; Name: The name to be returned by the Execute() method if this item is clicked
261 &apos;&apos;&apos; Default = the last component of MenuItem
262 &apos;&apos;&apos; Icon: The path name of the icon to be displayed, without leading path separator
263 &apos;&apos;&apos; The icons are stored in one of the &lt;install folder&gt;/share/config/images_*.zip files
264 &apos;&apos;&apos; The exact file depends on the user options about the current icon set
265 &apos;&apos;&apos; Use the (normal) slash &quot;/&quot; as path separator
266 &apos;&apos;&apos; Example: &quot;cmd/sc_cut.png&quot;
267 &apos;&apos;&apos; Tooltip: The help text to be displayed as a tooltip
268 &apos;&apos;&apos; Returns:
269 &apos;&apos;&apos; The numeric identification of the newly inserted item
270 &apos;&apos;&apos; Examples:
271 &apos;&apos;&apos; Dim myMenu As Object, iId As Integer
272 &apos;&apos;&apos; Set myMenu = CreateScriptService(&quot;SFWidgets.PopupMenu&quot;, poEvent)
273 &apos;&apos;&apos; iId = myMenu.AddItem(&quot;Menu top&gt;Normal item&quot;, Icon := &quot;cmd.sc_cut.png&quot;)
275 Dim iId As Integer &apos; Return value
277 Const cstThisSub = &quot;SFWidgets.PopupMenu.AddItem&quot;
278 Const cstSubArgs = &quot;MenuItem, [Name=&quot;&quot;&quot;&quot;], [Icon=&quot;&quot;&quot;&quot;], [Tooltip=&quot;&quot;&quot;&quot;]&quot;
280 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
281 iId = 0
283 Check:
284 If IsMissing(Name) Or IsEmpty(Name) Then Name = &quot;&quot;
285 If IsMissing(Icon) Or IsEmpty(Icon) Then Icon = &quot;&quot;
286 If IsMissing(Tooltip) Or IsEmpty(Tooltip) Then Tooltip = &quot;&quot;
287 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
288 If Not ScriptForge.SF_Utils._Validate(MenuItem, &quot;MenuItem&quot;, V_STRING) Then GoTo Catch
289 If Not ScriptForge.SF_Utils._Validate(Name, &quot;Name&quot;, V_STRING) Then GoTo Catch
290 If Not ScriptForge.SF_Utils._Validate(Icon, &quot;Icon&quot;, V_STRING) Then GoTo Catch
291 If Not ScriptForge.SF_Utils._Validate(Tooltip, &quot;Tooltip&quot;, V_STRING) Then GoTo Catch
292 End If
294 Try:
295 iId = _AddItem(MenuItem, Name, cstNormal, False, Icon, Tooltip)
297 Finally:
298 AddItem = iId
299 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
300 Exit Function
301 Catch:
302 GoTo Finally
303 End Function &apos; SFWidgets.SF_PopupMenu.AddItem
305 REM -----------------------------------------------------------------------------
306 Public Function AddRadioButton(Optional ByVal MenuItem As Variant _
307 , Optional ByVal Name As Variant _
308 , Optional ByVal Status As Variant _
309 , Optional ByVal Icon As Variant _
310 , Optional ByVal Tooltip As Variant _
311 ) As Integer
312 &apos;&apos;&apos; Insert in the popup menu a new entry as a radio button
313 &apos;&apos;&apos; Args:
314 &apos;&apos;&apos; MenuItem: The text to be displayed in the menu entry.
315 &apos;&apos;&apos; It determines also the hieAddCheckBoxrarchy of the popup menu
316 &apos;&apos;&apos; It is made up of all the components (separated by the &quot;SubmenuCharacter&quot;) of the menu branch
317 &apos;&apos;&apos; Example: A&gt;B&gt;C means &quot;C&quot; is a new entry in submenu &quot;A =&gt; B =&gt;&quot;
318 &apos;&apos;&apos; If the last component is equal to the &quot;SeparatorCharacter&quot;, a line separator is inserted
319 &apos;&apos;&apos; Name: The name to be returned by the Execute() method if this item is clicked
320 &apos;&apos;&apos; Default = the last component of MenuItem
321 &apos;&apos;&apos; Status: when True the item is selected. Default = False
322 &apos;&apos;&apos; Icon: The path name of the icon to be displayed, without leading path separator
323 &apos;&apos;&apos; The icons are stored in one of the &lt;install folder&gt;/share/config/images_*.zip files
324 &apos;&apos;&apos; The exact file depends on the user options about the current icon set
325 &apos;&apos;&apos; Use the (normal) slash &quot;/&quot; as path separator
326 &apos;&apos;&apos; Example: &quot;cmd/sc_cut.png&quot;
327 &apos;&apos;&apos; Tooltip: The help text to be displayed as a tooltip
328 &apos;&apos;&apos; Returns:
329 &apos;&apos;&apos; The numeric identification of the newly inserted item
330 &apos;&apos;&apos; Examples:
331 &apos;&apos;&apos; Dim myMenu As Object, iId As Integer
332 &apos;&apos;&apos; Set myMenu = CreateScriptService(&quot;SFWidgets.PopupMenu&quot;, poEvent)
333 &apos;&apos;&apos; iId = myMenu.AddRadioButton(&quot;Menu top&gt;Radio item&quot;, Status := True)
335 Dim iId As Integer &apos; Return value
337 Const cstThisSub = &quot;SFWidgets.PopupMenu.AddRadioButton&quot;
338 Const cstSubArgs = &quot;MenuItem, [Name=&quot;&quot;&quot;&quot;], [Status=False], [Icon=&quot;&quot;&quot;&quot;], [Tooltip=&quot;&quot;&quot;&quot;]&quot;
340 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
341 iId = 0
343 Check:
344 If IsMissing(Name) Or IsEmpty(Name) Then Name = &quot;&quot;
345 If IsMissing(Status) Or IsEmpty(Status) Then Status = False
346 If IsMissing(Icon) Or IsEmpty(Icon) Then Icon = &quot;&quot;
347 If IsMissing(Tooltip) Or IsEmpty(Tooltip) Then Tooltip = &quot;&quot;
348 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
349 If Not ScriptForge.SF_Utils._Validate(MenuItem, &quot;MenuItem&quot;, V_STRING) Then GoTo Catch
350 If Not ScriptForge.SF_Utils._Validate(Name, &quot;Name&quot;, V_STRING) Then GoTo Catch
351 If Not ScriptForge.SF_Utils._Validate(Status, &quot;Status&quot;, ScriptForge.V_BOOLEAN) Then GoTo Catch
352 If Not ScriptForge.SF_Utils._Validate(Icon, &quot;Icon&quot;, V_STRING) Then GoTo Catch
353 If Not ScriptForge.SF_Utils._Validate(Tooltip, &quot;Tooltip&quot;, V_STRING) Then GoTo Catch
354 End If
356 Try:
357 iId = _AddItem(MenuItem, Name, cstRadio, Status, Icon, Tooltip)
359 Finally:
360 AddRadioButton = iId
361 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
362 Exit Function
363 Catch:
364 GoTo Finally
365 End Function &apos; SFWidgets.SF_PopupMenu.AddRadioButton
367 REM -----------------------------------------------------------------------------
368 Public Function Execute(Optional ByVal ReturnId As Variant) As Variant
369 &apos;&apos;&apos; Display the popup menu and return the menu item clicked by the user
370 &apos;&apos;&apos; Args:
371 &apos;&apos;&apos; ReturnId: When True (default), return the unique ID of the clicked item, otherwise return its name
372 &apos;&apos;&apos; Returns:
373 &apos;&apos;&apos; The numeric identification of clicked item or its name
374 &apos;&apos;&apos; The returned value is 0 or &quot;&quot; (depending on ReturnId) when the menu is cancelled
375 &apos;&apos;&apos; Examples:
376 &apos;&apos;&apos; Sub OpenMenu(Optional poMouseEvent As Object)
377 &apos;&apos;&apos; Dim myMenu As Object, vChoice As Variant
378 &apos;&apos;&apos; Set myMenu = CreateScriptService(&quot;SFWidgets.PopupMenu&quot;, poMouseEvent)
379 &apos;&apos;&apos; With myMenu
380 &apos;&apos;&apos; .AddCheckBox(&quot;View&gt;Toolbars&gt;Dialog&quot;)
381 &apos;&apos;&apos; .AddCheckBox(&quot;View&gt;Toolbars&gt;Find&quot;, Status := True)
382 &apos;&apos;&apos; .AddCheckBox(&quot;View&gt;Status Bar&quot;, Status := True)
383 &apos;&apos;&apos; .AddItem(&quot;View&gt;Full Screen&quot;, Name := &quot;FULLSCREEN&quot;)
384 &apos;&apos;&apos; vChoice = .Execute(False) &apos; When 1st checkbox is clicked, return &quot;Dialog&quot;
385 &apos;&apos;&apos; &apos; When last item is clicked, return &quot;FULLSCREEN&quot;
386 &apos;&apos;&apos; End With
388 Dim vMenuItem As Variant &apos; Return value
390 Const cstThisSub = &quot;SFWidgets.PopupMenu.Execute&quot;
391 Const cstSubArgs = &quot;[ReturnId=True]&quot;
393 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
394 vMenuItem = 0
396 Check:
397 If IsMissing(ReturnId) Or IsEmpty(ReturnId) Then ReturnId = True
398 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
399 If Not ScriptForge.SF_Utils._Validate(ReturnId, &quot;ReturnId&quot;, ScriptForge.V_BOOLEAN) Then GoTo Catch
400 End If
401 If Not ReturnId Then vMenuItem = &quot;&quot;
403 Try:
404 vMenuItem = MenuRoot.Execute(PeerWindow, Rectangle, com.sun.star.awt.PopupMenuDirection.EXECUTE_DEFAULT)
405 If Not ReturnId Then vMenuItem = MenuIdentification.Item(CStr(vMenuItem))
407 Finally:
408 Execute = vMenuItem
409 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
410 Exit Function
411 Catch:
412 GoTo Finally
413 End Function &apos; SFWidgets.SF_PopupMenu.Execute
415 REM -----------------------------------------------------------------------------
416 Public Function GetProperty(Optional ByVal PropertyName As Variant) As Variant
417 &apos;&apos;&apos; Return the actual value of the given property
418 &apos;&apos;&apos; Args:
419 &apos;&apos;&apos; PropertyName: the name of the property as a string
420 &apos;&apos;&apos; Returns:
421 &apos;&apos;&apos; The actual value of the property
422 &apos;&apos;&apos; If the property does not exist, returns Null
423 &apos;&apos;&apos; Exceptions:
424 &apos;&apos;&apos; see the exceptions of the individual properties
425 &apos;&apos;&apos; Examples:
426 &apos;&apos;&apos; myModel.GetProperty(&quot;MyProperty&quot;)
428 Const cstThisSub = &quot;SFWidgets.PopupMenu.GetProperty&quot;
429 Const cstSubArgs = &quot;&quot;
431 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
432 GetProperty = Null
434 Check:
435 If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
436 If Not ScriptForge.SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
437 End If
439 Try:
440 GetProperty = _PropertyGet(PropertyName)
442 Finally:
443 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
444 Exit Function
445 Catch:
446 GoTo Finally
447 End Function &apos; SFWidgets.SF_PopupMenu.GetProperty
449 REM -----------------------------------------------------------------------------
450 Public Function Methods() As Variant
451 &apos;&apos;&apos; Return the list of public methods of the Model service as an array
453 Methods = Array( _
454 &quot;AddCheckBox&quot; _
455 , &quot;AddItem&quot; _
456 , &quot;AddRadioButton&quot; _
457 , &quot;Execute&quot; _
460 End Function &apos; SFWidgets.SF_PopupMenu.Methods
462 REM -----------------------------------------------------------------------------
463 Public Function Properties() As Variant
464 &apos;&apos;&apos; Return the list or properties of the Timer a.AddItem(&quot;B&gt;B1&quot;)class as an array
466 Properties = Array( _
467 &quot;ShortcutCharacter&quot; _
468 , &quot;SubmenuCharacter&quot; _
471 End Function &apos; SFWidgets.SF_PopupMenu.Properties
473 REM -----------------------------------------------------------------------------
474 Public Function SetProperty(Optional ByVal PropertyName As Variant _
475 , Optional ByRef Value As Variant _
476 ) As Boolean
477 &apos;&apos;&apos; Set a new value to the given property
478 &apos;&apos;&apos; Args:
479 &apos;&apos;&apos; PropertyName: the name of the property as a string
480 &apos;&apos;&apos; Value: its new value
481 &apos;&apos;&apos; Exceptions
482 &apos;&apos;&apos; ARGUMENTERROR The property does not exist
484 Const cstThisSub = &quot;SFWidgets.PopupMenu.SetProperty&quot;
485 Const cstSubArgs = &quot;PropertyName, Value&quot;
487 If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
488 SetProperty = False
490 Check:
491 If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
492 If Not SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
493 End If
495 Try:
496 SetProperty = _PropertySet(PropertyName, Value)
498 Finally:
499 SF_Utils._ExitFunction(cstThisSub)
500 Exit Function
501 Catch:
502 GoTo Finally
503 End Function &apos; SFWidgets.SF_PopupMenu.SetProperty
505 REM =========================================================== PRIVATE FUNCTIONS
507 REM -----------------------------------------------------------------------------
508 Public Function _AddItem(ByVal MenuItem As String _
509 , ByVal Name As String _
510 , ByVal ItemType As String _
511 , ByVal Status As Boolean _
512 , ByVal Icon As String _
513 , ByVal Tooltip As String _
514 , Optional ByVal Command As String _
515 ) As Integer
516 &apos;&apos;&apos; Insert in the popup menu a new entry
517 &apos;&apos;&apos; Args:
518 &apos;&apos;&apos; MenuItem: The text to be displayed in the menu entry.
519 &apos;&apos;&apos; It determines also the hierarchy of the popup menu
520 &apos;&apos;&apos; It is made up of all the components (separated by the &quot;SubmenuCharacter&quot;) of the menu branch
521 &apos;&apos;&apos; Example: A&gt;B&gt;C means &quot;C&quot; is a new entry in submenu &quot;A =&gt; B =&gt;&quot;
522 &apos;&apos;&apos; If the last component is equal to the &quot;SeparatorCharacter&quot;, a line separator is inserted
523 &apos;&apos;&apos; Name: The name to be returned by the Execute() method if this item is clicked
524 &apos;&apos;&apos; Default = the last component of MenuItem
525 &apos;&apos;&apos; ItemType: &quot;N&quot;(ormal, &quot;C&quot;(heck) or &quot;R&quot;(adio)
526 &apos;&apos;&apos; Status: when True the item is selected
527 &apos;&apos;&apos; Icon: The path name of the icon to be displayed, without leading path separator
528 &apos;&apos;&apos; The icons are stored in one of the &lt;install folder&gt;/share/config/images_*.zip files
529 &apos;&apos;&apos; The exact file depends on the user options about the current icon set
530 &apos;&apos;&apos; Use the (normal) slash &quot;/&quot; as path separator
531 &apos;&apos;&apos; Example: &quot;cmd/sc_cut.png&quot;
532 &apos;&apos;&apos; Tooltip: The help text to be displayed as a tooltip
533 &apos;&apos;&apos; Command: only for menubar menus
534 &apos;&apos;&apos; Either a UNO command like &quot;.uno:About&quot;
535 &apos;&apos;&apos; or a script to be run: script URI ::: string argument to be passed to the script
536 &apos;&apos;&apos; Returns:
537 &apos;&apos;&apos; The numeric identification of the newly inserted item
539 Dim iId As Integer &apos; Return value
540 Dim vSplit As Variant &apos; Split menu item
541 Dim sMenu As String &apos; Submenu where to attach the new item, as a string
542 Dim oMenu As Object &apos; Submenu where to attach the new item, as an object
543 Dim sName As String &apos; The text displayed in the menu box
544 Dim oImage As Object &apos; com.sun.star.graphic.XGraphic
545 Dim sCommand As String &apos; Alias of Command completed with arguments
546 Const cstCommandSep = &quot;,&quot;
548 On Local Error GoTo Catch
549 iId = 0
550 If IsMissing(Command) Then Command = &quot;&quot;
552 Try:
553 &apos; Run through the upper menu tree
554 vSplit = _SplitMenuItem(MenuItem)
556 &apos; Create and determine the menu to which to attach the new item
557 sMenu = vSplit(0)
558 Set oMenu = _GetPopupMenu(sMenu) &apos; Run through the upper menu tree and retain the last branch
560 &apos; Insert the new item
561 LastItem = LastItem + 1
562 sName = vSplit(1)
564 With oMenu
565 If sName = _SeparatorChar Then
566 .insertSeparator(-1)
567 Else
568 Select Case ItemType
569 Case cstNormal
570 .insertItem(LastItem, sName, 0, -1)
571 Case cstCheck
572 .insertItem(LastItem, sName, com.sun.star.awt.MenuItemStyle.CHECKABLE + com.sun.star.awt.MenuItemStyle.AUTOCHECK, -1)
573 .checkItem(LastItem, Status)
574 Case cstRadio
575 .insertItem(LastItem, sName, com.sun.star.awt.MenuItemStyle.RADIOCHECK + com.sun.star.awt.MenuItemStyle.AUTOCHECK, -1)
576 .checkItem(LastItem, Status)
577 End Select
579 &apos; Store the ID - Name relation
580 If Len(Name) = 0 Then Name = Replace(sName, _UnderlineAccessKeyChar, &quot;&quot;)
581 MenuIdentification.Add(CStr(LastItem), Name)
583 &apos; Add the icon when relevant
584 If Len(Icon) &gt; 0 Then
585 Set oImage = _GetImageFromUrl(_IconsDirectory &amp; Icon)
586 If Not IsNull(oImage) Then .setItemImage(LastItem, oImage, False)
587 End If
589 &apos; Add the tooltip when relevant
590 If Len(Tooltip) &gt; 0 Then .setTipHelpText(LastItem, Tooltip)
592 &apos; Add the command: UNO command or script to run - menubar menus only
593 If Len(Command) &gt; 0 Then
594 If Left(Command, Len(cstUnoPrefix)) = cstUnoPrefix Then
595 sCommand = Command
596 Else
597 sCommand = Command &amp; cstCommandSep &amp; Name &amp; cstCommandSep &amp; CStr(LastItem)
598 End If
599 .setCommand(LastItem, sCommand)
600 End If
601 End If
602 End With
604 iId = LastItem
606 Finally:
607 _AddItem = iId
608 Exit Function
609 Catch:
610 GoTo Finally
611 End Function &apos; SFWidgets.SF_PopupMenu._AddItem
613 REM -----------------------------------------------------------------------------
614 Private Function _GetImageFromURL(ByVal psUrl as String) As Object
615 &apos;&apos;&apos; Returns a com.sun.star.graphic.XGraphic instance based on the given URL
616 &apos;&apos;&apos; The returned object is intended to be inserted as an icon in the popup menu
617 &apos;&apos;&apos; Derived from &quot;Useful Macro Information For OpenOffice&quot; By Andrew Pitonyak
619 Dim vMediaProperties As Variant &apos; Array of com.sun.star.beans.PropertyValue
620 Dim oGraphicProvider As Object &apos; com.sun.star.graphic.GraphicProvider
621 Dim oImage As Object &apos; Return value
623 On Local Error GoTo Catch &apos; Ignore errors
624 Set oImage = Nothing
626 Try:
627 &apos; Create graphic provider instance to load images from files.
628 Set oGraphicProvider = CreateUnoService(&quot;com.sun.star.graphic.GraphicProvider&quot;)
630 &apos; Set the URL property so graphic provider is able to load the image
631 Set vMediaProperties = Array(ScriptForge.SF_Utils._MakePropertyValue(&quot;URL&quot;, psURL))
633 &apos; Retrieve the com.sun.star.graphic.XGraphic instance
634 Set oImage = oGraphicProvider.queryGraphic(vMediaProperties)
636 Finally:
637 Set _GetImageFromUrl = oImage
638 Exit Function
639 Catch:
640 GoTo Finally
641 End Function &apos; SFWidgets.SF_PopupMenu._GetImageFromUrl
643 REM -----------------------------------------------------------------------------
644 Private Function _GetPopupMenu(ByVal psSubmenu As String) As Object
645 &apos;&apos;&apos; Get the com.sun.star.awt.XPopupMenu object corresponding with the string in argument
646 &apos;&apos;&apos; If the menu exists, it is found in the MenuTree dictionary
647 &apos;&apos;&apos; If it does not exist, it is created recursively.
648 &apos;&apos;&apos; Args:
649 &apos;&apos;&apos; psSubmenu: a string like &quot;A&gt;B&quot;
650 &apos;&apos;&apos; Returns
651 &apos;&apos;&apos; A com.sun.star.awt.XpopupMenu object
652 &apos;&apos;&apos; Example
653 &apos;&apos;&apos; If psSubmenu = &quot;A&gt;B&gt;C&gt;D&quot;, and only the root menu exists,
654 &apos;&apos;&apos; - &quot;A&quot;, &quot;A&gt;B&quot;, &quot;A&gt;B&gt;C&quot;, &quot;A&gt;B&gt;C&gt;D&quot; should be created
655 &apos;&apos;&apos; - the popup menu corresponding with &quot;A&gt;B&gt;C&gt;D&quot; should be returned
657 Dim oPopup As Object &apos; Return value
658 Dim vSplit As Variant &apos; An array as returned by Split()
659 Dim sMenu As String &apos; The left part of psSubmenu
660 Dim oMenu As Object &apos; com.sun.star.awt.XpopupMenu
661 Dim oLastMenu As Object &apos; com.sun.star.awt.XpopupMenu
662 Dim i As Long
664 Set oPopup = Nothing
665 Set oLastMenu = MenuRoot
666 Try:
667 If Len(psSubmenu) = 0 Then &apos; Menu starts at the root
668 Set oPopup = MenuRoot
669 ElseIf MenuTree.Exists(psSubmenu) Then &apos; Shortcut: if the submenu exists, get it directly
670 Set oPopup = MenuTree.Item(psSubmenu)
671 Else &apos; Build the tree
672 vSplit = Split(psSubmenu, SubmenuChar)
673 &apos; Search the successive submenus in the MenuTree dictionary, If not found, create a new entry
674 For i = 0 To UBound(vSplit)
675 sMenu = Join(ScriptForge.SF_Array.Slice(vSplit, 0, i), SubmenuChar)
676 If MenuTree.Exists(sMenu) Then
677 Set oLastMenu = MenuTree.Item(sMenu)
678 Else
679 &apos; Insert the new menu tree item
680 LastItem = LastItem + 1
681 oLastMenu.insertItem(LastItem, vSplit(i), 0, -1)
682 Set oMenu = CreateUnoService(&quot;stardiv.vcl.PopupMenu&quot;)
683 If MenubarMenu Then SFWidgets.SF_MenuListener.SetMenuListener(oMenu)
684 MenuTree.Add(sMenu, oMenu)
685 oLastMenu.setPopupMenu(LastItem, oMenu)
686 Set oLastMenu = oMenu
687 End If
688 Next i
689 Set oPopup = oLastMenu
690 End If
692 Finally:
693 Set _GetPopupMenu = oPopup
694 Exit Function
695 End Function &apos; SFWidgets.SF_PopupMenu._GetPopupMenu
697 REM -----------------------------------------------------------------------------
698 Public Sub _Initialize(ByRef poPeer As Object _
699 , plXPos As Long _
700 , plYPos As Long _
701 , psSubmenuChar As String _
703 &apos;&apos;&apos; Complete the object creation process:
704 &apos;&apos;&apos; - Initialize the dictionaries
705 &apos;&apos;&apos; - initialize the root popup menu
706 &apos;&apos;&apos; - initialize the display area
707 &apos;&apos;&apos; - store the arguments for later use
708 &apos;&apos;&apos; Args:
709 &apos;&apos;&apos; poPeer: a peer window
710 &apos;&apos;&apos; plXPos, plYPos: the coordinates
712 Try:
713 &apos; Initialize the dictionaries (with case-sensitive comparison of keys)
714 With ScriptForge.SF_Services
715 Set MenuTree = .CreateScriptService(&quot;Dictionary&quot;, True)
716 Set MenuIdentification = .CreateScriptService(&quot;Dictionary&quot;, True)
717 End With
719 &apos; Initialize the root of the menu tree
720 Set MenuRoot = CreateUnoService(&quot;stardiv.vcl.PopupMenu&quot;)
722 &apos; Setup the display area
723 Set Rectangle = New com.sun.star.awt.Rectangle
724 Rectangle.X = plXPos
725 Rectangle.Y = plYPos
727 &apos; Keep the targeted window
728 Set PeerWindow = poPeer
730 &apos; Store the submenu character
731 If Len(psSubmenuChar) &gt; 0 Then SubmenuChar = psSubmenuChar
733 Finally:
734 Exit Sub
735 End Sub &apos; SFWidgets.SF_PopupMenu._Initialize
737 REM -----------------------------------------------------------------------------
738 Private Function _PropertyGet(Optional ByVal psProperty As String) As Variant
739 &apos;&apos;&apos; Return the value of the named property
740 &apos;&apos;&apos; Args:
741 &apos;&apos;&apos; psProperty: the name of the property
743 Dim vGet As Variant &apos; Return value
744 Dim cstThisSub As String
745 Const cstSubArgs = &quot;&quot;
747 cstThisSub = &quot;SFWidgets.PopupMenu.get&quot; &amp; psProperty
748 If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
750 ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
751 _PropertyGet = Null
753 Select Case UCase(psProperty)
754 Case UCase(&quot;ShortcutCharacter&quot;)
755 _PropertyGet = _UnderlineAccessKeyChar
756 Case UCase(&quot;SubmenuCharacter&quot;)
757 _PropertyGet = SubmenuChar
758 Case Else
759 _PropertyGet = Null
760 End Select
762 Finally:
763 ScriptForge.SF_Utils._ExitFunction(cstThisSub)
764 Exit Function
765 Catch:
766 GoTo Finally
767 End Function &apos; SFWidgets.SF_PopupMenu._PropertyGet
769 REM -----------------------------------------------------------------------------
770 Private Function _Repr() As String
771 &apos;&apos;&apos; Convert the SF_PopupMenu instance to a readable string, typically for debugging purposes (DebugPrint ...)
772 &apos;&apos;&apos; Args:
773 &apos;&apos;&apos; Return:
774 &apos;&apos;&apos; &quot;[PopupMenu]: Name, Type (dialogname)
775 _Repr = &quot;[PopupMenu]: &quot; &amp; SF_String.Represent(MenuTree.Keys()) &amp; &quot;, &quot; &amp; SF_String.Represent(MenuIdentification.Items())
777 End Function &apos; SFWidgets.SF_PopupMenu._Repr
779 REM -----------------------------------------------------------------------------
780 Private Function _SplitMenuItem(ByVal psMenuItem As String ) As Variant
781 &apos;&apos;&apos; Split a menu item given as a string and delimited by the submenu character
782 &apos;&apos;&apos; Args:
783 &apos;&apos;&apos; psMenuItem: a string like &quot;A&gt;B&gt;C&quot;
784 &apos;&apos;&apos; Returns:
785 &apos;&apos;&apos; An array: [0] = &quot;A&gt;B&quot;
786 &apos;&apos;&apos; [1] = &quot;C&quot;
788 Dim vReturn(0 To 1) As String &apos; Return value
789 Dim vMenus() As Variant &apos; Array of menus
791 Try:
792 vMenus = Split(psMenuItem, SubmenuChar)
793 vReturn(1) = vMenus(UBound(vMenus))
794 vReturn(0) = Left(psMenuItem, Len(psMenuItem) - Iif(UBound(vMenus) &gt; 0, Len(SubmenuChar), 0) - Len(vReturn(1)))
796 Finally:
797 _SplitMenuItem = vReturn
798 End Function &apos; SFWidgets.SF_PopupMenu._SplitMenuItem
800 REM ============================================ END OF SFWIDGETS.SF_POPUPMENU
801 </script:module>