SF_DialogControl.xba 100 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084
  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_DialogControl" 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 SFDialogs 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_DialogControl
  13. &apos;&apos;&apos; ================
  14. &apos;&apos;&apos; Manage the controls belonging to a dialog defined with the Basic IDE
  15. &apos;&apos;&apos; Each instance of the current class represents a single control within a dialog box
  16. &apos;&apos;&apos;
  17. &apos;&apos;&apos; The focus is clearly set on getting and setting the values displayed by the controls of the dialog box,
  18. &apos;&apos;&apos; not on their formatting. The latter is easily accessible via the XControlModel and XControlView
  19. &apos;&apos;&apos; UNO objects.
  20. &apos;&apos;&apos; Essentially a single property &quot;Value&quot; maps many alternative UNO properties depending each on
  21. &apos;&apos;&apos; the control type.
  22. &apos;&apos;&apos;
  23. &apos;&apos;&apos; A special attention is given to controls with types TreeControl and TableControl
  24. &apos;&apos;&apos; It is easy with the API proposed in the current class to populate a tree, either
  25. &apos;&apos;&apos; - branch by branch (CreateRoot and AddSubNode), or
  26. &apos;&apos;&apos; - with a set of branches at once (AddSubtree)
  27. &apos;&apos;&apos; Additionally populating a TreeControl can be done statically or dynamically
  28. &apos;&apos;&apos;
  29. &apos;&apos;&apos; With the method SetTableData(), feed a tablecontrol with a sortable and selectable
  30. &apos;&apos;&apos; array of data. Columns and rows may receive a header. Column widths are adjusted manually by the user or
  31. &apos;&apos;&apos; with the same method. Alignments can be set as well by script.
  32. &apos;&apos;&apos;
  33. &apos;&apos;&apos; Service invocation:
  34. &apos;&apos;&apos; Dim myDialog As Object, myControl As Object
  35. &apos;&apos;&apos; Set myDialog = CreateScriptService(&quot;SFDialogs.Dialog&quot;, &quot;GlobalScope&quot;, myLibrary, DialogName)
  36. &apos;&apos;&apos; Set myControl = myDialog.Controls(&quot;myTextBox&quot;)
  37. &apos;&apos;&apos; myControl.Value = &quot;Dialog started at &quot; &amp; Now()
  38. &apos;&apos;&apos; myDialog.Execute()
  39. &apos;&apos;&apos; &apos; ... process the controls actual values
  40. &apos;&apos;&apos; myDialog.Terminate()
  41. &apos;&apos;&apos;
  42. &apos;&apos;&apos; Detailed user documentation:
  43. &apos;&apos;&apos; https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03/sf_dialogcontrol.html?DbPAR=BASIC
  44. &apos;&apos;&apos;
  45. &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;
  46. REM ================================================================== EXCEPTIONS
  47. Private Const CONTROLTYPEERROR = &quot;CONTROLTYPEERROR&quot;
  48. Private Const TEXTFIELDERROR = &quot;TEXTFIELDERROR&quot;
  49. REM ============================================================= PRIVATE MEMBERS
  50. Private [Me] As Object
  51. Private [_Parent] As Object
  52. Private ObjectType As String &apos; Must be DIALOGCONTROL
  53. Private ServiceName As String
  54. &apos; Control naming
  55. Private _Name As String
  56. Private _IndexOfNames As Long &apos; Index in ElementNames array. Used to access SF_Dialog._ControlCache
  57. Private _DialogName As String &apos; Parent dialog name
  58. &apos; Control UNO references
  59. Private _ControlModel As Object &apos; com.sun.star.awt.XControlModel
  60. Private _ControlView As Object &apos; com.sun.star.awt.XControl - stardiv.Toolkit.UnoDialogControl
  61. Private _TreeDataModel As Object &apos; com.sun.star.awt.tree.MutableTreeDataModel
  62. Private _GridColumnModel As Object &apos; com.sun.star.awt.grid.XGridColumnModel
  63. Private _GridDataModel As Object &apos; com.sun.star.awt.grid.XGridDataModel
  64. &apos; Control attributes
  65. Private _ImplementationName As String
  66. Private _ControlType As String &apos; One of the CTLxxx constants
  67. &apos; Tree control on-select and on-expand attributes
  68. &apos; Tree controls may be associated with events not defined in the Basic IDE
  69. Private _OnNodeSelected As String &apos; Script to invoke when a node is selected
  70. Private _OnNodeExpanded As String &apos; Script to invoke when a node is expanded
  71. Private _SelectListener As Object &apos; com.sun.star.view.XSelectionChangeListener
  72. Private _ExpandListener As Object &apos; com.sun.star.awt.tree.XTreeExpansionListener
  73. &apos; Table control attributes
  74. Private _ColumnWidths As Variant &apos; Array of column widths
  75. REM ============================================================ MODULE CONSTANTS
  76. Private Const CTLBUTTON = &quot;Button&quot;
  77. Private Const CTLCHECKBOX = &quot;CheckBox&quot;
  78. Private Const CTLCOMBOBOX = &quot;ComboBox&quot;
  79. Private Const CTLCURRENCYFIELD = &quot;CurrencyField&quot;
  80. Private Const CTLDATEFIELD = &quot;DateField&quot;
  81. Private Const CTLFILECONTROL = &quot;FileControl&quot;
  82. Private Const CTLFIXEDLINE = &quot;FixedLine&quot;
  83. Private Const CTLFIXEDTEXT = &quot;FixedText&quot;
  84. Private Const CTLFORMATTEDFIELD = &quot;FormattedField&quot;
  85. Private Const CTLGROUPBOX = &quot;GroupBox&quot;
  86. Private Const CTLIMAGECONTROL = &quot;ImageControl&quot;
  87. Private Const CTLLISTBOX = &quot;ListBox&quot;
  88. Private Const CTLNUMERICFIELD = &quot;NumericField&quot;
  89. Private Const CTLPATTERNFIELD = &quot;PatternField&quot;
  90. Private Const CTLPROGRESSBAR = &quot;ProgressBar&quot;
  91. Private Const CTLRADIOBUTTON = &quot;RadioButton&quot;
  92. Private Const CTLSCROLLBAR = &quot;ScrollBar&quot;
  93. Private Const CTLTABLECONTROL = &quot;TableControl&quot;
  94. Private Const CTLTEXTFIELD = &quot;TextField&quot;
  95. Private Const CTLTIMEFIELD = &quot;TimeField&quot;
  96. Private Const CTLTREECONTROL = &quot;TreeControl&quot;
  97. REM ====================================================== CONSTRUCTOR/DESTRUCTOR
  98. REM -----------------------------------------------------------------------------
  99. Private Sub Class_Initialize()
  100. Set [Me] = Nothing
  101. Set [_Parent] = Nothing
  102. ObjectType = &quot;DIALOGCONTROL&quot;
  103. ServiceName = &quot;SFDialogs.DialogControl&quot;
  104. _Name = &quot;&quot;
  105. _IndexOfNames = -1
  106. _DialogName = &quot;&quot;
  107. Set _ControlModel = Nothing
  108. Set _ControlView = Nothing
  109. Set _TreeDataModel = Nothing
  110. Set _GridColumnModel = Nothing
  111. Set _GridDataModel = Nothing
  112. _ImplementationName = &quot;&quot;
  113. _ControlType = &quot;&quot;
  114. _OnNodeSelected = &quot;&quot;
  115. _OnNodeExpanded = &quot;&quot;
  116. Set _SelectListener = Nothing
  117. Set _ExpandListener = Nothing
  118. _ColumnWidths = Array()
  119. End Sub &apos; SFDialogs.SF_DialogControl Constructor
  120. REM -----------------------------------------------------------------------------
  121. Private Sub Class_Terminate()
  122. Call Class_Initialize()
  123. End Sub &apos; SFDialogs.SF_DialogControl Destructor
  124. REM -----------------------------------------------------------------------------
  125. Public Function Dispose() As Variant
  126. Call Class_Terminate()
  127. Set Dispose = Nothing
  128. End Function &apos; SFDialogs.SF_DialogControl Explicit Destructor
  129. REM ================================================================== PROPERTIES
  130. REM -----------------------------------------------------------------------------
  131. Property Get Cancel() As Variant
  132. &apos;&apos;&apos; The Cancel property specifies if a command button has or not the behaviour of a Cancel button.
  133. Cancel = _PropertyGet(&quot;Cancel&quot;, False)
  134. End Property &apos; SFDialogs.SF_DialogControl.Cancel (get)
  135. REM -----------------------------------------------------------------------------
  136. Property Let Cancel(Optional ByVal pvCancel As Variant)
  137. &apos;&apos;&apos; Set the updatable property Cancel
  138. _PropertySet(&quot;Cancel&quot;, pvCancel)
  139. End Property &apos; SFDialogs.SF_DialogControl.Cancel (let)
  140. REM -----------------------------------------------------------------------------
  141. Property Get Caption() As Variant
  142. &apos;&apos;&apos; The Caption property refers to the text associated with the control
  143. Caption = _PropertyGet(&quot;Caption&quot;, &quot;&quot;)
  144. End Property &apos; SFDialogs.SF_DialogControl.Caption (get)
  145. REM -----------------------------------------------------------------------------
  146. Property Let Caption(Optional ByVal pvCaption As Variant)
  147. &apos;&apos;&apos; Set the updatable property Caption
  148. _PropertySet(&quot;Caption&quot;, pvCaption)
  149. End Property &apos; SFDialogs.SF_DialogControl.Caption (let)
  150. REM -----------------------------------------------------------------------------
  151. Property Get ControlType() As String
  152. &apos;&apos;&apos; Return the type of the actual control: &quot;CheckBox&quot;, &quot;TextField&quot;, &quot;DateField&quot;, ...
  153. ControlType = _PropertyGet(&quot;ControlType&quot;)
  154. End Property &apos; SFDialogs.SF_DialogControl.ControlType
  155. REM -----------------------------------------------------------------------------
  156. Property Get CurrentNode() As Variant
  157. &apos;&apos;&apos; The CurrentNode property returns the currently selected node
  158. &apos;&apos;&apos; It returns Empty when there is no node selected
  159. &apos;&apos;&apos; When there are several selections, it returns the topmost node among the selected ones
  160. CurrentNode = _PropertyGet(&quot;CurrentNode&quot;, &quot;&quot;)
  161. End Property &apos; SFDialogs.SF_DialogControl.CurrentNode (get)
  162. REM -----------------------------------------------------------------------------
  163. Property Let CurrentNode(Optional ByVal pvCurrentNode As Variant)
  164. &apos;&apos;&apos; Set a single selection in a tree control
  165. _PropertySet(&quot;CurrentNode&quot;, pvCurrentNode)
  166. End Property &apos; SFDialogs.SF_DialogControl.CurrentNode (let)
  167. REM -----------------------------------------------------------------------------
  168. Property Get Default() As Variant
  169. &apos;&apos;&apos; The Default property specifies whether a command button is the default (OK) button.
  170. Default = _PropertyGet(&quot;Default&quot;, False)
  171. End Property &apos; SFDialogs.SF_DialogControl.Default (get)
  172. REM -----------------------------------------------------------------------------
  173. Property Let Default(Optional ByVal pvDefault As Variant)
  174. &apos;&apos;&apos; Set the updatable property Default
  175. _PropertySet(&quot;Default&quot;, pvDefault)
  176. End Property &apos; SFDialogs.SF_DialogControl.Default (let)
  177. REM -----------------------------------------------------------------------------
  178. Property Get Enabled() As Variant
  179. &apos;&apos;&apos; The Enabled property specifies if the control is accessible with the cursor.
  180. Enabled = _PropertyGet(&quot;Enabled&quot;)
  181. End Property &apos; SFDialogs.SF_DialogControl.Enabled (get)
  182. REM -----------------------------------------------------------------------------
  183. Property Let Enabled(Optional ByVal pvEnabled As Variant)
  184. &apos;&apos;&apos; Set the updatable property Enabled
  185. _PropertySet(&quot;Enabled&quot;, pvEnabled)
  186. End Property &apos; SFDialogs.SF_DialogControl.Enabled (let)
  187. REM -----------------------------------------------------------------------------
  188. Property Get Format() As Variant
  189. &apos;&apos;&apos; The Format property specifies the format in which to display dates and times.
  190. Format = _PropertyGet(&quot;Format&quot;, &quot;&quot;)
  191. End Property &apos; SFDialogs.SF_DialogControl.Format (get)
  192. REM -----------------------------------------------------------------------------
  193. Property Let Format(Optional ByVal pvFormat As Variant)
  194. &apos;&apos;&apos; Set the updatable property Format
  195. &apos;&apos;&apos; NB: Format is read-only for formatted field controls
  196. _PropertySet(&quot;Format&quot;, pvFormat)
  197. End Property &apos; SFDialogs.SF_DialogControl.Format (let)
  198. REM -----------------------------------------------------------------------------
  199. Property Get ListCount() As Long
  200. &apos;&apos;&apos; The ListCount property specifies the number of rows in a list box or a combo box
  201. ListCount = _PropertyGet(&quot;ListCount&quot;, 0)
  202. End Property &apos; SFDialogs.SF_DialogControl.ListCount (get)
  203. REM -----------------------------------------------------------------------------
  204. Property Get ListIndex() As Variant
  205. &apos;&apos;&apos; The ListIndex property specifies which item is selected in a list box or combo box.
  206. &apos;&apos;&apos; In case of multiple selection, the index of the first one is returned or only one is set
  207. ListIndex = _PropertyGet(&quot;ListIndex&quot;, -1)
  208. End Property &apos; SFDialogs.SF_DialogControl.ListIndex (get)
  209. REM -----------------------------------------------------------------------------
  210. Property Let ListIndex(Optional ByVal pvListIndex As Variant)
  211. &apos;&apos;&apos; Set the updatable property ListIndex
  212. _PropertySet(&quot;ListIndex&quot;, pvListIndex)
  213. End Property &apos; SFDialogs.SF_DialogControl.ListIndex (let)
  214. REM -----------------------------------------------------------------------------
  215. Property Get Locked() As Variant
  216. &apos;&apos;&apos; The Locked property specifies if a control is read-only
  217. Locked = _PropertyGet(&quot;Locked&quot;, False)
  218. End Property &apos; SFDialogs.SF_DialogControl.Locked (get)
  219. REM -----------------------------------------------------------------------------
  220. Property Let Locked(Optional ByVal pvLocked As Variant)
  221. &apos;&apos;&apos; Set the updatable property Locked
  222. _PropertySet(&quot;Locked&quot;, pvLocked)
  223. End Property &apos; SFDialogs.SF_DialogControl.Locked (let)
  224. REM -----------------------------------------------------------------------------
  225. Property Get MultiSelect() As Variant
  226. &apos;&apos;&apos; The MultiSelect property specifies whether a user can make multiple selections in a listbox
  227. MultiSelect = _PropertyGet(&quot;MultiSelect&quot;, False)
  228. End Property &apos; SFDialogs.SF_DialogControl.MultiSelect (get)
  229. REM -----------------------------------------------------------------------------
  230. Property Let MultiSelect(Optional ByVal pvMultiSelect As Variant)
  231. &apos;&apos;&apos; Set the updatable property MultiSelect
  232. _PropertySet(&quot;MultiSelect&quot;, pvMultiSelect)
  233. End Property &apos; SFDialogs.SF_DialogControl.MultiSelect (let)
  234. REM -----------------------------------------------------------------------------
  235. Property Get Name() As String
  236. &apos;&apos;&apos; Return the name of the actual control
  237. Name = _PropertyGet(&quot;Name&quot;)
  238. End Property &apos; SFDialogs.SF_DialogControl.Name
  239. REM -----------------------------------------------------------------------------
  240. Property Get OnActionPerformed() As Variant
  241. &apos;&apos;&apos; Get the script associated with the OnActionPerformed event
  242. OnActionPerformed = _PropertyGet(&quot;OnActionPerformed&quot;)
  243. End Property &apos; SFDialogs.SF_DialogControl.OnActionPerformed (get)
  244. REM -----------------------------------------------------------------------------
  245. Property Get OnAdjustmentValueChanged() As Variant
  246. &apos;&apos;&apos; Get the script associated with the OnAdjustmentValueChanged event
  247. OnAdjustmentValueChanged = _PropertyGet(&quot;OnAdjustmentValueChanged&quot;)
  248. End Property &apos; SFDialogs.SF_DialogControl.OnAdjustmentValueChanged (get)
  249. REM -----------------------------------------------------------------------------
  250. Property Get OnFocusGained() As Variant
  251. &apos;&apos;&apos; Get the script associated with the OnFocusGained event
  252. OnFocusGained = _PropertyGet(&quot;OnFocusGained&quot;)
  253. End Property &apos; SFDialogs.SF_DialogControl.OnFocusGained (get)
  254. REM -----------------------------------------------------------------------------
  255. Property Get OnFocusLost() As Variant
  256. &apos;&apos;&apos; Get the script associated with the OnFocusLost event
  257. OnFocusLost = _PropertyGet(&quot;OnFocusLost&quot;)
  258. End Property &apos; SFDialogs.SF_DialogControl.OnFocusLost (get)
  259. REM -----------------------------------------------------------------------------
  260. Property Get OnItemStateChanged() As Variant
  261. &apos;&apos;&apos; Get the script associated with the OnItemStateChanged event
  262. OnItemStateChanged = _PropertyGet(&quot;OnItemStateChanged&quot;)
  263. End Property &apos; SFDialogs.SF_DialogControl.OnItemStateChanged (get)
  264. REM -----------------------------------------------------------------------------
  265. Property Get OnKeyPressed() As Variant
  266. &apos;&apos;&apos; Get the script associated with the OnKeyPressed event
  267. OnKeyPressed = _PropertyGet(&quot;OnKeyPressed&quot;)
  268. End Property &apos; SFDialogs.SF_DialogControl.OnKeyPressed (get)
  269. REM -----------------------------------------------------------------------------
  270. Property Get OnKeyReleased() As Variant
  271. &apos;&apos;&apos; Get the script associated with the OnKeyReleased event
  272. OnKeyReleased = _PropertyGet(&quot;OnKeyReleased&quot;)
  273. End Property &apos; SFDialogs.SF_DialogControl.OnKeyReleased (get)
  274. REM -----------------------------------------------------------------------------
  275. Property Get OnMouseDragged() As Variant
  276. &apos;&apos;&apos; Get the script associated with the OnMouseDragged event
  277. OnMouseDragged = _PropertyGet(&quot;OnMouseDragged&quot;)
  278. End Property &apos; SFDialogs.SF_DialogControl.OnMouseDragged (get)
  279. REM -----------------------------------------------------------------------------
  280. Property Get OnMouseEntered() As Variant
  281. &apos;&apos;&apos; Get the script associated with the OnMouseEntered event
  282. OnMouseEntered = _PropertyGet(&quot;OnMouseEntered&quot;)
  283. End Property &apos; SFDialogs.SF_DialogControl.OnMouseEntered (get)
  284. REM -----------------------------------------------------------------------------
  285. Property Get OnMouseExited() As Variant
  286. &apos;&apos;&apos; Get the script associated with the OnMouseExited event
  287. OnMouseExited = _PropertyGet(&quot;OnMouseExited&quot;)
  288. End Property &apos; SFDialogs.SF_DialogControl.OnMouseExited (get)
  289. REM -----------------------------------------------------------------------------
  290. Property Get OnMouseMoved() As Variant
  291. &apos;&apos;&apos; Get the script associated with the OnMouseMoved event
  292. OnMouseMoved = _PropertyGet(&quot;OnMouseMoved&quot;)
  293. End Property &apos; SFDialogs.SF_DialogControl.OnMouseMoved (get)
  294. REM -----------------------------------------------------------------------------
  295. Property Get OnMousePressed() As Variant
  296. &apos;&apos;&apos; Get the script associated with the OnMousePressed event
  297. OnMousePressed = _PropertyGet(&quot;OnMousePressed&quot;)
  298. End Property &apos; SFDialogs.SF_DialogControl.OnMousePressed (get)
  299. REM -----------------------------------------------------------------------------
  300. Property Get OnMouseReleased() As Variant
  301. &apos;&apos;&apos; Get the script associated with the OnMouseReleased event
  302. OnMouseReleased = _PropertyGet(&quot;OnMouseReleased&quot;)
  303. End Property &apos; SFDialogs.SF_DialogControl.OnMouseReleased (get)
  304. REM -----------------------------------------------------------------------------
  305. Property Get OnNodeExpanded() As Variant
  306. &apos;&apos;&apos; Get the script associated with the OnNodeExpanded event
  307. OnNodeExpanded = _PropertyGet(&quot;OnNodeExpanded&quot;)
  308. End Property &apos; SFDialogs.SF_DialogControl.OnNodeExpanded (get)
  309. REM -----------------------------------------------------------------------------
  310. Property Let OnNodeExpanded(Optional ByVal pvOnNodeExpanded As Variant)
  311. &apos;&apos;&apos; Set the updatable property OnNodeExpanded
  312. _PropertySet(&quot;OnNodeExpanded&quot;, pvOnNodeExpanded)
  313. End Property &apos; SFDialogs.SF_DialogControl.OnNodeExpanded (let)
  314. REM -----------------------------------------------------------------------------
  315. Property Get OnNodeSelected() As Variant
  316. &apos;&apos;&apos; Get the script associated with the OnNodeSelected event
  317. OnNodeSelected = _PropertyGet(&quot;OnNodeSelected&quot;)
  318. End Property &apos; SFDialogs.SF_DialogControl.OnNodeSelected (get)
  319. REM -----------------------------------------------------------------------------
  320. Property Let OnNodeSelected(Optional ByVal pvOnNodeSelected As Variant)
  321. &apos;&apos;&apos; Set the updatable property OnNodeSelected
  322. _PropertySet(&quot;OnNodeSelected&quot;, pvOnNodeSelected)
  323. End Property &apos; SFDialogs.SF_DialogControl.OnNodeSelected (let)
  324. REM -----------------------------------------------------------------------------
  325. Property Get OnTextChanged() As Variant
  326. &apos;&apos;&apos; Get the script associated with the OnTextChanged event
  327. OnTextChanged = _PropertyGet(&quot;OnTextChanged&quot;)
  328. End Property &apos; SFDialogs.SF_DialogControl.OnTextChanged (get)
  329. REM -----------------------------------------------------------------------------
  330. Property Get Page() As Variant
  331. &apos;&apos;&apos; A dialog may have several pages that can be traversed by the user step by step. The Page property of the Dialog object defines which page of the dialog is active.
  332. &apos;&apos;&apos; The Page property of a control defines the page of the dialog on which the control is visible.
  333. &apos;&apos;&apos; For example, if a control has a page value of 1, it is only visible on page 1 of the dialog.
  334. &apos;&apos;&apos; If the page value of the dialog is increased from 1 to 2, then all controls with a page value of 1 disappear and all controls with a page value of 2 become visible.
  335. Page = _PropertyGet(&quot;Page&quot;)
  336. End Property &apos; SFDialogs.SF_DialogControl.Page (get)
  337. REM -----------------------------------------------------------------------------
  338. Property Let Page(Optional ByVal pvPage As Variant)
  339. &apos;&apos;&apos; Set the updatable property Page
  340. _PropertySet(&quot;Page&quot;, pvPage)
  341. End Property &apos; SFDialogs.SF_DialogControl.Page (let)
  342. REM -----------------------------------------------------------------------------
  343. Property Get Parent() As Object
  344. &apos;&apos;&apos; Return the Parent dialog object of the actual control
  345. Parent = _PropertyGet(&quot;Parent&quot;, Nothing)
  346. End Property &apos; SFDialogs.SF_DialogControl.Parent
  347. REM -----------------------------------------------------------------------------
  348. Property Get Picture() As Variant
  349. &apos;&apos;&apos; The Picture property specifies a bitmap or other type of graphic to be displayed on the specified control
  350. Picture = _PropertyGet(&quot;Picture&quot;, &quot;&quot;)
  351. End Property &apos; SFDialogs.SF_DialogControl.Picture (get)
  352. REM -----------------------------------------------------------------------------
  353. Property Let Picture(Optional ByVal pvPicture As Variant)
  354. &apos;&apos;&apos; Set the updatable property Picture
  355. _PropertySet(&quot;Picture&quot;, pvPicture)
  356. End Property &apos; SFDialogs.SF_DialogControl.Picture (let)
  357. REM -----------------------------------------------------------------------------
  358. Property Get RootNode() As Variant
  359. &apos;&apos;&apos; The RootNode property returns the last root node of a tree control
  360. RootNode = _PropertyGet(&quot;RootNode&quot;, &quot;&quot;)
  361. End Property &apos; SFDialogs.SF_DialogControl.RootNode (get)
  362. REM -----------------------------------------------------------------------------
  363. Property Get RowSource() As Variant
  364. &apos;&apos;&apos; The RowSource property specifies the data contained in a combobox or a listbox
  365. &apos;&apos;&apos; as a zero-based array of string values
  366. RowSource = _PropertyGet(&quot;RowSource&quot;, &quot;&quot;)
  367. End Property &apos; SFDialogs.SF_DialogControl.RowSource (get)
  368. REM -----------------------------------------------------------------------------
  369. Property Let RowSource(Optional ByVal pvRowSource As Variant)
  370. &apos;&apos;&apos; Set the updatable property RowSource
  371. _PropertySet(&quot;RowSource&quot;, pvRowSource)
  372. End Property &apos; SFDialogs.SF_DialogControl.RowSource (let)
  373. REM -----------------------------------------------------------------------------
  374. Property Get Text() As Variant
  375. &apos;&apos;&apos; The Text property specifies the actual content of the control like it is displayed on the screen
  376. Text = _PropertyGet(&quot;Text&quot;, &quot;&quot;)
  377. End Property &apos; SFDialogs.SF_DialogControl.Text (get)
  378. REM -----------------------------------------------------------------------------
  379. Property Get TipText() As Variant
  380. &apos;&apos;&apos; The TipText property specifies the text that appears in a screentip when you hold the mouse pointer over a control
  381. TipText = _PropertyGet(&quot;TipText&quot;, &quot;&quot;)
  382. End Property &apos; SFDialogs.SF_DialogControl.TipText (get)
  383. REM -----------------------------------------------------------------------------
  384. Property Let TipText(Optional ByVal pvTipText As Variant)
  385. &apos;&apos;&apos; Set the updatable property TipText
  386. _PropertySet(&quot;TipText&quot;, pvTipText)
  387. End Property &apos; SFDialogs.SF_DialogControl.TipText (let)
  388. REM -----------------------------------------------------------------------------
  389. Property Get TripleState() As Variant
  390. &apos;&apos;&apos; The TripleState property specifies how a check box will display Null values
  391. &apos;&apos;&apos; When True, the control will cycle through states for Yes, No, and Null values. The control appears dimmed (grayed) when its Value property is set to Null.
  392. &apos;&apos;&apos; When False, the control will cycle through states for Yes and No values. Null values display as if they were No values.
  393. TripleState = _PropertyGet(&quot;TripleState&quot;, False)
  394. End Property &apos; SFDialogs.SF_DialogControl.TripleState (get)
  395. REM -----------------------------------------------------------------------------
  396. Property Let TripleState(Optional ByVal pvTripleState As Variant)
  397. &apos;&apos;&apos; Set the updatable property TripleState
  398. _PropertySet(&quot;TripleState&quot;, pvTripleState)
  399. End Property &apos; SFDialogs.SF_DialogControl.TripleState (let)
  400. REM -----------------------------------------------------------------------------
  401. Property Get Value() As Variant
  402. &apos;&apos;&apos; The Value property specifies the data contained in the control
  403. Value = _PropertyGet(&quot;Value&quot;, Empty)
  404. End Property &apos; SFDialogs.SF_DialogControl.Value (get)
  405. REM -----------------------------------------------------------------------------
  406. Property Let Value(Optional ByVal pvValue As Variant)
  407. &apos;&apos;&apos; Set the updatable property Value
  408. _PropertySet(&quot;Value&quot;, pvValue)
  409. End Property &apos; SFDialogs.SF_DialogControl.Value (let)
  410. REM -----------------------------------------------------------------------------
  411. Property Get Visible() As Variant
  412. &apos;&apos;&apos; The Visible property specifies if the control is accessible with the cursor.
  413. Visible = _PropertyGet(&quot;Visible&quot;, True)
  414. End Property &apos; SFDialogs.SF_DialogControl.Visible (get)
  415. REM -----------------------------------------------------------------------------
  416. Property Let Visible(Optional ByVal pvVisible As Variant)
  417. &apos;&apos;&apos; Set the updatable property Visible
  418. _PropertySet(&quot;Visible&quot;, pvVisible)
  419. End Property &apos; SFDialogs.SF_DialogControl.Visible (let)
  420. REM -----------------------------------------------------------------------------
  421. Property Get XControlModel() As Object
  422. &apos;&apos;&apos; The XControlModel property returns the model UNO object of the control
  423. XControlModel = _PropertyGet(&quot;XControlModel&quot;, Nothing)
  424. End Property &apos; SFDialogs.SF_DialogControl.XControlModel (get)
  425. REM -----------------------------------------------------------------------------
  426. Property Get XControlView() As Object
  427. &apos;&apos;&apos; The XControlView property returns the view UNO object of the control
  428. XControlView = _PropertyGet(&quot;XControlView&quot;, Nothing)
  429. End Property &apos; SFDialogs.SF_DialogControl.XControlView (get)
  430. REM -----------------------------------------------------------------------------
  431. Property Get XGridColumnModel() As Object
  432. &apos;&apos;&apos; The XGridColumnModel property returns the mutable data model UNO object of the tree control
  433. XGridColumnModel = _PropertyGet(&quot;XGridColumnModel&quot;, Nothing)
  434. End Property &apos; SFDialogs.SF_DialogControl.XGridColumnModel (get)
  435. REM -----------------------------------------------------------------------------
  436. Property Get XGridDataModel() As Object
  437. &apos;&apos;&apos; The XGridDataModel property returns the mutable data model UNO object of the tree control
  438. XGridDataModel = _PropertyGet(&quot;XGridDataModel&quot;, Nothing)
  439. End Property &apos; SFDialogs.SF_DialogControl.XGridDataModel (get)
  440. REM -----------------------------------------------------------------------------
  441. Property Get XTreeDataModel() As Object
  442. &apos;&apos;&apos; The XTreeDataModel property returns the mutable data model UNO object of the tree control
  443. XTreeDataModel = _PropertyGet(&quot;XTreeDataModel&quot;, Nothing)
  444. End Property &apos; SFDialogs.SF_DialogControl.XTreeDataModel (get)
  445. REM ===================================================================== METHODS
  446. REM -----------------------------------------------------------------------------
  447. Public Function AddSubNode(Optional ByRef ParentNode As Variant _
  448. , Optional ByVal DisplayValue As Variant _
  449. , Optional ByRef DataValue As Variant _
  450. ) As Variant
  451. &apos;&apos;&apos; Return a new node of the tree control subordinate to a parent node
  452. &apos;&apos;&apos; Args:
  453. &apos;&apos;&apos; ParentNode: A node UNO object, of type com.sun.star.awt.tree.XMutableTreeNode
  454. &apos;&apos;&apos; DisplayValue: the text appearing in the control box
  455. &apos;&apos;&apos; DataValue: any value associated with the new node. Default = Empty
  456. &apos;&apos;&apos; Returns:
  457. &apos;&apos;&apos; The new node UNO object: com.sun.star.awt.tree.XMutableTreeNode
  458. &apos;&apos;&apos; Examples:
  459. &apos;&apos;&apos; Dim myTree As Object, myNode As Object, theRoot As Object
  460. &apos;&apos;&apos; Set myTree = myDialog.Controls(&quot;myTreeControl&quot;)
  461. &apos;&apos;&apos; Set theRoot = myTree.CreateRoot(&quot;Tree top&quot;)
  462. &apos;&apos;&apos; Set myNode = myTree.AddSubNode(theRoot, &quot;A branch ...&quot;)
  463. Dim oNode As Object &apos; Return value
  464. Const cstThisSub = &quot;SFDialogs.DialogControl.AddSubNode&quot;
  465. Const cstSubArgs = &quot;ParentNode, DisplayValue, [DataValue=Empty]&quot;
  466. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  467. Set oNode = Nothing
  468. Check:
  469. If IsMissing(DataValue) Then DataValue = Empty
  470. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  471. If _ControlType &lt;&gt; CTLTREECONTROL Then GoTo CatchType
  472. If Not ScriptForge.SF_Utils._Validate(ParentNode, &quot;ParentNode&quot;, V_OBJECT) Then GoTo Catch
  473. If ScriptForge.SF_Session.UnoObjectType(ParentNode) &lt;&gt; &quot;toolkit.MutableTreeNode&quot; Then GoTo Catch
  474. If Not ScriptForge.SF_Utils._Validate(DisplayValue, &quot;DisplayValue&quot;, V_STRING) Then GoTo Catch
  475. End If
  476. Try:
  477. With _TreeDataModel
  478. Set oNode = .createNode(DisplayValue, True)
  479. oNode.DataValue = DataValue
  480. ParentNode.appendChild(oNode)
  481. End With
  482. Finally:
  483. Set AddSubNode = oNode
  484. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  485. Exit Function
  486. Catch:
  487. GoTo Finally
  488. CatchType:
  489. ScriptForge.SF_Exception.RaiseFatal(CONTROLTYPEERROR, _Name, _DialogName, _ControlType, &quot;AddSubNode&quot;)
  490. GoTo Finally
  491. End Function &apos; SFDialogs.SF_DialogControl.AddSubNode
  492. REM -----------------------------------------------------------------------------
  493. Public Function AddSubTree(Optional ByRef ParentNode As Variant _
  494. , Optional ByRef FlatTree As Variant _
  495. , Optional ByVal WithDataValue As Variant _
  496. ) As Boolean
  497. &apos;&apos;&apos; Return True when a subtree, subordinate to a parent node, could be inserted successfully in a tree control
  498. &apos;&apos;&apos; If the parent node had already child nodes before calling this method, the child nodes are erased
  499. &apos;&apos;&apos; Args:
  500. &apos;&apos;&apos; ParentNode: A node UNO object, of type com.sun.star.awt.tree.XMutableTreeNode
  501. &apos;&apos;&apos; FlatTree: a 2D array sorted on the columns containing the DisplayValues
  502. &apos;&apos;&apos; Flat tree &gt;&gt;&gt;&gt; Resulting subtree
  503. &apos;&apos;&apos; A1 B1 C1 |__ A1
  504. &apos;&apos;&apos; A1 B1 C2 |__ B1
  505. &apos;&apos;&apos; A1 B2 C3 |__ C1
  506. &apos;&apos;&apos; A2 B3 C4 |__ C2
  507. &apos;&apos;&apos; A2 B3 C5 |__ B2
  508. &apos;&apos;&apos; A3 B4 C6 |__ C3
  509. &apos;&apos;&apos; |__ A2
  510. &apos;&apos;&apos; |__ B3
  511. &apos;&apos;&apos; |__ C4
  512. &apos;&apos;&apos; |__ C5
  513. &apos;&apos;&apos; |__ A3
  514. &apos;&apos;&apos; |__ B4
  515. &apos;&apos;&apos; |__ C6
  516. &apos;&apos;&apos; Typically, such an array can be issued by the GetRows method applied on the SFDatabases.Database service
  517. &apos;&apos;&apos; when an array item containing the text to be displayed is = &quot;&quot; or is empty/null,
  518. &apos;&apos;&apos; no new subnode is created and the remainder of the row is skipped
  519. &apos;&apos;&apos; When AddSubTree() is called from a Python script, FlatTree may be an array of arrays
  520. &apos;&apos;&apos; WithDataValue:
  521. &apos;&apos;&apos; When False (default), every column of FlatTree contains the text to be displayed in the tree control
  522. &apos;&apos;&apos; When True, the texts to be displayed (DisplayValue) are in columns 0, 2, 4, ...
  523. &apos;&apos;&apos; while the DataValues are in columns 1, 3, 5, ...
  524. &apos;&apos;&apos; Returns:
  525. &apos;&apos;&apos; True when successful
  526. &apos;&apos;&apos; Examples:
  527. &apos;&apos;&apos; Dim myTree As Object, theRoot As Object, oDb As Object, vData As Variant
  528. &apos;&apos;&apos; Set myTree = myDialog.Controls(&quot;myTreeControl&quot;)
  529. &apos;&apos;&apos; Set theRoot = myTree.CreateRoot(&quot;By product category&quot;)
  530. &apos;&apos;&apos; Set oDb = CreateScriptService(&quot;SFDatabases.Database&quot;, &quot;/home/.../mydatabase.odb&quot;)
  531. &apos;&apos;&apos; vData = oDb.GetRows(&quot;SELECT [Category].[Name], [Category].[ID], [Product].[Name], [Product].[ID] &quot; _
  532. &apos;&apos;&apos; &amp; &quot;FROM [Category], [Product] WHERE [Product].[CategoryID] = [Category].[ID] &quot; _
  533. &apos;&apos;&apos; &amp; &quot;ORDER BY [Category].[Name], [Product].[Name]&quot;)
  534. &apos;&apos;&apos; myTree.AddSubTree(theRoot, vData, WithDataValue := True)
  535. Dim bSubTree As Boolean &apos; Return value
  536. Dim oNode As Object &apos; com.sun.star.awt.tree.XMutableTreeNode
  537. Dim oNewNode As Object &apos; com.sun.star.awt.tree.XMutableTreeNode
  538. Dim lChildCount As Long &apos; Number of children nodes of a parent node
  539. Dim iStep As Integer &apos; 1 when WithDataValue = False, 2 otherwise
  540. Dim iDims As Integer &apos; Number of dimensions of FlatTree
  541. Dim lMin1 As Long &apos; Lower bound (rows)
  542. Dim lMin2 As Long &apos; Lower bounds (cols)
  543. Dim lMax1 As Long &apos; Upper bound (rows)
  544. Dim lMax2 As Long &apos; Upper bounds (cols)
  545. Dim vFlatItem As Variant &apos; A single FlatTree item: FlatTree(i, j)
  546. Dim vFlatItem2 As Variant &apos; A single FlatTree item
  547. Dim bChange As Boolean &apos; When True, the item in FlatTree is different from the item above
  548. Dim sValue As String &apos; Alias for display values
  549. Dim i As Long, j As Long
  550. Const cstThisSub = &quot;SFDialogs.DialogControl.AddSubTree&quot;
  551. Const cstSubArgs = &quot;ParentNode, FlatTree, [WithDataValue=False]&quot;
  552. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  553. bSubTree = False
  554. Check:
  555. If IsMissing(WithDataValue) Or IsEmpty(WithDataValue) Then WithDataValue = False
  556. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  557. If _ControlType &lt;&gt; CTLTREECONTROL Then GoTo CatchType
  558. If Not ScriptForge.SF_Utils._Validate(ParentNode, &quot;ParentNode&quot;, V_OBJECT) Then GoTo Catch
  559. If ScriptForge.SF_Session.UnoObjectType(ParentNode) &lt;&gt; &quot;toolkit.MutableTreeNode&quot; Then GoTo Catch
  560. If Not ScriptForge.SF_Utils._ValidateArray(FlatTree, &quot;FlatTree&quot;) Then GoTo Catch &apos; Dimensions checked below
  561. If Not ScriptForge.SF_Utils._Validate(WithDataValue, &quot;WithDataValue&quot;, V_BOOLEAN) Then GoTo Catch
  562. End If
  563. Try:
  564. With _TreeDataModel
  565. &apos; Clean subtree
  566. lChildCount = ParentNode.getChildCount()
  567. For i = 1 To lChildCount
  568. ParentNode.removeChildByIndex(0) &apos; This cleans all subtrees too
  569. Next i
  570. &apos; Determine bounds
  571. iDims = ScriptForge.SF_Array.CountDims(FlatTree)
  572. Select Case iDims
  573. Case -1, 0 : GoTo Catch
  574. Case 1 &apos; Called probably from Python
  575. lMin1 = LBound(FlatTree, 1) : lMax1 = UBound(FlatTree, 1)
  576. If Not IsArray(FlatTree(0)) Then GoTo Catch
  577. If UBound(FlatTree(0)) &lt; LBound(FlatTree(0)) Then GoTo Catch &apos; No columns
  578. lMin2 = LBound(FlatTree(0)) : lMax2 = UBound(FlatTree(0))
  579. Case 2
  580. lMin1 = LBound(FlatTree, 1) : lMax1 = UBound(FlatTree, 1)
  581. lMin2 = LBound(FlatTree, 2) : lMax2 = UBound(FlatTree, 2)
  582. Case Else : GoTo Catch
  583. End Select
  584. &apos; Build a new subtree
  585. iStep = Iif(WithDataValue, 2, 1)
  586. For i = lMin1 To lMax1
  587. bChange = ( i = 0 )
  588. &apos; Restart from the parent node at each i-iteration
  589. Set oNode = ParentNode
  590. For j = lMin2 To lMax2 Step iStep &apos; Array columns
  591. If iDims = 1 Then vFlatItem = FlatTree(i)(j) Else vFlatItem = FlatTree(i, j)
  592. If vFlatItem = &quot;&quot; Or IsNull(vFlatItem) Or IsEmpty(vFlatItem) Then
  593. Set oNode = Nothing
  594. Exit For &apos; Exit j-loop
  595. End If
  596. If Not bChange Then
  597. If iDims = 1 Then vFlatItem2 = FlatTree(i - 1)(j) Else vFlatItem2 = FlatTree(i - 1, j)
  598. bChange = ( vFlatItem &lt;&gt; vFlatItem2 )
  599. End If
  600. If bChange Then &apos; Create new subnode at tree depth = j
  601. If VarType(vFlatItem) = V_STRING Then sValue = vFlatItem Else sValue = ScriptForge.SF_String.Represent(vFlatItem)
  602. Set oNewNode = .createNode(sValue, True)
  603. If WithDataValue Then
  604. If iDims = 1 Then vFlatItem2 = FlatTree(i)(j + 1) Else vFlatItem2 = FlatTree(i, j + 1)
  605. oNewNode.DataValue = vFlatItem2
  606. End If
  607. oNode.appendChild(oNewNode)
  608. Set oNode = oNewNode
  609. Else
  610. &apos; Position next current node on last child of actual current node
  611. lChildCount = oNode.getChildCount()
  612. If lChildCount &gt; 0 Then Set oNode = oNode.getChildAt(lChildCount - 1) Else Set oNode = Nothing
  613. End If
  614. Next j
  615. Next i
  616. bSubTree = True
  617. End With
  618. Finally:
  619. AddSubTree = bSubTree
  620. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  621. Exit Function
  622. Catch:
  623. GoTo Finally
  624. CatchType:
  625. ScriptForge.SF_Exception.RaiseFatal(CONTROLTYPEERROR, _Name, _DialogName, _ControlType, &quot;AddSubTree&quot;)
  626. GoTo Finally
  627. End Function &apos; SFDialogs.SF_DialogControl.AddSubTree
  628. REM -----------------------------------------------------------------------------
  629. Public Function CreateRoot(Optional ByVal DisplayValue As Variant _
  630. , Optional ByRef DataValue As Variant _
  631. ) As Variant
  632. &apos;&apos;&apos; Return a new root node of the tree control. The new tree root is inserted below pre-existing root nodes
  633. &apos;&apos;&apos; Args:
  634. &apos;&apos;&apos; DisplayValue: the text appearing in the control box
  635. &apos;&apos;&apos; DataValue: any value associated with the root node. Default = Empty
  636. &apos;&apos;&apos; Returns:
  637. &apos;&apos;&apos; The new root node as a UNO object of type com.sun.star.awt.tree.XMutableTreeNode
  638. &apos;&apos;&apos; Examples:
  639. &apos;&apos;&apos; Dim myTree As Object, myNode As Object
  640. &apos;&apos;&apos; Set myTree = myDialog.Controls(&quot;myTreeControl&quot;)
  641. &apos;&apos;&apos; Set myNode = myTree.CreateRoot(&quot;Tree starts here ...&quot;)
  642. Dim oRoot As Object &apos; Return value
  643. Const cstThisSub = &quot;SFDialogs.DialogControl.CreateRoot&quot;
  644. Const cstSubArgs = &quot;DisplayValue, [DataValue=Empty]&quot;
  645. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  646. Set oRoot = Nothing
  647. Check:
  648. If IsMissing(DataValue) Then DataValue = Empty
  649. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  650. If _ControlType &lt;&gt; CTLTREECONTROL Then GoTo CatchType
  651. If Not ScriptForge.SF_Utils._Validate(DisplayValue, &quot;DisplayValue&quot;, V_STRING) Then GoTo Catch
  652. End If
  653. Try:
  654. With _TreeDataModel
  655. Set oRoot = .createNode(DisplayValue, True)
  656. oRoot.DataValue = DataValue
  657. .setRoot(oRoot)
  658. &apos; To be visible, a root must have contained at least 1 child. Create a fictive one and erase it.
  659. &apos; This behaviour does not seem related to the RootDisplayed property ??
  660. oRoot.appendChild(.createNode(&quot;Something&quot;, False))
  661. oRoot.removeChildByIndex(0)
  662. End With
  663. Finally:
  664. Set CreateRoot = oRoot
  665. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  666. Exit Function
  667. Catch:
  668. GoTo Finally
  669. CatchType:
  670. ScriptForge.SF_Exception.RaiseFatal(CONTROLTYPEERROR, _Name, _DialogName, _ControlType, &quot;CreateRoot&quot;)
  671. GoTo Finally
  672. End Function &apos; SFDialogs.SF_DialogControl.CreateRoot
  673. REM -----------------------------------------------------------------------------
  674. Public Function FindNode(Optional ByVal DisplayValue As String _
  675. , Optional ByRef DataValue As Variant _
  676. , Optional ByVal CaseSensitive As Boolean _
  677. ) As Object
  678. &apos;&apos;&apos; Traverses the tree and find recursively, starting from the root, a node meeting some criteria
  679. &apos;&apos;&apos; Either (1 match is enough):
  680. &apos;&apos;&apos; having its DisplayValue like DisplayValue
  681. &apos;&apos;&apos; having its DataValue = DataValue
  682. &apos;&apos;&apos; Comparisons may be or not case-sensitive
  683. &apos;&apos;&apos; The first matching occurrence is returned
  684. &apos;&apos;&apos; Args:
  685. &apos;&apos;&apos; DisplayValue: the pattern to be matched
  686. &apos;&apos;&apos; DataValue: a string, a numeric value or a date or Empty (if not applicable)
  687. &apos;&apos;&apos; CaseSensitive: applicable on both criteria. Default = False
  688. &apos;&apos;&apos; Returns:
  689. &apos;&apos;&apos; The found node of type com.sun.star.awt.tree.XMutableTreeNode or Nothing if not found
  690. &apos;&apos;&apos; Examples:
  691. &apos;&apos;&apos; Dim myTree As Object, myNode As Object
  692. &apos;&apos;&apos; Set myTree = myDialog.Controls(&quot;myTreeControl&quot;)
  693. &apos;&apos;&apos; Set myNode = myTree.FindNode(&quot;*Sophie*&quot;, CaseSensitive := True)
  694. Dim oNode As Object &apos; Return value
  695. Const cstThisSub = &quot;SFDialogs.DialogControl.FindNode&quot;
  696. Const cstSubArgs = &quot;[DisplayValue=&quot;&quot;&quot;&quot;], [DataValue=Empty], [CaseSensitive=False]&quot;
  697. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  698. Set oNode = Nothing
  699. Check:
  700. If IsMissing(DisplayValue) Or IsEmpty(DisplayValue) Then DisplayValue = &quot;&quot;
  701. If IsMissing(DataValue) Then DataValue = Empty
  702. If IsMissing(CaseSensitive) Or IsEmpty(CaseSensitive) Then CaseSensitive = False
  703. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  704. If _ControlType &lt;&gt; CTLTREECONTROL Then GoTo CatchType
  705. If Not ScriptForge.SF_Utils._Validate(DisplayValue, &quot;DisplayValue&quot;, V_STRING) Then GoTo Catch
  706. If Not ScriptForge.SF_Utils._Validate(CaseSensitive, &quot;CaseSensitive&quot;, ScriptForge.V_BOOLEAN) Then GoTo Catch
  707. End If
  708. Try:
  709. Set oNode = _FindNode(_TreeDataModel.getRoot(), DisplayValue, DataValue, CaseSensitive)
  710. Finally:
  711. Set FindNode = oNode
  712. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  713. Exit Function
  714. Catch:
  715. GoTo Finally
  716. CatchType:
  717. ScriptForge.SF_Exception.RaiseFatal(CONTROLTYPEERROR, _Name, _DialogName, _ControlType, &quot;FindNode&quot;)
  718. GoTo Finally
  719. End Function &apos; SFDialogs.SF_DialogControl.FindNode
  720. REM -----------------------------------------------------------------------------
  721. Public Function GetProperty(Optional ByVal PropertyName As Variant) As Variant
  722. &apos;&apos;&apos; Return the actual value of the given property
  723. &apos;&apos;&apos; Args:
  724. &apos;&apos;&apos; PropertyName: the name of the property as a string
  725. &apos;&apos;&apos; Returns:
  726. &apos;&apos;&apos; The actual value of the property
  727. &apos;&apos;&apos; If the property does not exist, returns Null
  728. &apos;&apos;&apos; Exceptions:
  729. &apos;&apos;&apos; see the exceptions of the individual properties
  730. &apos;&apos;&apos; Examples:
  731. &apos;&apos;&apos; myModel.GetProperty(&quot;MyProperty&quot;)
  732. Const cstThisSub = &quot;SFDialogs.DialogControl.GetProperty&quot;
  733. Const cstSubArgs = &quot;&quot;
  734. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  735. GetProperty = Null
  736. Check:
  737. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  738. If Not ScriptForge.SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
  739. End If
  740. Try:
  741. GetProperty = _PropertyGet(PropertyName)
  742. Finally:
  743. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  744. Exit Function
  745. Catch:
  746. GoTo Finally
  747. End Function &apos; SFDialogs.SF_DialogControl.GetProperty
  748. REM -----------------------------------------------------------------------------
  749. Public Function Methods() As Variant
  750. &apos;&apos;&apos; Return the list of public methods of the Model service as an array
  751. Methods = Array( _
  752. &quot;AddSubNode&quot; _
  753. , &quot;AddSubTree&quot; _
  754. , &quot;CreateRoot&quot; _
  755. , &quot;FindNode&quot; _
  756. , &quot;SetFocus&quot; _
  757. , &quot;WriteLine&quot; _
  758. )
  759. End Function &apos; SFDialogs.SF_DialogControl.Methods
  760. REM -----------------------------------------------------------------------------
  761. Public Function Properties() As Variant
  762. &apos;&apos;&apos; Return the list or properties of the Timer class as an array
  763. Properties = Array( _
  764. &quot;Cancel&quot; _
  765. , &quot;Caption&quot; _
  766. , &quot;ControlType&quot; _
  767. , &quot;CurrentNode&quot; _
  768. , &quot;Default&quot; _
  769. , &quot;Enabled&quot; _
  770. , &quot;Format&quot; _
  771. , &quot;ListCount&quot; _
  772. , &quot;ListIndex&quot; _
  773. , &quot;Locked&quot; _
  774. , &quot;MultiSelect&quot; _
  775. , &quot;Name&quot; _
  776. , &quot;OnActionPerformed&quot; _
  777. , &quot;OnAdjustmentValueChanged&quot; _
  778. , &quot;OnFocusGained&quot; _
  779. , &quot;OnFocusLost&quot; _
  780. , &quot;OnItemStateChanged&quot; _
  781. , &quot;OnKeyPressed&quot; _
  782. , &quot;OnKeyReleased&quot; _
  783. , &quot;OnMouseDragged&quot; _
  784. , &quot;OnMouseEntered&quot; _
  785. , &quot;OnMouseExited&quot; _
  786. , &quot;OnMouseMoved&quot; _
  787. , &quot;OnMousePressed&quot; _
  788. , &quot;OnMouseReleased&quot; _
  789. , &quot;OnNodeExpanded&quot; _
  790. , &quot;OnNodeSelected&quot; _
  791. , &quot;OnTextChanged&quot; _
  792. , &quot;Page&quot; _
  793. , &quot;Parent&quot; _
  794. , &quot;Picture&quot; _
  795. , &quot;RootNode&quot; _
  796. , &quot;RowSource&quot; _
  797. , &quot;Text&quot; _
  798. , &quot;TipText&quot; _
  799. , &quot;TripleState&quot; _
  800. , &quot;Value&quot; _
  801. , &quot;Visible&quot; _
  802. , &quot;XControlModel&quot; _
  803. , &quot;XControlView&quot; _
  804. , &quot;XGridColumnModel&quot; _
  805. , &quot;XGridDataModel&quot; _
  806. , &quot;XTreeDataModel&quot; _
  807. )
  808. End Function &apos; SFDialogs.SF_DialogControl.Properties
  809. REM -----------------------------------------------------------------------------
  810. Public Function SetFocus() As Boolean
  811. &apos;&apos;&apos; Set the focus on the current Control instance
  812. &apos;&apos;&apos; Probably called from after an event occurrence
  813. &apos;&apos;&apos; Args:
  814. &apos;&apos;&apos; Returns:
  815. &apos;&apos;&apos; True if focusing is successful
  816. &apos;&apos;&apos; Example:
  817. &apos;&apos;&apos; Dim oDlg As Object, oControl As Object
  818. &apos;&apos;&apos; Set oDlg = CreateScriptService(,, &quot;myControl&quot;) &apos; Control stored in current document&apos;s standard library
  819. &apos;&apos;&apos; Set oControl = oDlg.Controls(&quot;thisControl&quot;)
  820. &apos;&apos;&apos; oControl.SetFocus()
  821. Dim bSetFocus As Boolean &apos; Return value
  822. Const cstThisSub = &quot;SFDialogs.DialogControl.SetFocus&quot;
  823. Const cstSubArgs = &quot;&quot;
  824. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  825. bSetFocus = False
  826. Check:
  827. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  828. If Not [_Parent]._IsStillAlive() Then GoTo Finally
  829. End If
  830. Try:
  831. If Not IsNull(_ControlView) Then
  832. _ControlView.setFocus()
  833. bSetFocus = True
  834. End If
  835. Finally:
  836. SetFocus = bSetFocus
  837. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  838. Exit Function
  839. Catch:
  840. GoTo Finally
  841. End Function &apos; SFControls.SF_DialogControl.SetFocus
  842. REM -----------------------------------------------------------------------------
  843. Public Function SetProperty(Optional ByVal PropertyName As Variant _
  844. , Optional ByRef Value As Variant _
  845. ) As Boolean
  846. &apos;&apos;&apos; Set a new value to the given property
  847. &apos;&apos;&apos; Args:
  848. &apos;&apos;&apos; PropertyName: the name of the property as a string
  849. &apos;&apos;&apos; Value: its new value
  850. &apos;&apos;&apos; Exceptions
  851. &apos;&apos;&apos; ARGUMENTERROR The property does not exist
  852. Const cstThisSub = &quot;SFDialogs.DialogControl.SetProperty&quot;
  853. Const cstSubArgs = &quot;PropertyName, Value&quot;
  854. If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  855. SetProperty = False
  856. Check:
  857. If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  858. If Not SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
  859. End If
  860. Try:
  861. SetProperty = _PropertySet(PropertyName, Value)
  862. Finally:
  863. SF_Utils._ExitFunction(cstThisSub)
  864. Exit Function
  865. Catch:
  866. GoTo Finally
  867. End Function &apos; SFDialogs.SF_DialogControl.SetProperty
  868. REM -----------------------------------------------------------------------------
  869. Public Function SetTableData(Optional ByRef DataArray As Variant _
  870. , Optional ByRef Widths As Variant _
  871. , Optional ByRef Alignments As Variant _
  872. ) As Boolean
  873. &apos;&apos;&apos; Fill a table control with the given data. Preexisting data is erased
  874. &apos;&apos;&apos; The Basic IDE allows to define if the control has a row and/or a column header
  875. &apos;&apos;&apos; When it is the case, the array in argument should contain those headers resp. in the first
  876. &apos;&apos;&apos; column and/or in the first row
  877. &apos;&apos;&apos; A column in the control shall be sortable when the data (headers excluded) in that column
  878. &apos;&apos;&apos; is homogeneously filled either with numbers or with strings
  879. &apos;&apos;&apos; Columns containing strings will be left-aligned, those with numbers will be right-aligned
  880. &apos;&apos;&apos; Args:
  881. &apos;&apos;&apos; DataArray: the set of data to display in the table control, including optional column/row headers
  882. &apos;&apos;&apos; Is a 2D array in Basic, is a tuple of tuples when called from Python
  883. &apos;&apos;&apos; Widths: the column&apos;s relative widths as a 1D array, each element corresponding with a column
  884. &apos;&apos;&apos; If the array is shorter than the number of columns, the last value is kept for the next columns.
  885. &apos;&apos;&apos; Example:
  886. &apos;&apos;&apos; Widths := Array(1, 2)
  887. &apos;&apos;&apos; means that the first column is half as wide as all the other columns
  888. &apos;&apos;&apos; When the argument is absent, the columns are evenly spread over the control
  889. &apos;&apos;&apos; Alignments: the column&apos;s horizontal alignment as a string with length = number of columns.
  890. &apos;&apos;&apos; Possible characters are:
  891. &apos;&apos;&apos; L(EFT), C(ENTER), R(IGHT) or space (default behaviour)
  892. &apos;&apos;&apos; Returns:
  893. &apos;&apos;&apos; True when successful
  894. &apos;&apos;&apos; Examples:
  895. &apos;&apos;&apos; Dim myTable As Object, bSet As Boolean, vData As Variant
  896. &apos;&apos;&apos; Set myTable = myDialog.Controls(&quot;myTableControl&quot;) &apos; This control has only column headers
  897. &apos;&apos;&apos; vData = Array(&quot;Col1&quot;, &quot;Col2&quot;, &quot;Col3&quot;)
  898. &apos;&apos;&apos; vData = SF_Array.AppendRow(vData, Array(1, 2, 3))
  899. &apos;&apos;&apos; vData = SF_Array.AppendRow(vData, Array(4, 5, 6))
  900. &apos;&apos;&apos; vData = SF_Array.AppendRow(vData, Array(7, 8, 9))
  901. &apos;&apos;&apos; bSet = myTable.SetTableData(vData, Alignments := &quot; C &quot;)
  902. Dim bData As Boolean &apos; Return value
  903. Dim iDims As Integer &apos; Number of dimensions of DataArray
  904. Dim lMin1 As Long &apos; LBound1 of input array
  905. Dim lMax1 As Long &apos; UBound1 of input array
  906. Dim lMin2 As Long &apos; LBound2 of input array
  907. Dim lMax2 As Long &apos; UBound2 of input array
  908. Dim lControlWidth As Long &apos; Width of the table control
  909. Dim lMinW As Long &apos; lBound of Widths
  910. Dim lMaxW As Long &apos; UBound of vWidths
  911. Dim lMinRow As Long &apos; Row index of effective data subarray
  912. Dim lMinCol As Long &apos; Column index of effective data subarray
  913. Dim vRowHeaders As Variant &apos; Array of row headers
  914. Dim sRowHeader As String &apos; A single row header
  915. Dim vColHeaders As Variant &apos; Array of column headers
  916. Dim oColumn As Object &apos; com.sun.star.awt.grid.XGridColumn
  917. Dim dWidth As Double &apos; A single item of Widths
  918. Dim dRelativeWidth As Double &apos; Sum of Widths up to the number of columns
  919. Dim dWidthFactor As Double &apos; Factor to apply to relative widths to get absolute column widths
  920. Dim vDataRow As Variant &apos; A single row content in the tablecontrol
  921. Dim vDataItem As Variant &apos; A single DataArray item
  922. Dim sAlign As String &apos; Column&apos;s horizontal alignments (single chars: L, C, R, space)
  923. Dim lAlign As Long &apos; com.sun.star.style.HorizontalAlignment.XXX
  924. Dim i As Long, j As Long, k As Long
  925. Const cstRowHdrWidth = 12 &apos; Estimated width of the row header
  926. Const cstThisSub = &quot;SFDialogs.DialogControl.SetTableData&quot;
  927. Const cstSubArgs = &quot;DataArray, [Widths=Array(1)], [Alignments=&quot;&quot;&quot;&quot;]&quot;
  928. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  929. bData = False
  930. Check:
  931. If IsMissing(Widths) Or IsEmpty(Widths) Then Widths = Array(1)
  932. If IsMissing(Alignments) Or IsEmpty(Alignments) Then Alignments = &quot;&quot;
  933. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  934. If _ControlType &lt;&gt; CTLTABLECONTROL Then GoTo CatchType
  935. If Not ScriptForge.SF_Utils._ValidateArray(DataArray, &quot;DataArray&quot;) Then GoTo Catch &apos; Dimensions are checked below
  936. If Not ScriptForge.SF_Utils._ValidateArray(Widths, &quot;Widths&quot;, 1, ScriptForge.V_NUMERIC, True) Then GoTo Catch
  937. If Not ScriptForge.SF_Utils._Validate(Alignments, &quot;Alignments&quot;, V_STRING) Then GoTo Catch
  938. End If
  939. Try:
  940. &apos; Erase any pre-existing data and columns
  941. _GridDataModel.removeAllRows()
  942. For i = _GridColumnModel.ColumnCount - 1 To 0 Step -1
  943. _GridColumnModel.removeColumn(i)
  944. Next i
  945. &apos; LBounds, UBounds - Basic or Pytho
  946. iDims = ScriptForge.SF_Array.CountDims(DataArray)
  947. Select Case iDims
  948. Case -1, 0 : GoTo Catch
  949. Case 1 &apos; Called probably from Python
  950. lMin1 = LBound(DataArray, 1) : lMax1 = UBound(DataArray, 1)
  951. If Not IsArray(DataArray(0)) Then GoTo Catch
  952. If UBound(DataArray(0)) &lt; LBound(DataArray(0)) Then GoTo Catch &apos; No columns
  953. lMin2 = LBound(DataArray(0)) : lMax2 = UBound(DataArray(0))
  954. Case 2
  955. lMin1 = LBound(DataArray, 1) : lMax1 = UBound(DataArray, 1)
  956. lMin2 = LBound(DataArray, 2) : lMax2 = UBound(DataArray, 2)
  957. Case Else : GoTo Catch
  958. End Select
  959. &apos; Extract headers from data array
  960. lMinW = LBound(Widths) : lMaxW = UBound(Widths)
  961. With _ControlModel
  962. If .ShowColumnHeader Then
  963. lMinRow = lMin1 + 1
  964. If iDims = 1 Then
  965. vColHeaders = DataArray(lMin1)
  966. Else
  967. vColHeaders = ScriptForge.SF_Array.ExtractRow(DataArray, lMin1)
  968. End If
  969. Else
  970. lMinRow = lMin1
  971. vColHeaders = Array()
  972. End If
  973. If .ShowRowHeader Then
  974. lMinCol = lMin2 + 1
  975. If iDims = 1 Then
  976. vRowHeaders = Array()
  977. ReDim vRowHeaders(lMin1 To lMax1)
  978. For i = lMin1 To lMax1
  979. vRowHeaders(i) = DataArray(i)(lMin2)
  980. Next i
  981. Else
  982. vRowHeaders = ScriptForge.SF_Array.ExtractColumn(DataArray, lMin2)
  983. End If
  984. Else
  985. lMinCol = lMin2
  986. vRowHeaders = Array()
  987. End If
  988. End With
  989. &apos; Create the columns
  990. For j = lMinCol To lMax2
  991. Set oColumn = _GridColumnModel.createColumn()
  992. If _ControlModel.ShowColumnHeader Then oColumn.Title = vColHeaders(j)
  993. _GridColumnModel.addColumn(oColumn)
  994. Next j
  995. &apos; Size the columns. Column sizing cannot be done before all the columns are added
  996. If lMaxW &gt;= lMinW Then &apos; There must be at least 1 width given as argument
  997. &apos; Size the columns proportionally with their relative widths
  998. dRelativeWidth = 0.0
  999. i = lMinW - 1
  1000. &apos; Compute the sum of the relative widths
  1001. For j = 0 To lMax2 - lMinCol
  1002. i = i + 1
  1003. If i &gt;= lMinW And i &lt;= lMaxW Then dRelativeWidth = dRelativeWidth + Widths(i) Else dRelativeWidth = dRelativeWidth + Widths(lMaxW)
  1004. Next j
  1005. &apos; Set absolute widths
  1006. If dRelativeWidth &gt; 0.0 Then dWidthFactor = CDbl((_ControlModel.Width - cstRowHdrWidth) / dRelativeWidth) Else dWidthFactor = 1.0
  1007. i = lMinW - 1
  1008. For j = 0 To lMax2 - lMinCol
  1009. i = i + 1
  1010. If i &gt;= lMinW And i &lt;= lMaxW Then dWidth = CDbl(Widths(i)) Else dWidth = CDbl(Widths(lMaxW))
  1011. _GridColumnModel.Columns(j).ColumnWidth = CLng(dWidthFactor * dWidth)
  1012. Next j
  1013. Else
  1014. &apos; Size all columns evenly
  1015. For j = 0 To lMax2 - lMinCol
  1016. _GridColumnModel.Columns(j).ColumnWidth = (_ControlModel.Width - cstRowHdrWidth) / (lMax2 - lMonCol + 1)
  1017. Next j
  1018. End If
  1019. &apos; Initialize the column alignment
  1020. If Len(Alignments) &gt;= lMax2 - lMinCol + 1 Then sAlign = Alignments Else sAlign = Alignments &amp; Space(lMax2 - lMinCol + 1 - Len(Alignments))
  1021. &apos; Feed the table with data and define/confirm the column alignment
  1022. vDataRow = Array()
  1023. For i = lMinRow To lMax1
  1024. ReDim vDataRow(0 To lMax2 - lMinCol)
  1025. For j = lMinCol To lMax2
  1026. If iDims = 1 Then vDataItem = DataArray(i)(j) Else vDataItem = DataArray(i, j)
  1027. If VarType(vDataItem) = V_STRING Then
  1028. ElseIf ScriptForge.SF_Utils._VarTypeExt(vDataItem) = ScriptForge.V_NUMERIC Then
  1029. Else
  1030. vDataItem = ScriptForge.SF_String.Represent(vDataItem)
  1031. End If
  1032. vDataRow(j - lMinCol) = vDataItem
  1033. &apos; Store alignment while processing the first row of the array
  1034. If i = lMinRow Then
  1035. k = j - lMinCol + 1
  1036. If Mid(sAlign, k, 1) = &quot; &quot; Then Mid(sAlign, k, 1) = Iif(VarType(vDataItem) = V_STRING, &quot;L&quot;, &quot;R&quot;)
  1037. End If
  1038. Next j
  1039. If _ControlModel.ShowRowHeader Then sRowHeader = vRowHeaders(i) Else sRowHeader = &quot;&quot;
  1040. _GridDataModel.addRow(sRowHeader, vDataRow)
  1041. Next i
  1042. &apos; Determine alignments of each column
  1043. For j = 0 To lMax2 - lMinCol
  1044. Select Case Mid(sAlign, j + 1, 1)
  1045. Case &quot;L&quot;, &quot; &quot; : lAlign = com.sun.star.style.HorizontalAlignment.LEFT
  1046. Case &quot;R&quot; : lAlign = com.sun.star.style.HorizontalAlignment.RIGHT
  1047. Case &quot;C&quot; : lAlign = com.sun.star.style.HorizontalAlignment.CENTER
  1048. Case Else
  1049. End Select
  1050. _GridColumnModel.Columns(j).HorizontalAlign = lAlign
  1051. Next j
  1052. bData = True
  1053. Finally:
  1054. SetTableData = bData
  1055. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  1056. Exit Function
  1057. Catch:
  1058. GoTo Finally
  1059. CatchType:
  1060. ScriptForge.SF_Exception.RaiseFatal(CONTROLTYPEERROR, _Name, _DialogName, _ControlType, &quot;SetTableData&quot;)
  1061. GoTo Finally
  1062. End Function &apos; SFDialogs.SF_DialogControl.SetTableData
  1063. REM -----------------------------------------------------------------------------
  1064. Public Function WriteLine(Optional ByVal Line As Variant) As Boolean
  1065. &apos;&apos;&apos; Add a new line to a multiline TextField control
  1066. &apos;&apos;&apos; Args:
  1067. &apos;&apos;&apos; Line: (default = &quot;&quot;) the line to insert at the end of the text box
  1068. &apos;&apos;&apos; a newline character will be inserted before the line, if relevant
  1069. &apos;&apos;&apos; Returns:
  1070. &apos;&apos;&apos; True if insertion is successful
  1071. &apos;&apos;&apos; Exceptions
  1072. &apos;&apos;&apos; TEXTFIELDERROR Method applicable on multiline text fields only
  1073. &apos;&apos;&apos; Example:
  1074. &apos;&apos;&apos; Dim oDlg As Object, oControl As Object
  1075. &apos;&apos;&apos; Set oDlg = CreateScriptService(,, &quot;myControl&quot;) &apos; Control stored in current document&apos;s standard library
  1076. &apos;&apos;&apos; Set oControl = oDlg.Controls(&quot;thisControl&quot;)
  1077. &apos;&apos;&apos; oControl.WriteLine(&quot;a new line&quot;)
  1078. Dim bWriteLine As Boolean &apos; Return value
  1079. Dim lTextLength As Long &apos; Actual length of text in box
  1080. Dim oSelection As New com.sun.star.awt.Selection
  1081. Dim sNewLine As String &apos; Newline character(s)
  1082. Const cstThisSub = &quot;SFDialogs.DialogControl.WriteLine&quot;
  1083. Const cstSubArgs = &quot;[Line=&quot;&quot;&quot;&quot;]&quot;
  1084. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  1085. bWriteLine = False
  1086. Check:
  1087. If IsMissing(Line) Or IsEmpty(Line) Then Line = &quot;&quot;
  1088. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  1089. If Not [_Parent]._IsStillAlive() Then GoTo Finally
  1090. If Not ScriptForge.SF_Utils._Validate(Line, &quot;Line&quot;, V_STRING) Then GoTo Finally
  1091. End If
  1092. If ControlType &lt;&gt; CTLTEXTFIELD Then GoTo CatchField
  1093. If _ControlModel.MultiLine = False Then GoTo CatchField
  1094. Try:
  1095. _ControlModel.HardLineBreaks = True
  1096. sNewLine = ScriptForge.SF_String.sfNEWLINE
  1097. With _ControlView
  1098. lTextLength = Len(.getText())
  1099. If lTextLength = 0 Then &apos; Text field is still empty
  1100. oSelection.Min = 0 : oSelection.Max = 0
  1101. .setText(Line)
  1102. Else &apos; Put cursor at the end of the actual text
  1103. oSelection.Min = lTextLength : oSelection.Max = lTextLength
  1104. .insertText(oSelection, sNewLine &amp; Line)
  1105. End If
  1106. &apos; Put the cursor at the end of the inserted text
  1107. oSelection.Max = oSelection.Max + Len(sNewLine) + Len(Line)
  1108. oSelection.Min = oSelection.Max
  1109. .setSelection(oSelection)
  1110. End With
  1111. bWriteLine = True
  1112. Finally:
  1113. WriteLine = bWriteLine
  1114. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  1115. Exit Function
  1116. Catch:
  1117. GoTo Finally
  1118. CatchField:
  1119. ScriptForge.SF_Exception.RaiseFatal(TEXTFIELDERROR, _Name, _DialogName)
  1120. GoTo Finally
  1121. End Function &apos; SFControls.SF_DialogControl.WriteLine
  1122. REM =========================================================== PRIVATE FUNCTIONS
  1123. REM -----------------------------------------------------------------------------
  1124. Private Function _FindNode(ByRef poNode As Object _
  1125. , ByVal psDisplayValue As String _
  1126. , ByRef pvDataValue As Variant _
  1127. , ByVal pbCaseSensitive As Boolean _
  1128. ) As Object
  1129. &apos;&apos;&apos; Traverses the tree and find recursively, starting from the root, a node meeting some criteria
  1130. &apos;&apos;&apos; Either (1 match is enough):
  1131. &apos;&apos;&apos; having its DisplayValue like psDisplayValue
  1132. &apos;&apos;&apos; having its DataValue = pvDataValue
  1133. &apos;&apos;&apos; Comparisons may be or not case-sensitive
  1134. &apos;&apos;&apos; The first matching occurrence is returned
  1135. &apos;&apos;&apos; Args:
  1136. &apos;&apos;&apos; poNode: the current node, the root at 1st call
  1137. &apos;&apos;&apos; psDisplayValue: the pattern to be matched
  1138. &apos;&apos;&apos; pvDataValue: a string, a numeric value or a date or Empty (if not applicable)
  1139. &apos;&apos;&apos; pbCaseSensitive: applicable on both criteria
  1140. &apos;&apos;&apos; Returns:
  1141. &apos;&apos;&apos; The found node of type com.sun.star.awt.tree.XMutableTreeNode
  1142. Dim oChild As Object &apos; Child node com.sun.star.awt.tree.XMutableTreeNode
  1143. Dim oFind As Object &apos; Found node com.sun.star.awt.tree.XMutableTreeNode
  1144. Dim lChildCount As Long &apos; Number of children of a node
  1145. Dim bFound As Boolean &apos; True when node found
  1146. Dim i As Long
  1147. Set _FindNode = Nothing
  1148. On Local Error GoTo Finally &apos; Better not found than raise an error
  1149. Check:
  1150. &apos; Does the actual node match the criteria ?
  1151. bFound = False
  1152. If Len(psDisplayValue) &gt; 0 Then
  1153. bFound = ScriptForge.SF_String.IsLike(poNode.DisplayValue, psDisplayValue, pbCaseSensitive)
  1154. End If
  1155. If Not bFound And Not IsEmpty(poNode.DataValue) Then
  1156. If Not IsEmpty(pvdataValue) Then bFound = ( ScriptForge.SF_Array._ValCompare(poNode.DataValue, pvDataB-Value, pbCaseSensitive) = 0 )
  1157. End If
  1158. If bFound Then
  1159. Set _FindNode = poNode
  1160. Exit Function
  1161. End If
  1162. Try:
  1163. &apos; Explore sub-branches
  1164. lChildCount = poNode.getChildCount
  1165. If lChildCount &gt; 0 Then
  1166. For i = 0 To lChildCount - 1
  1167. Set oChild = poNode.getChildAt(i)
  1168. Set oFind = _FindNode(oChild, psDisplayValue, pvDataValue, pbCaseSensitive) &apos; Recursive call
  1169. If Not IsNull(oFind) Then
  1170. Set _FindNode = oFind
  1171. Exit For
  1172. End If
  1173. Next i
  1174. End If
  1175. Finally:
  1176. Exit Function
  1177. End Function &apos; SFDialogs.SF_DialogControl._FindNode
  1178. REM -----------------------------------------------------------------------------
  1179. Private Function _FormatsList() As Variant
  1180. &apos;&apos;&apos; Return the allowed format entries as a zero-based array for Date and Time control types
  1181. Dim vFormats() As Variant &apos; Return value
  1182. Select Case _ControlType
  1183. Case CTLDATEFIELD
  1184. vFormats = Array( _
  1185. &quot;Standard (short)&quot; _
  1186. , &quot;Standard (short YY)&quot; _
  1187. , &quot;Standard (short YYYY)&quot; _
  1188. , &quot;Standard (long)&quot; _
  1189. , &quot;DD/MM/YY&quot; _
  1190. , &quot;MM/DD/YY&quot; _
  1191. , &quot;YY/MM/DD&quot; _
  1192. , &quot;DD/MM/YYYY&quot; _
  1193. , &quot;MM/DD/YYYY&quot; _
  1194. , &quot;YYYY/MM/DD&quot; _
  1195. , &quot;YY-MM-DD&quot; _
  1196. , &quot;YYYY-MM-DD&quot; _
  1197. )
  1198. Case CTLTIMEFIELD
  1199. vFormats = Array( _
  1200. &quot;24h short&quot; _
  1201. , &quot;24h long&quot; _
  1202. , &quot;12h short&quot; _
  1203. , &quot;12h long&quot; _
  1204. )
  1205. Case Else
  1206. vFormats = Array()
  1207. End Select
  1208. _FormatsList = vFormats
  1209. End Function &apos; SFDialogs.SF_DialogControl._FormatsList
  1210. REM -----------------------------------------------------------------------------
  1211. Public Function _GetEventName(ByVal psProperty As String) As String
  1212. &apos;&apos;&apos; Return the LO internal event name derived from the SF property name
  1213. &apos;&apos;&apos; The SF property name is not case sensitive, while the LO name is case-sensitive
  1214. &apos; Corrects the typo on ErrorOccur(r?)ed, if necessary
  1215. Dim vProperties As Variant &apos; Array of class properties
  1216. Dim sProperty As String &apos; Correctly cased property name
  1217. vProperties = Properties()
  1218. sProperty = vProperties(ScriptForge.SF_Array.IndexOf(vProperties, psProperty, SortOrder := &quot;ASC&quot;))
  1219. _GetEventName = LCase(Mid(sProperty, 3, 1)) &amp; Right(sProperty, Len(sProperty) - 3)
  1220. End Function &apos; SFDialogs.SF_DialogControl._GetEventName
  1221. REM -----------------------------------------------------------------------------
  1222. Private Function _GetListener(ByVal psEventName As String) As String
  1223. &apos;&apos;&apos; Getting/Setting macros triggered by events requires a Listener-EventName pair
  1224. &apos;&apos;&apos; Return the X...Listener corresponding with the event name in argument
  1225. Select Case UCase(psEventName)
  1226. Case UCase(&quot;OnActionPerformed&quot;)
  1227. _GetListener = &quot;XActionListener&quot;
  1228. Case UCase(&quot;OnAdjustmentValueChanged&quot;)
  1229. _GetListener = &quot;XAdjustmentListener&quot;
  1230. Case UCase(&quot;OnFocusGained&quot;), UCase(&quot;OnFocusLost&quot;)
  1231. _GetListener = &quot;XFocusListener&quot;
  1232. Case UCase(&quot;OnItemStateChanged&quot;)
  1233. _GetListener = &quot;XItemListener&quot;
  1234. Case UCase(&quot;OnKeyPressed&quot;), UCase(&quot;OnKeyReleased&quot;)
  1235. _GetListener = &quot;XKeyListener&quot;
  1236. Case UCase(&quot;OnMouseDragged&quot;), UCase(&quot;OnMouseMoved&quot;)
  1237. _GetListener = &quot;XMouseMotionListener&quot;
  1238. Case UCase(&quot;OnMouseEntered&quot;), UCase(&quot;OnMouseExited&quot;), UCase(&quot;OnMousePressed&quot;), UCase(&quot;OnMouseReleased&quot;)
  1239. _GetListener = &quot;XMouseListener&quot;
  1240. Case UCase(&quot;OnTextChanged&quot;)
  1241. _GetListener = &quot;XTextListener&quot;
  1242. Case Else
  1243. _GetListener = &quot;&quot;
  1244. End Select
  1245. End Function &apos; SFDialogs.SF_DialogControl._GetListener
  1246. REM -----------------------------------------------------------------------------
  1247. Public Sub _Initialize()
  1248. &apos;&apos;&apos; Complete the object creation process:
  1249. &apos;&apos;&apos; - Initialization of private members
  1250. &apos;&apos;&apos; - Collection of specific attributes
  1251. &apos;&apos;&apos; - synchronization with parent dialog instance
  1252. Dim vServiceName As Variant &apos; Split service name
  1253. Dim sType As String &apos; Last component of service name
  1254. Try:
  1255. _ImplementationName = _ControlModel.getImplementationName()
  1256. &apos; Identify the control type
  1257. vServiceName = Split(_ControlModel.getServiceName(), &quot;.&quot;)
  1258. sType = vServiceName(UBound(vServiceName))
  1259. Select Case sType
  1260. Case &quot;UnoControlSpinButtonModel&quot;
  1261. _ControlType = &quot;&quot; &apos; Not supported
  1262. Case &quot;Edit&quot; : _ControlType = CTLTEXTFIELD
  1263. Case &quot;TreeControlModel&quot;
  1264. &apos; Initialize the data model
  1265. _ControlType = CTLTREECONTROL
  1266. Set _ControlModel.DataModel = CreateUnoService(&quot;com.sun.star.awt.tree.MutableTreeDataModel&quot;)
  1267. Set _TreeDataModel = _ControlModel.DataModel
  1268. Case &quot;UnoControlGridModel&quot;
  1269. _ControlType = CTLTABLECONTROL
  1270. Set _GridColumnModel = _ControlModel.ColumnModel
  1271. Set _GridDataModel = _ControlModel.GridDataModel
  1272. Case Else : _ControlType = sType
  1273. End Select
  1274. &apos; Store the SF_DialogControl object in the parent cache
  1275. Set _Parent._ControlCache(_IndexOfNames) = [Me]
  1276. Finally:
  1277. Exit Sub
  1278. End Sub &apos; SFDialogs.SF_DialogControl._Initialize
  1279. REM -----------------------------------------------------------------------------
  1280. Private Function _PropertyGet(Optional ByVal psProperty As String _
  1281. , Optional ByVal pvDefault As Variant _
  1282. ) As Variant
  1283. &apos;&apos;&apos; Return the value of the named property
  1284. &apos;&apos;&apos; Args:
  1285. &apos;&apos;&apos; psProperty: the name of the property
  1286. &apos;&apos;&apos; pvDefault: the value returned when the property is not applicable on the control&apos;s type
  1287. &apos;&apos;&apos; Getting a non-existing property for a specific control type should
  1288. &apos;&apos;&apos; not generate an error to not disrupt the Basic IDE debugger
  1289. Dim vGet As Variant &apos; Return value
  1290. Static oSession As Object &apos; Alias of SF_Session
  1291. Dim vSelection As Variant &apos; Alias of Model.SelectedItems or Model.Selection
  1292. Dim vList As Variant &apos; Alias of Model.StringItemList
  1293. Dim lIndex As Long &apos; Index in StringItemList
  1294. Dim sItem As String &apos; A single item
  1295. Dim vDate As Variant &apos; com.sun.star.util.Date or com.sun.star.util.Time
  1296. Dim vValues As Variant &apos; Array of listbox values
  1297. Dim oControlEvents As Object &apos; com.sun.star.container.XNameContainer
  1298. Dim sEventName As String &apos; Internal event name
  1299. Dim i As Long
  1300. Dim cstThisSub As String
  1301. Const cstSubArgs = &quot;&quot;
  1302. cstThisSub = &quot;SFDialogs.DialogControl.get&quot; &amp; psProperty
  1303. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  1304. ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
  1305. If Not [_Parent]._IsStillAlive() Then GoTo Finally
  1306. If IsMissing(pvDefault) Then pvDefault = Null
  1307. _PropertyGet = pvDefault
  1308. If IsNull(oSession) Then Set oSession = ScriptForge.SF_Services.CreateScriptService(&quot;Session&quot;)
  1309. Select Case UCase(psProperty)
  1310. Case UCase(&quot;Cancel&quot;)
  1311. Select Case _ControlType
  1312. Case CTLBUTTON
  1313. If oSession.HasUNOProperty(_ControlModel, &quot;PushButtonType&quot;) Then _PropertyGet = ( _ControlModel.PushButtonType = com.sun.star.awt.PushButtonType.CANCEL )
  1314. Case Else : GoTo CatchType
  1315. End Select
  1316. Case UCase(&quot;Caption&quot;)
  1317. Select Case _ControlType
  1318. Case CTLBUTTON, CTLCHECKBOX, CTLFIXEDLINE, CTLFIXEDTEXT, CTLGROUPBOX, CTLRADIOBUTTON
  1319. If oSession.HasUNOProperty(_ControlModel, &quot;Label&quot;) Then _PropertyGet = _ControlModel.Label
  1320. Case Else : GoTo CatchType
  1321. End Select
  1322. Case UCase(&quot;ControlType&quot;)
  1323. _PropertyGet = _ControlType
  1324. Case UCase(&quot;CurrentNode&quot;)
  1325. Select Case _ControlType
  1326. Case CTLTREECONTROL
  1327. If oSession.HasUNOMethod(_ControlView, &quot;getSelection&quot;) Then
  1328. _PropertyGet = Empty
  1329. If _ControlModel.SelectionType &lt;&gt; com.sun.star.view.SelectionType.NONE Then
  1330. vSelection = _ControlView.getSelection()
  1331. If IsArray(vSelection) Then
  1332. If UBound(vSelection) &gt;= 0 Then Set _PropertyGet = vSelection(0)
  1333. Else
  1334. Set _PropertyGet = vSelection
  1335. End If
  1336. End If
  1337. End If
  1338. Case Else : GoTo CatchType
  1339. End Select
  1340. Case UCase(&quot;Default&quot;)
  1341. Select Case _ControlType
  1342. Case CTLBUTTON
  1343. If oSession.HasUNOProperty(_ControlModel, &quot;DefaultButton&quot;) Then _PropertyGet = _ControlModel.DefaultButton
  1344. Case Else : GoTo CatchType
  1345. End Select
  1346. Case UCase(&quot;Enabled&quot;)
  1347. If oSession.HasUnoProperty(_ControlModel, &quot;Enabled&quot;) Then _PropertyGet = _ControlModel.Enabled
  1348. Case UCase(&quot;Format&quot;)
  1349. Select Case _ControlType
  1350. Case CTLDATEFIELD
  1351. If oSession.HasUNOProperty(_ControlModel, &quot;DateFormat&quot;) Then _PropertyGet = _FormatsList()(_ControlModel.DateFormat)
  1352. Case CTLTIMEFIELD
  1353. If oSession.HasUNOProperty(_ControlModel, &quot;TimeFormat&quot;) Then _PropertyGet = _FormatsList()(_ControlModel.TimeFormat)
  1354. Case CTLFORMATTEDFIELD
  1355. If oSession.HasUNOProperty(_ControlModel, &quot;FormatsSupplier&quot;) And oSession.HasUNOProperty(_ControlModel, &quot;FormatKey&quot;) Then
  1356. _PropertyGet = _ControlModel.FormatsSupplier.getNumberFormats.getByKey(_ControlModel.FormatKey).FormatString
  1357. End If
  1358. Case Else : GoTo CatchType
  1359. End Select
  1360. Case UCase(&quot;ListCount&quot;)
  1361. Select Case _ControlType
  1362. Case CTLCOMBOBOX, CTLLISTBOX
  1363. If oSession.HasUNOProperty(_ControlModel, &quot;StringItemList&quot;) Then _PropertyGet = UBound(_ControlModel.StringItemList) + 1
  1364. Case CTLTABLECONTROL &apos; Returns zero when no table data yet
  1365. If oSession.HasUNOProperty(_GridDataModel, &quot;RowCount&quot;) Then _PropertyGet = _GridDataModel.RowCount
  1366. Case Else : GoTo CatchType
  1367. End Select
  1368. Case UCase(&quot;ListIndex&quot;)
  1369. Select Case _ControlType
  1370. Case CTLCOMBOBOX
  1371. _PropertyGet = -1 &apos; Not found, multiselection
  1372. If oSession.HasUNOProperty(_ControlModel, &quot;Text&quot;) And oSession.HasUNOProperty(_ControlModel, &quot;StringItemList&quot;) Then
  1373. _PropertyGet = ScriptForge.SF_Array.IndexOf(_ControlModel.StringItemList, _ControlModel.Text, CaseSensitive := True)
  1374. End If
  1375. Case CTLLISTBOX
  1376. _PropertyGet = -1 &apos; Not found, multiselection
  1377. If oSession.HasUNOProperty(_ControlModel, &quot;SelectedItems&quot;) And oSession.HasUNOProperty(_ControlModel, &quot;StringItemList&quot;) Then
  1378. vSelection = _ControlModel.SelectedItems
  1379. If UBound(vSelection) &gt;= 0 Then _PropertyGet = vSelection(0)
  1380. End If
  1381. Case CTLTABLECONTROL
  1382. _PropertyGet = -1 &apos; No row selected, no data, multiselection
  1383. If oSession.HasUNOProperty(_ControlModel, &quot;SelectionModel&quot;) _
  1384. And oSession.HasUNOProperty(_ControlView, &quot;CurrentRow&quot;) Then
  1385. &apos; Other selection types (multi, range) not supported
  1386. If _ControlModel.SelectionModel = com.sun.star.view.SelectionType.SINGLE Then
  1387. lIndex = _ControlView.CurrentRow
  1388. If lIndex &lt; 0 And oSession.HasUNOProperty(_ControlView, &quot;SelectedRows&quot;) Then
  1389. If UBound(_ControlView.SelectedRows) &gt;= 0 Then lIndex = _ControlView.SelectedRows(0)
  1390. End If
  1391. _PropertyGet = lIndex
  1392. End If
  1393. End If
  1394. Case Else : GoTo CatchType
  1395. End Select
  1396. Case UCase(&quot;Locked&quot;)
  1397. Select Case _ControlType
  1398. Case CTLCOMBOBOX, CTLCURRENCYFIELD, CTLDATEFIELD, CTLFILECONTROL, CTLFORMATTEDFIELD, CTLLISTBOX _
  1399. , CTLNUMERICFIELD, CTLPATTERNFIELD, CTLTEXTFIELD, CTLTIMEFIELD
  1400. If oSession.HasUnoProperty(_ControlModel, &quot;ReadOnly&quot;) Then _PropertyGet = _ControlModel.ReadOnly
  1401. Case Else : GoTo CatchType
  1402. End Select
  1403. Case UCase(&quot;MultiSelect&quot;)
  1404. Select Case _ControlType
  1405. Case CTLLISTBOX
  1406. If oSession.HasUnoProperty(_ControlModel, &quot;MultiSelection&quot;) Then
  1407. _PropertyGet = _ControlModel.MultiSelection
  1408. ElseIf oSession.HasUnoProperty(_ControlModel, &quot;MultiSelectionSimpleMode&quot;) Then &apos; Not documented: gridcontrols only TBC ??
  1409. _PropertyGet = _ControlModel.MultiSelectionSimpleMode
  1410. End If
  1411. Case Else : GoTo CatchType
  1412. End Select
  1413. Case UCase(&quot;Name&quot;)
  1414. _PropertyGet = _Name
  1415. Case UCase(&quot;OnActionPerformed&quot;), UCase(&quot;OnAdjustmentValueChanged&quot;), UCase(&quot;OnFocusGained&quot;), UCase(&quot;OnFocusLost&quot;) _
  1416. , UCase(&quot;OnItemStateChanged&quot;), UCase(&quot;OnKeyPressed&quot;), UCase(&quot;OnKeyReleased&quot;) _
  1417. , UCase(&quot;OnMouseDragged&quot;), UCase(&quot;OnMouseEntered&quot;), UCase(&quot;OnMouseExited&quot;), UCase(&quot;OnMouseMoved&quot;) _
  1418. , UCase(&quot;OnMousePressed&quot;), UCase(&quot;OnMouseReleased&quot;), UCase(&quot;OnTextChanged&quot;)
  1419. Set oControlEvents = _ControlModel.getEvents()
  1420. sEventName = &quot;com.sun.star.awt.&quot; &amp; _GetListener(psProperty) &amp; &quot;::&quot; &amp; _GetEventName(psProperty)
  1421. If oControlEvents.hasByName(sEventName) Then
  1422. _PropertyGet = oControlEvents.getByName(sEventName).ScriptCode
  1423. Else
  1424. _PropertyGet = &quot;&quot;
  1425. End If
  1426. Case UCase(&quot;OnNodeExpanded&quot;)
  1427. Select Case _ControlType
  1428. Case CTLTREECONTROL
  1429. _PropertyGet = _OnNodeExpanded
  1430. Case Else : GoTo CatchType
  1431. End Select
  1432. Case UCase(&quot;OnNodeSelected&quot;)
  1433. Select Case _ControlType
  1434. Case CTLTREECONTROL
  1435. _PropertyGet = _OnNodeSelected
  1436. Case Else : GoTo CatchType
  1437. End Select
  1438. Case UCase(&quot;Page&quot;)
  1439. If oSession.HasUnoProperty(_ControlModel, &quot;Step&quot;) Then _PropertyGet = _ControlModel.Step
  1440. Case UCase(&quot;Parent&quot;)
  1441. Set _PropertyGet = [_Parent]
  1442. Case UCase(&quot;Picture&quot;)
  1443. Select Case _ControlType
  1444. Case CTLBUTTON, CTLIMAGECONTROL
  1445. If oSession.HasUnoProperty(_ControlModel, &quot;ImageURL&quot;) Then _PropertyGet = ScriptForge.SF_FileSystem._ConvertFromUrl(_ControlModel.ImageURL)
  1446. Case Else : GoTo CatchType
  1447. End Select
  1448. Case UCase(&quot;RootNode&quot;)
  1449. Select Case _ControlType
  1450. Case CTLTREECONTROL
  1451. _PropertyGet = _TreeDataModel.getRoot()
  1452. Case Else : GoTo CatchType
  1453. End Select
  1454. Case UCase(&quot;RowSource&quot;)
  1455. Select Case _ControlType
  1456. Case CTLCOMBOBOX, CTLLISTBOX
  1457. If oSession.HasUnoProperty(_ControlModel, &quot;StringItemList&quot;) Then
  1458. If IsArray(_ControlModel.StringItemList) Then _PropertyGet = _ControlModel.StringItemList Else _PropertyGet = Array(_ControlModel.StringItemList)
  1459. End If
  1460. Case Else : GoTo CatchType
  1461. End Select
  1462. Case UCase(&quot;Text&quot;)
  1463. Select Case _ControlType
  1464. Case CTLCOMBOBOX, CTLFILECONTROL, CTLFORMATTEDFIELD, CTLPATTERNFIELD, CTLTEXTFIELD
  1465. If oSession.HasUnoProperty(_ControlModel, &quot;Text&quot;) Then _PropertyGet = _ControlModel.Text
  1466. Case Else : GoTo CatchType
  1467. End Select
  1468. Case UCase(&quot;TipText&quot;)
  1469. If oSession.HasUnoProperty(_ControlModel, &quot;HelpText&quot;) Then _PropertyGet = _ControlModel.HelpText
  1470. Case UCase(&quot;TripleState&quot;)
  1471. Select Case _ControlType
  1472. Case CTLCHECKBOX
  1473. If oSession.HasUnoProperty(_ControlModel, &quot;TriState&quot;) Then _PropertyGet = _ControlModel.TriState
  1474. Case Else : GoTo CatchType
  1475. End Select
  1476. Case UCase(&quot;Value&quot;) &apos; Default values are set here by control type, not in the 2nd argument
  1477. vGet = pvDefault
  1478. Select Case _ControlType
  1479. Case CTLBUTTON &apos;Boolean, toggle buttons only
  1480. vGet = False
  1481. If oSession.HasUnoProperty(_ControlModel, &quot;Toggle&quot;) Then
  1482. If oSession.HasUnoProperty(_ControlModel, &quot;State&quot;) Then vGet = ( _ControlModel.State = 1 )
  1483. End If
  1484. Case CTLCHECKBOX &apos;0 = Not checked, 1 = Checked, 2 = Don&apos;t know
  1485. If oSession.HasUnoProperty(_ControlModel, &quot;State&quot;) Then vGet = _ControlModel.State Else vGet = 2
  1486. Case CTLCOMBOBOX, CTLFILECONTROL, CTLPATTERNFIELD, CTLTEXTFIELD &apos;String
  1487. If oSession.HasUnoProperty(_ControlModel, &quot;Text&quot;) Then vGet = _ControlModel.Text Else vGet = &quot;&quot;
  1488. Case CTLCURRENCYFIELD, CTLNUMERICFIELD &apos;Numeric
  1489. If oSession.HasUnoProperty(_ControlModel, &quot;Value&quot;) Then vGet = _ControlModel.Value Else vGet = 0
  1490. Case CTLDATEFIELD &apos;Date
  1491. vGet = CDate(1)
  1492. If oSession.HasUnoProperty(_ControlModel, &quot;Date&quot;) Then
  1493. If VarType(_ControlModel.Date) = ScriptForge.V_OBJECT Then &apos; com.sun.star.util.Date
  1494. Set vDate = _ControlModel.Date
  1495. vGet = DateSerial(vDate.Year, vDate.Month, vDate.Day)
  1496. End If
  1497. End If
  1498. Case CTLFORMATTEDFIELD &apos;String or numeric
  1499. If oSession.HasUnoProperty(_ControlModel, &quot;EffectiveValue&quot;) Then vGet = _ControlModel.EffectiveValue Else vGet = &quot;&quot;
  1500. Case CTLLISTBOX &apos;String or array of strings depending on MultiSelection
  1501. &apos; StringItemList is the list of the items displayed in the box
  1502. &apos; SelectedItems is the list of the indexes in StringItemList of the selected items
  1503. &apos; It can go beyond the limits of StringItemList
  1504. &apos; It can contain multiple values even if the listbox is not multiselect
  1505. If oSession.HasUnoProperty(_ControlModel, &quot;StringItemList&quot;) And oSession.HasUnoProperty(_ControlModel, &quot;SelectedItems&quot;) _
  1506. And oSession.HasUnoProperty(_ControlModel, &quot;MultiSelection&quot;) Then
  1507. vSelection = _ControlModel.SelectedItems
  1508. vList = _ControlModel.StringItemList
  1509. If _ControlModel.MultiSelection Then vValues = Array()
  1510. For i = 0 To UBound(vSelection)
  1511. lIndex = vSelection(i)
  1512. If lIndex &gt;= 0 And lIndex &lt;= UBound(vList) Then
  1513. If Not _ControlModel.MultiSelection Then
  1514. vValues = vList(lIndex)
  1515. Exit For
  1516. End If
  1517. vValues = ScriptForge.SF_Array.Append(vValues, vList(lIndex))
  1518. End If
  1519. Next i
  1520. vGet = vValues
  1521. Else
  1522. vGet = &quot;&quot;
  1523. End If
  1524. Case CTLPROGRESSBAR &apos;Numeric
  1525. If oSession.HasUnoProperty(_ControlModel, &quot;ProgressValue&quot;) Then vGet = _ControlModel.ProgressValue Else vGet = 0
  1526. Case CTLRADIOBUTTON &apos;Boolean
  1527. If oSession.HasUnoProperty(_ControlModel, &quot;State&quot;) Then vGet = ( _ControlModel.State = 1 ) Else vGet = False
  1528. Case CTLSCROLLBAR &apos;Numeric
  1529. If oSession.HasUnoProperty(_ControlModel, &quot;ScrollValue&quot;) Then vGet = _ControlModel.ScrollValue Else vGet = 0
  1530. Case CTLTABLECONTROL
  1531. vGet = Array() &apos; Default value when no row selected, no data, multiselection
  1532. If oSession.HasUNOProperty(_ControlModel, &quot;SelectionModel&quot;) _
  1533. And oSession.HasUNOProperty(_ControlView, &quot;CurrentRow&quot;) Then
  1534. &apos; Other selection types (multi, range) not supported
  1535. If _ControlModel.SelectionModel = com.sun.star.view.SelectionType.SINGLE Then
  1536. lIndex = _ControlView.CurrentRow
  1537. If lIndex &lt; 0 And oSession.HasUNOProperty(_ControlView, &quot;SelectedRows&quot;) Then
  1538. If UBound(_ControlView.SelectedRows) &gt;= 0 Then lIndex = _ControlView.SelectedRows(0)
  1539. End If
  1540. If lIndex &gt;= 0 Then vGet = _GridDataModel.getRowData(lIndex)
  1541. End If
  1542. End If
  1543. Case CTLTIMEFIELD
  1544. vGet = CDate(0)
  1545. If oSession.HasUnoProperty(_ControlModel, &quot;Time&quot;) Then
  1546. If VarType(_ControlModel.Time) = ScriptForge.V_OBJECT Then &apos; com.sun.star.Util.Time
  1547. Set vDate = _ControlModel.Time
  1548. vGet = TimeSerial(vDate.Hours, vDate.Minutes, vDate.Seconds)
  1549. End If
  1550. End If
  1551. Case Else : GoTo CatchType
  1552. End Select
  1553. _PropertyGet = vGet
  1554. Case UCase(&quot;Visible&quot;)
  1555. If oSession.HasUnoMethod(_ControlView, &quot;isVisible&quot;) Then _PropertyGet = CBool(_ControlView.isVisible())
  1556. Case UCase(&quot;XControlModel&quot;)
  1557. Set _PropertyGet = _ControlModel
  1558. Case UCase(&quot;XControlView&quot;)
  1559. Set _PropertyGet = _ControlView
  1560. Case UCase(&quot;XGridColumnModel&quot;)
  1561. Set _PropertyGet = _GridColumnModel
  1562. Case UCase(&quot;XGridDataModel&quot;)
  1563. Set _PropertyGet = _GridDataModel
  1564. Case UCase(&quot;XTreeDataModel&quot;)
  1565. Set _PropertyGet = _TreeDataModel
  1566. Case Else
  1567. _PropertyGet = Null
  1568. End Select
  1569. Finally:
  1570. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  1571. Exit Function
  1572. Catch:
  1573. GoTo Finally
  1574. CatchType:
  1575. GoTo Finally
  1576. End Function &apos; SFDialogs.SF_DialogControl._PropertyGet
  1577. REM -----------------------------------------------------------------------------
  1578. Private Function _PropertySet(Optional ByVal psProperty As String _
  1579. , Optional ByVal pvValue As Variant _
  1580. ) As Boolean
  1581. &apos;&apos;&apos; Set the new value of the named property
  1582. &apos;&apos;&apos; Args:
  1583. &apos;&apos;&apos; psProperty: the name of the property
  1584. &apos;&apos;&apos; pvValue: the new value of the given property
  1585. Dim bSet As Boolean &apos; Return value
  1586. Static oSession As Object &apos; Alias of SF_Session
  1587. Dim vSet As Variant &apos; Value to set in UNO model or view property
  1588. Dim vFormats As Variant &apos; Format property: output of _FormatsList()
  1589. Dim iFormat As Integer &apos; Format property: index in vFormats
  1590. Dim vSelection As Variant &apos; Alias of Model.SelectedItems
  1591. Dim vList As Variant &apos; Alias of Model.StringItemList
  1592. Dim lIndex As Long &apos; Index in StringItemList
  1593. Dim sItem As String &apos; A single item
  1594. Dim vCtlTypes As Variant &apos; Array of allowed control types
  1595. Dim i As Long
  1596. Dim cstThisSub As String
  1597. Const cstSubArgs = &quot;Value&quot;
  1598. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  1599. bSet = False
  1600. cstThisSub = &quot;SFDialogs.DialogControl.set&quot; &amp; psProperty
  1601. ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
  1602. If Not [_Parent]._IsStillAlive() Then GoTo Finally
  1603. If IsNull(oSession) Then Set oSession = ScriptForge.SF_Services.CreateScriptService(&quot;Session&quot;)
  1604. bSet = True
  1605. Select Case UCase(psProperty)
  1606. Case UCase(&quot;Cancel&quot;)
  1607. Select Case _ControlType
  1608. Case CTLBUTTON
  1609. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Cancel&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
  1610. If oSession.HasUNOProperty(_ControlModel, &quot;PushButtonType&quot;) Then
  1611. If pvValue Then vSet = com.sun.star.awt.PushButtonType.CANCEL Else vSet = com.sun.star.awt.PushButtonType.STANDARD
  1612. _ControlModel.PushButtonType = vSet
  1613. End If
  1614. Case Else : GoTo CatchType
  1615. End Select
  1616. Case UCase(&quot;Caption&quot;)
  1617. Select Case _ControlType
  1618. Case CTLBUTTON, CTLCHECKBOX, CTLFIXEDLINE, CTLFIXEDTEXT, CTLGROUPBOX, CTLRADIOBUTTON
  1619. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Caption&quot;, V_STRING) Then GoTo Finally
  1620. If oSession.HasUNOProperty(_ControlModel, &quot;Label&quot;) Then _ControlModel.Label = pvValue
  1621. Case Else : GoTo CatchType
  1622. End Select
  1623. Case UCase(&quot;CurrentNode&quot;)
  1624. Select Case _ControlType
  1625. Case CTLTREECONTROL
  1626. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Selection&quot;, ScriptForge.V_OBJECT) Then GoTo Finally
  1627. If oSession.UnoObjectType(pvValue) &lt;&gt; &quot;toolkit.MutableTreeNode&quot; Then GoTo CatchType
  1628. With _ControlView
  1629. .clearSelection()
  1630. If Not IsNull(pvValue) Then
  1631. .addSelection(pvValue)
  1632. &apos; Suspending temporarily the expansion listener avoids conflicts
  1633. If Len(_OnNodeExpanded) &gt; 0 Then _ControlView.removeTreeExpansionListener(_ExpandListener)
  1634. .makeNodeVisible(pvValue) &apos; Expand parent nodes and put node in the display area
  1635. If Len(_OnNodeExpanded) &gt; 0 Then _ControlView.addTreeExpansionListener(_ExpandListener)
  1636. End If
  1637. End With
  1638. Case Else : GoTo CatchType
  1639. End Select
  1640. Case UCase(&quot;Default&quot;)
  1641. Select Case _ControlType
  1642. Case CTLBUTTON
  1643. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Default&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
  1644. If oSession.HasUNOProperty(_ControlModel, &quot;DefaultButton&quot;) Then _ControlModel.DefaultButton = pvValue
  1645. Case Else : GoTo CatchType
  1646. End Select
  1647. Case UCase(&quot;Enabled&quot;)
  1648. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Enabled&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
  1649. If oSession.HasUnoProperty(_ControlModel, &quot;Enabled&quot;) Then _ControlModel.Enabled = pvValue
  1650. Case UCase(&quot;Format&quot;)
  1651. Select Case _ControlType
  1652. Case CTLDATEFIELD, CTLTIMEFIELD
  1653. vFormats = _FormatsList()
  1654. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Format&quot;, V_STRING, vFormats) Then GoTo Finally
  1655. iFormat = ScriptForge.SF_Array.IndexOf(vFormats, pvValue, CaseSensitive := False)
  1656. If oSession.HasUNOProperty(_ControlModel, &quot;DateFormat&quot;) Then
  1657. _ControlModel.DateFormat = iFormat
  1658. ElseIf oSession.HasUNOProperty(_ControlModel, &quot;TimeFormat&quot;) Then
  1659. _ControlModel.TimeFormat = iFormat
  1660. End If
  1661. Case Else : GoTo CatchType
  1662. End Select
  1663. Case UCase(&quot;ListIndex&quot;)
  1664. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;ListIndex&quot;, ScriptForge.V_NUMERIC) Then GoTo Finally
  1665. Select Case _ControlType
  1666. Case CTLCOMBOBOX
  1667. If oSession.HasUNOProperty(_ControlModel, &quot;Text&quot;) And oSession.HasUNOProperty(_ControlModel, &quot;StringItemList&quot;) Then
  1668. _ControlModel.Text = _ControlModel.StringItemList(CInt(pvValue))
  1669. End If
  1670. Case CTLLISTBOX
  1671. If oSession.HasUNOProperty(_ControlModel, &quot;SelectedItems&quot;) Then _ControlModel.SelectedItems = Array(CInt(pvValue))
  1672. Case CTLTABLECONTROL
  1673. If oSession.HasUNOProperty(_ControlModel, &quot;SelectionModel&quot;) _
  1674. And oSession.HasUNOMethod(_ControlView, &quot;selectRow&quot;) Then
  1675. &apos; Other selection types (multi, range) not supported
  1676. If _ControlModel.SelectionModel = com.sun.star.view.SelectionType.SINGLE _
  1677. And pvValue &gt;= 0 And pvValue &lt;= _GridDataModel.RowCount - 1 Then
  1678. _ControlView.selectRow(pvValue)
  1679. End If
  1680. End If
  1681. Case Else : GoTo CatchType
  1682. End Select
  1683. Case UCase(&quot;Locked&quot;)
  1684. Select Case _ControlType
  1685. Case CTLCOMBOBOX, CTLCURRENCYFIELD, CTLDATEFIELD, CTLFILECONTROL, CTLFORMATTEDFIELD, CTLLISTBOX _
  1686. , CTLNUMERICFIELD, CTLPATTERNFIELD, CTLTEXTFIELD, CTLTIMEFIELD
  1687. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Locked&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
  1688. If oSession.HasUnoProperty(_ControlModel, &quot;ReadOnly&quot;) Then _ControlModel.ReadOnly = pvValue
  1689. Case Else : GoTo CatchType
  1690. End Select
  1691. Case UCase(&quot;MultiSelect&quot;)
  1692. Select Case _ControlType
  1693. Case CTLLISTBOX
  1694. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;MultiSelect&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
  1695. If oSession.HasUnoProperty(_ControlModel, &quot;MultiSelection&quot;) Then _ControlModel.MultiSelection = pvValue
  1696. If oSession.HasUnoProperty(_ControlModel, &quot;MultiSelectionSimpleMode&quot;) Then _ControlModel.MultiSelectionSimpleMode = pvValue
  1697. If oSession.HasUnoProperty(_ControlModel, &quot;SelectedItems&quot;) Then
  1698. If Not pvValue And UBound(_ControlModel.SelectedItems) &gt; 0 Then &apos; Cancel selections when MultiSelect becomes False
  1699. lIndex = _ControlModel.SelectedItems(0)
  1700. _ControlModel.SelectedItems = Array(lIndex)
  1701. End If
  1702. End If
  1703. Case Else : GoTo CatchType
  1704. End Select
  1705. Case UCase(&quot;OnNodeExpanded&quot;)
  1706. Select Case _ControlType
  1707. Case CTLTREECONTROL
  1708. If Not ScriptForge.SF_Utils._Validate(pvValue, psProperty, V_STRING) Then GoTo Finally
  1709. &apos; If the listener was already set, then stop it
  1710. If Len(_OnNodeExpanded) &gt; 0 Then
  1711. _ControlView.removeTreeExpansionListener(_ExpandListener)
  1712. Set _ExpandListener = Nothing
  1713. _OnNodeExpanded = &quot;&quot;
  1714. End If
  1715. &apos; Setup a new fresh listener
  1716. If Len(pvValue) &gt; 0 Then
  1717. Set _ExpandListener = CreateUnoListener(&quot;_SFEXP_&quot;, &quot;com.sun.star.awt.tree.XTreeExpansionListener&quot;)
  1718. _ControlView.addTreeExpansionListener(_ExpandListener)
  1719. _OnNodeExpanded = pvValue
  1720. End If
  1721. Case Else : GoTo CatchType
  1722. End Select
  1723. Case UCase(&quot;OnNodeSelected&quot;)
  1724. Select Case _ControlType
  1725. Case CTLTREECONTROL
  1726. If Not ScriptForge.SF_Utils._Validate(pvValue, psProperty, V_STRING) Then GoTo Finally
  1727. &apos; If the listener was already set, then stop it
  1728. If Len(_OnNodeSelected) &gt; 0 Then
  1729. _ControlView.removeSelectionChangeListener(_SelectListener)
  1730. Set _SelectListener = Nothing
  1731. _OnNodeSelected = &quot;&quot;
  1732. End If
  1733. &apos; Setup a new fresh listener
  1734. If Len(pvValue) &gt; 0 Then
  1735. Set _SelectListener = CreateUnoListener(&quot;_SFSEL_&quot;, &quot;com.sun.star.view.XSelectionChangeListener&quot;)
  1736. _ControlView.addSelectionChangeListener(_SelectListener)
  1737. _OnNodeSelected = pvValue
  1738. End If
  1739. Case Else : GoTo CatchType
  1740. End Select
  1741. Case UCase(&quot;Page&quot;)
  1742. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Page&quot;, ScriptForge.V_NUMERIC) Then GoTo Finally
  1743. If oSession.HasUnoProperty(_ControlModel, &quot;Step&quot;) Then _ControlModel.Step = CLng(pvValue)
  1744. Case UCase(&quot;Picture&quot;)
  1745. Select Case _ControlType
  1746. Case CTLBUTTON, CTLIMAGECONTROL
  1747. If Not ScriptForge.SF_Utils._ValidateFile(pvValue, &quot;Picture&quot;) Then GoTo Finally
  1748. If oSession.HasUnoProperty(_ControlModel, &quot;ImageURL&quot;) Then _ControlModel.ImageURL = ScriptForge.SF_FileSystem._ConvertToUrl(pvValue)
  1749. Case Else : GoTo CatchType
  1750. End Select
  1751. Case UCase(&quot;RowSource&quot;)
  1752. Select Case _ControlType
  1753. Case CTLCOMBOBOX, CTLLISTBOX
  1754. If Not IsArray(pvValue) Then
  1755. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;RowSource&quot;, V_STRING) Then GoTo Finally
  1756. pvArray = Array(pvArray)
  1757. ElseIf Not ScriptForge.SF_Utils._ValidateArray(pvValue, &quot;RowSource&quot;, 1, V_STRING, True) Then
  1758. GoTo Finally
  1759. End If
  1760. If oSession.HasUnoProperty(_ControlModel, &quot;StringItemList&quot;) Then _ControlModel.StringItemList = pvValue
  1761. Case Else : GoTo CatchType
  1762. End Select
  1763. Case UCase(&quot;TipText&quot;)
  1764. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;TipText&quot;, V_STRING) Then GoTo Finally
  1765. If oSession.HasUnoProperty(_ControlModel, &quot;HelpText&quot;) Then _ControlModel.HelpText = pvValue
  1766. Case UCase(&quot;TripleState&quot;)
  1767. Select Case _ControlType
  1768. Case CTLCHECKBOX
  1769. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;TripleState&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
  1770. If oSession.HasUnoProperty(_ControlModel, &quot;TriState&quot;) Then _ControlModel.TriState = pvValue
  1771. Case Else : GoTo CatchType
  1772. End Select
  1773. Case UCase(&quot;Value&quot;)
  1774. Select Case _ControlType
  1775. Case CTLBUTTON &apos;Boolean, toggle buttons only
  1776. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Value&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
  1777. If oSession.HasUnoProperty(_ControlModel, &quot;Toggle&quot;) And oSession.HasUnoProperty(_ControlModel, &quot;State&quot;) Then
  1778. _ControlModel.State = Iif(pvValue, 1, 0)
  1779. End If
  1780. Case CTLCHECKBOX &apos;0 = Not checked, 1 = Checked, 2 = Don&apos;t know
  1781. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Value&quot;, Array(ScriptForge.V_BOOLEAN, ScriptForge.V_NUMERIC), Array(0, 1, 2, True, False)) Then GoTo Finally
  1782. If oSession.HasUnoProperty(_ControlModel, &quot;State&quot;) Then
  1783. If VarType(pvValue) = ScriptForge.V_BOOLEAN Then pvValue = Iif(pvValue, 1, 0)
  1784. _ControlModel.State = pvValue
  1785. End If
  1786. Case CTLCOMBOBOX, CTLFILECONTROL, CTLPATTERNFIELD, CTLTEXTFIELD &apos;String
  1787. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Value&quot;, V_STRING) Then GoTo Finally
  1788. If oSession.HasUnoProperty(_ControlModel, &quot;Text&quot;) Then _ControlModel.Text = pvValue
  1789. Case CTLCURRENCYFIELD, CTLNUMERICFIELD &apos;Numeric
  1790. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Value&quot;, ScriptForge.V_NUMERIC) Then GoTo Finally
  1791. If oSession.HasUnoProperty(_ControlModel, &quot;Value&quot;) Then _ControlModel.Value = pvValue
  1792. Case CTLDATEFIELD &apos;Date
  1793. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Value&quot;, V_DATE) Then GoTo Finally
  1794. If oSession.HasUnoProperty(_ControlModel, &quot;Date&quot;) Then
  1795. Set vSet = New com.sun.star.util.Date
  1796. vSet.Year = Year(pvValue)
  1797. vSet.Month = Month(pvValue)
  1798. vSet.Day = Day(pvValue)
  1799. _ControlModel.Date = vSet
  1800. End If
  1801. Case CTLFORMATTEDFIELD &apos;String or numeric
  1802. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Value&quot;, Array(V_STRING, ScriptForge.V_NUMERIC)) Then GoTo Finally
  1803. If oSession.HasUnoProperty(_ControlModel, &quot;EffectiveValue&quot;) Then _ControlModel.EffectiveValue = pvValue
  1804. Case CTLLISTBOX &apos;String or array of strings depending on MultiSelection
  1805. &apos; StringItemList is the list of the items displayed in the box
  1806. &apos; SelectedItems is the list of the indexes in StringItemList of the selected items
  1807. &apos; It can go beyond the limits of StringItemList
  1808. &apos; It can contain multiple values even if the listbox is not multiselect
  1809. If oSession.HasUnoProperty(_ControlModel, &quot;StringItemList&quot;) And oSession.HasUnoProperty(_ControlModel, &quot;SelectedItems&quot;) _
  1810. And oSession.HasUnoProperty(_ControlModel, &quot;MultiSelection&quot;) Then
  1811. vSelection = Array()
  1812. If _ControlModel.MultiSelection Then
  1813. If Not ScriptForge.SF_Utils._ValidateArray(pvValue, &quot;Value&quot;, 1, V_STRING, True) Then GoTo Finally
  1814. vList = _ControlModel.StringItemList
  1815. For i = LBound(pvValue) To UBound(pvValue)
  1816. sItem = pvValue(i)
  1817. lIndex = ScriptForge.SF_Array.IndexOf(vList, sItem)
  1818. If lIndex &gt;= 0 Then vSelection = ScriptForge.SF_Array.Append(vSelection, lIndex)
  1819. Next i
  1820. Else
  1821. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Value&quot;, V_STRING) Then GoTo Finally
  1822. lIndex = ScriptForge.SF_Array.IndexOf(_ControlModel.StringItemList, pvValue)
  1823. If lIndex &gt;= 0 Then vSelection = Array(lIndex)
  1824. End If
  1825. _ControlModel.SelectedItems = vSelection
  1826. End If
  1827. Case CTLPROGRESSBAR &apos;Numeric
  1828. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Value&quot;, ScriptForge.V_NUMERIC) Then GoTo Finally
  1829. If oSession.HasUnoProperty(_ControlModel, &quot;ProgressValueMin&quot;) Then
  1830. If pvValue &lt; _ControlModel.ProgressValueMin Then pvValue = _ControlModel.ProgressValueMin
  1831. End If
  1832. If oSession.HasUnoProperty(_ControlModel, &quot;ProgressValueMax&quot;) Then
  1833. If pvValue &gt; _ControlModel.ProgressValueMax Then pvValue = _ControlModel.ProgressValueMax
  1834. End If
  1835. If oSession.HasUnoProperty(_ControlModel, &quot;ProgressValue&quot;) Then _ControlModel.ProgressValue = pvValue
  1836. Case CTLRADIOBUTTON &apos;Boolean
  1837. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Value&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
  1838. If oSession.HasUnoProperty(_ControlModel, &quot;State&quot;) Then _ControlModel.State = Iif(pvValue, 1, 0)
  1839. Case CTLSCROLLBAR &apos;Numeric
  1840. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Value&quot;, ScriptForge.V_NUMERIC) Then GoTo Finally
  1841. If oSession.HasUnoProperty(_ControlModel, &quot;ScrollValueMin&quot;) Then
  1842. If pvValue &lt; _ControlModel.ScrollValueMin Then pvValue = _ControlModel.ScrollValueMin
  1843. End If
  1844. If oSession.HasUnoProperty(_ControlModel, &quot;ScrollValueMax&quot;) Then
  1845. If pvValue &gt; _ControlModel.ScrollValueMax Then pvValue = _ControlModel.ScrollValueMax
  1846. End If
  1847. If oSession.HasUnoProperty(_ControlModel, &quot;ScrollValue&quot;) Then _ControlModel.ScrollValue = pvValue
  1848. Case CTLTIMEFIELD
  1849. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Value&quot;, V_DATE) Then GoTo Finally
  1850. If oSession.HasUnoProperty(_ControlModel, &quot;Time&quot;) Then
  1851. Set vSet = New com.sun.star.util.Time
  1852. vSet.Hours = Hour(pvValue)
  1853. vSet.Minutes = Minute(pvValue)
  1854. vSet.Seconds = Second(pvValue)
  1855. _ControlModel.Time = vSet
  1856. End If
  1857. Case Else : GoTo CatchType
  1858. End Select
  1859. Case UCase(&quot;Visible&quot;)
  1860. If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Visible&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
  1861. If oSession.HasUnoMethod(_ControlView, &quot;setVisible&quot;) Then
  1862. If pvValue Then
  1863. If oSession.HasUnoProperty(_ControlModel, &quot;EnableVisible&quot;) Then _ControlModel.EnableVisible = True
  1864. End If
  1865. _ControlView.setVisible(pvValue)
  1866. End If
  1867. Case Else
  1868. bSet = False
  1869. End Select
  1870. Finally:
  1871. _PropertySet = bSet
  1872. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  1873. Exit Function
  1874. Catch:
  1875. GoTo Finally
  1876. CatchType:
  1877. ScriptForge.SF_Exception.RaiseFatal(CONTROLTYPEERROR, _Name, _DialogName, _ControlType, psProperty)
  1878. GoTo Finally
  1879. End Function &apos; SFDialogs.SF_DialogControl._PropertySet
  1880. REM -----------------------------------------------------------------------------
  1881. Private Function _Repr() As String
  1882. &apos;&apos;&apos; Convert the Model instance to a readable string, typically for debugging purposes (DebugPrint ...)
  1883. &apos;&apos;&apos; Args:
  1884. &apos;&apos;&apos; Return:
  1885. &apos;&apos;&apos; &quot;[DIALOGCONTROL]: Name, Type (dialogname)
  1886. _Repr = &quot;[DIALOGCONTROL]: &quot; &amp; _Name &amp; &quot;, &quot; &amp; _ControlType &amp; &quot; (&quot; &amp; _DialogName &amp; &quot;)&quot;
  1887. End Function &apos; SFDialogs.SF_DialogControl._Repr
  1888. REM ============================================ END OF SFDIALOGS.SF_DIALOGCONTROL
  1889. </script:module>