SF_PopupMenu.xba 38 KB

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