SF_Utils.xba 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967
  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_Utils" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
  4. REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
  5. REM === Full documentation is available on https://help.libreoffice.org/ ===
  6. REM =======================================================================================================================
  7. Option Explicit
  8. Option Private Module
  9. &apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
  10. &apos;&apos;&apos; SF_Utils
  11. &apos;&apos;&apos; ========
  12. &apos;&apos;&apos; FOR INTERNAL USE ONLY
  13. &apos;&apos;&apos; Groups all private functions used by the official modules
  14. &apos;&apos;&apos; Declares the Global variable _SF_
  15. &apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
  16. REM ===================================================================== GLOBALS
  17. Global _SF_ As Variant &apos; SF_Root (Basic) object)
  18. &apos;&apos;&apos; ScriptForge version
  19. Const SF_Version = &quot;7.1&quot;
  20. &apos;&apos;&apos; Standard symbolic names for VarTypes
  21. &apos; V_EMPTY = 0
  22. &apos; V_NULL = 1
  23. &apos; V_INTEGER = 2
  24. &apos; V_LONG = 3
  25. &apos; V_SINGLE = 4
  26. &apos; V_DOUBLE = 5
  27. &apos; V_CURRENCY = 6
  28. &apos; V_DATE = 7
  29. &apos; V_STRING = 8
  30. &apos;&apos;&apos; Additional symbolic names for VarTypes
  31. Global Const V_OBJECT = 9
  32. Global Const V_BOOLEAN = 11
  33. Global Const V_VARIANT = 12
  34. Global Const V_BYTE = 17
  35. Global Const V_USHORT = 18
  36. Global Const V_ULONG = 19
  37. Global Const V_BIGINT = 35
  38. Global Const V_DECIMAL = 37
  39. Global Const V_ARRAY = 8192
  40. Global Const V_NUMERIC = 99 &apos; Fictive VarType synonym of any numeric value
  41. REM ================================================================== EXCEPTIONS
  42. Const MISSINGARGERROR = &quot;MISSINGARGERROR&quot; &apos; A mandatory argument is missing
  43. Const ARGUMENTERROR = &quot;ARGUMENTERROR&quot; &apos; An argument does not pass the _Validate() validation
  44. Const ARRAYERROR = &quot;ARRAYERROR&quot; &apos; An argument does not pass the _ValidateArray() validation
  45. Const FILEERROR = &quot;FILEERROR&quot; &apos; An argument does not pass the _ValidateFile() validation
  46. REM =========================================pvA==================== PRIVATE METHODS
  47. REM -----------------------------------------------------------------------------
  48. Public Function _CDateToIso(pvDate As Variant) As Variant
  49. &apos;&apos;&apos; Returns a string representation of the given Basic date
  50. &apos;&apos;&apos; Dates as strings are essential in property values, where Basic dates are evil
  51. Dim sIsoDate As Variant &apos; Return value
  52. If VarType(pvDate) = V_DATE Then
  53. If Year(pvDate) &lt; 1900 Then &apos; Time only
  54. sIsoDate = Right(&quot;0&quot; &amp; Hour(pvDate), 2) &amp; &quot;:&quot; &amp; Right(&quot;0&quot; &amp; Minute(pvDate), 2) &amp; &quot;:&quot; &amp; Right(&quot;0&quot; &amp; Second(pvDate), 2)
  55. ElseIf Hour(pvDate) + Minute(pvDate) + Second(pvDate) = 0 Then &apos; Date only
  56. sIsoDate = Year(pvDate) &amp; &quot;-&quot; &amp; Right(&quot;0&quot; &amp; Month(pvDate), 2) &amp; &quot;-&quot; &amp; Right(&quot;0&quot; &amp; Day(pvDate), 2)
  57. Else
  58. sIsoDate = Year(pvDate) &amp; &quot;-&quot; &amp; Right(&quot;0&quot; &amp; Month(pvDate), 2) &amp; &quot;-&quot; &amp; Right(&quot;0&quot; &amp; Day(pvDate), 2) _
  59. &amp; &quot; &quot; &amp; Right(&quot;0&quot; &amp; Hour(pvDate), 2) &amp; &quot;:&quot; &amp; Right(&quot;0&quot; &amp; Minute(pvDate), 2) _
  60. &amp; &quot;:&quot; &amp; Right(&quot;0&quot; &amp; Second(pvDate), 2)
  61. End If
  62. Else
  63. sIsoDate = pvDate
  64. End If
  65. _CDateToIso = sIsoDate
  66. End Function &apos; ScriptForge.SF_Utils._CDateToIso
  67. REM -----------------------------------------------------------------------------
  68. Public Function _CDateToUnoDate(pvDate As Variant) As Variant
  69. &apos;&apos;&apos; Returns a UNO com.sun.star.util.DateTime/Date/Time object depending on the given date
  70. &apos;&apos;&apos; by using the appropriate CDateToUnoDateXxx builtin function
  71. &apos;&apos;&apos; UNO dates are essential in property values, where Basic dates are evil
  72. Dim vUnoDate As Variant &apos; Return value
  73. If VarType(pvDate) = V_DATE Then
  74. If Year(pvDate) &lt; 1900 Then
  75. vUnoDate = CDateToUnoTime(pvDate)
  76. ElseIf Hour(pvDate) + Minute(pvDate) + Second(pvDate) = 0 Then
  77. vUnoDate = CDateToUnoDate(pvDate)
  78. Else
  79. vUnoDate = CDateToUnoDateTime(pvDate)
  80. End If
  81. Else
  82. vUnoDate = pvDate
  83. End If
  84. _CDateToUnoDate = vUnoDate
  85. End Function &apos; ScriptForge.SF_Utils._CDateToUnoDate
  86. REM -----------------------------------------------------------------------------
  87. Public Function _CPropertyValue(ByRef pvValue As Variant) As Variant
  88. &apos;&apos;&apos; Set a value of a correct type in a com.sun.star.beans.PropertyValue
  89. &apos;&apos;&apos; Date BASIC variables give error. Change them to UNO types
  90. &apos;&apos;&apos; Empty arrays should be replaced by Null
  91. Dim vValue As Variant &apos; Return value
  92. If VarType(pvValue) = V_DATE Then
  93. vValue = SF_Utils._CDateToUnoDate(pvValue)
  94. ElseIf IsArray(pvValue) Then
  95. If UBound(pvValue, 1) &lt; LBound(pvValue, 1) Then vValue = Null Else vValue = pvValue
  96. Else
  97. vValue = pvValue
  98. End If
  99. _CPropertyValue() = vValue
  100. End Function &apos; ScriptForge.SF_Utils._CPropertyValue
  101. REM -----------------------------------------------------------------------------
  102. Public Function _CStrToDate(ByRef pvStr As String) As Date
  103. &apos;&apos;&apos; Attempt to convert the input string to a Date variable with the CDate builtin function
  104. &apos;&apos;&apos; If not successful, returns conventionally -1 (29/12/1899)
  105. &apos;&apos;&apos; Date patterns: YYYY-MM-DD, HH:MM:DD and YYYY-MM-DD HH:MM:DD
  106. Dim dDate As Date &apos; Return value
  107. Const cstNoDate = -1
  108. dDate = cstNoDate
  109. Try:
  110. On Local Error Resume Next
  111. dDate = CDate(pvStr)
  112. Finally:
  113. _CStrToDate = dDate
  114. Exit Function
  115. End Function &apos; ScriptForge.SF_Utils._CStrToDate
  116. REM -----------------------------------------------------------------------------
  117. Public Function _EnterFunction(ByVal psSub As String, Optional ByVal psArgs As String)
  118. &apos;&apos;&apos; Called on top of each public function
  119. &apos;&apos;&apos; Used to trace routine in/outs (debug mode)
  120. &apos;&apos;&apos; and to allow the explicit mention of the user call which caused an error
  121. &apos;&apos;&apos; Args:
  122. &apos;&apos;&apos; psSub = the called Sub/Function/Property, usually something like &quot;service.sub&quot;
  123. &apos;&apos;&apos; Return: True when psSub is called from a user script
  124. &apos;&apos;&apos; Used to bypass the validation of the arguments when unnecessary
  125. If IsEmpty(_SF_) Or IsNull(_SF_) Then SF_Utils._InitializeRoot() &apos; First use of ScriptForge during current LibO session
  126. If IsMissing(psArgs) Then psArgs = &quot;&quot;
  127. With _SF_
  128. If .StackLevel = 0 Then
  129. .MainFunction = psSub
  130. .MainFunctionArgs = psArgs
  131. _EnterFunction = True
  132. Else
  133. _EnterFunction = False
  134. End If
  135. .StackLevel = .StackLevel + 1
  136. If .DebugMode Then ._AddToConsole(&quot;==&gt; &quot; &amp; psSub &amp; &quot;(&quot; &amp; .StackLevel &amp; &quot;)&quot;)
  137. End With
  138. End Function &apos; ScriptForge.SF_Utils._EnterFunction
  139. REM -----------------------------------------------------------------------------
  140. Public Function _ErrorHandling(Optional ByVal pbErrorHandler As Boolean) As Boolean
  141. &apos;&apos;&apos; Error handling is normally ON and can be set OFF for debugging purposes
  142. &apos;&apos;&apos; Each user visible routine starts with a call to this function to enable/disable
  143. &apos;&apos;&apos; standard handling of internal errors
  144. &apos;&apos;&apos; Args:
  145. &apos;&apos;&apos; pbErrorHandler = if present, set its value
  146. &apos;&apos;&apos; Return: the current value of the error handler
  147. If IsEmpty(_SF_) Or IsNull(_SF_) Then SF_Utils._InitializeRoot() &apos; First use of ScriptForge during current LibO session
  148. If Not IsMissing(pbErrorHandler) Then _SF_.ErrorHandler = pbErrorHandler
  149. _ErrorHandling = _SF_.ErrorHandler
  150. End Function &apos; ScriptForge.SF_Utils._ErrorHandling
  151. REM -----------------------------------------------------------------------------
  152. Public Sub _ExitFunction(ByVal psSub As String)
  153. &apos;&apos;&apos; Called in the Finally block of each public function
  154. &apos;&apos;&apos; Manage ScriptForge internal aborts
  155. &apos;&apos;&apos; Resets MainFunction (root) when exiting the method called by a user script
  156. &apos;&apos;&apos; Used to trace routine in/outs (debug mode)
  157. &apos;&apos;&apos; Args:
  158. &apos;&apos;&apos; psSub = the called Sub/Function/Property, usually something like &quot;service.sub&quot;
  159. If IsEmpty(_SF_) Or IsNull(_SF_) Then SF_Utils._InitializeRoot() &apos; Useful only when current module has been recompiled
  160. With _SF_
  161. If Err &gt; 0 Then
  162. SF_Exception.RaiseAbort(psSub)
  163. End If
  164. If .StackLevel = 1 Then
  165. .MainFunction = &quot;&quot;
  166. .MainFunctionArgs = &quot;&quot;
  167. End If
  168. If .DebugMode Then ._AddToConsole(&quot;&lt;== &quot; &amp; psSub &amp; &quot;(&quot; &amp; .StackLevel &amp; &quot;)&quot;)
  169. If .StackLevel &gt; 0 Then .StackLevel = .StackLevel - 1
  170. End With
  171. End Sub &apos; ScriptForge.SF_Utils._ExitFunction
  172. REM -----------------------------------------------------------------------------
  173. Public Sub _ExportScriptForgePOTFile(ByVal FileName As String)
  174. &apos;&apos;&apos; Export the ScriptForge POT file related to its own user interface
  175. &apos;&apos;&apos; Should be called only before issuing new ScriptForge releases only
  176. &apos;&apos;&apos; Args:
  177. &apos;&apos;&apos; FileName: the resulting file. If it exists, is overwritten without warning
  178. Dim sHeader As String &apos; The specific header to insert
  179. sHeader = &quot;&quot; _
  180. &amp; &quot;*********************************************************************\n&quot; _
  181. &amp; &quot;*** The ScriptForge library and its associated libraries ***\n&quot; _
  182. &amp; &quot;*** are part of the LibreOffice project. ***\n&quot; _
  183. &amp; &quot;*********************************************************************\n&quot; _
  184. &amp; &quot;\n&quot; _
  185. &amp; &quot;ScriptForge Release &quot; &amp; SF_Version &amp; &quot;\n&quot; _
  186. &amp; &quot;-----------------------&quot;
  187. Try:
  188. With _SF_
  189. .Interface.ExportToPOTFile(FileName, Header := sHeader)
  190. End With
  191. Finally:
  192. Exit Sub
  193. End Sub &apos; ScriptForge.SF_Utils._ExportScriptForgePOTFile
  194. REM -----------------------------------------------------------------------------
  195. Public Function _GetPropertyValue(ByRef pvArgs As Variant, ByVal psName As String) As Variant
  196. &apos;&apos;&apos; Returns the Value corresponding to the given name
  197. &apos;&apos;&apos; Args
  198. &apos;&apos;&apos; pvArgs: a zero_based array of PropertyValues
  199. &apos;&apos;&apos; psName: the comparison is not case-sensitive
  200. &apos;&apos;&apos; Returns:
  201. &apos;&apos;&apos; Zero-length string if not found
  202. Dim vValue As Variant &apos; Return value
  203. Dim i As Long
  204. vValue = &quot;&quot;
  205. If IsArray(pvArgs) Then
  206. For i = LBound(pvArgs) To UBound(pvArgs)
  207. If UCase(psName) = UCase(pvArgs(i).Name) Then
  208. vValue = pvArgs(i).Value
  209. Exit For
  210. End If
  211. Next i
  212. End If
  213. _GetPropertyValue = vValue
  214. End Function &apos; ScriptForge.SF_Utils._GetPropertyValue
  215. REM -----------------------------------------------------------------------------
  216. Public Function _GetRegistryKeyContent(ByVal psKeyName as string _
  217. , Optional pbForUpdate as Boolean _
  218. ) As Variant
  219. &apos;&apos;&apos; Implement a ConfigurationProvider service
  220. &apos;&apos;&apos; Derived from the Tools library
  221. &apos;&apos;&apos; Args:
  222. &apos;&apos;&apos; psKeyName: the name of the node in the configuration tree
  223. &apos;&apos;&apos; pbForUpdate: default = False
  224. Dim oConfigProvider as Object &apos; com.sun.star.configuration.ConfigurationProvider
  225. Dim vNodePath(0) as New com.sun.star.beans.PropertyValue
  226. Dim sConfig As String &apos; One of next 2 constants
  227. Const cstConfig = &quot;com.sun.star.configuration.ConfigurationAccess&quot;
  228. Const cstConfigUpdate = &quot;com.sun.star.configuration.ConfigurationUpdateAccess&quot;
  229. Set oConfigProvider = _GetUNOService(&quot;ConfigurationProvider&quot;)
  230. vNodePath(0).Name = &quot;nodepath&quot;
  231. vNodePath(0).Value = psKeyName
  232. If IsMissing(pbForUpdate) Then pbForUpdate = False
  233. If pbForUpdate Then sConfig = cstConfigUpdate Else sConfig = cstConfig
  234. Set _GetRegistryKeyContent = oConfigProvider.createInstanceWithArguments(sConfig, vNodePath())
  235. End Function &apos; ScriptForge.SF_Utils._GetRegistryKeyContent
  236. REM -----------------------------------------------------------------------------
  237. Public Function _GetUNOService(ByVal psService As String _
  238. , Optional ByVal pvArg As Variant _
  239. ) As Object
  240. &apos;&apos;&apos; Create a UNO service
  241. &apos;&apos;&apos; Each service is called only once
  242. &apos;&apos;&apos; Args:
  243. &apos;&apos;&apos; psService: shortcut to service
  244. &apos;&apos;&apos; pvArg: some services might require an argument
  245. Dim sLocale As String &apos; fr-BE f.i.
  246. Dim oConfigProvider As Object
  247. Dim oDefaultContext As Object
  248. Dim vNodePath As Variant
  249. Set _GetUNOService = Nothing
  250. With _SF_
  251. Select Case psService
  252. Case &quot;BrowseNodeFactory&quot;
  253. Set oDefaultContext = GetDefaultContext()
  254. If Not IsNull(oDefaultContext) Then Set _GetUNOService = oDefaultContext.getValueByName(&quot;/singletons/com.sun.star.script.browse.theBrowseNodeFactory&quot;)
  255. Case &quot;CharacterClass&quot;
  256. If IsEmpty(.CharacterClass) Or IsNull(.CharacterClass) Then
  257. Set .CharacterClass = CreateUnoService(&quot;com.sun.star.i18n.CharacterClassification&quot;)
  258. End If
  259. Set _GetUNOService = .CharacterClass
  260. Case &quot;ConfigurationProvider&quot;
  261. If IsEmpty(.ConfigurationProvider) Or IsNull(.ConfigurationProvider) Then
  262. Set .ConfigurationProvider = CreateUnoService(&quot;com.sun.star.configuration.ConfigurationProvider&quot;)
  263. End If
  264. Set _GetUNOService = .ConfigurationProvider
  265. Case &quot;CoreReflection&quot;
  266. If IsEmpty(.CoreReflection) Or IsNull(.CoreReflection) Then
  267. Set .CoreReflection = CreateUnoService(&quot;com.sun.star.reflection.CoreReflection&quot;)
  268. End If
  269. Set _GetUNOService = .CoreReflection
  270. Case &quot;DatabaseContext&quot;
  271. If IsEmpty(.DatabaseContext) Or IsNull(.DatabaseContext) Then
  272. Set .DatabaseContext = CreateUnoService(&quot;com.sun.star.sdb.DatabaseContext&quot;)
  273. End If
  274. Set _GetUNOService = .DatabaseContext
  275. Case &quot;DispatchHelper&quot;
  276. If IsEmpty(.DispatchHelper) Or IsNull(.DispatchHelper) Then
  277. Set .DispatchHelper = CreateUnoService(&quot;com.sun.star.frame.DispatchHelper&quot;)
  278. End If
  279. Set _GetUNOService = .DispatchHelper
  280. Case &quot;FileAccess&quot;
  281. If IsEmpty(.FileAccess) Or IsNull(.FileAccess) Then
  282. Set .FileAccess = CreateUnoService(&quot;com.sun.star.ucb.SimpleFileAccess&quot;)
  283. End If
  284. Set _GetUNOService = .FileAccess
  285. Case &quot;FilePicker&quot;
  286. If IsEmpty(.FilePicker) Or IsNull(.FilePicker) Then
  287. Set .FilePicker = CreateUnoService(&quot;com.sun.star.ui.dialogs.FilePicker&quot;)
  288. End If
  289. Set _GetUNOService = .FilePicker
  290. Case &quot;FilterFactory&quot;
  291. If IsEmpty(.FilterFactory) Or IsNull(.FilterFactory) Then
  292. Set .FilterFactory = CreateUnoService(&quot;com.sun.star.document.FilterFactory&quot;)
  293. End If
  294. Set _GetUNOService = .FilterFactory
  295. Case &quot;FolderPicker&quot;
  296. If IsEmpty(.FolderPicker) Or IsNull(.FolderPicker) Then
  297. Set .FolderPicker = CreateUnoService(&quot;com.sun.star.ui.dialogs.FolderPicker&quot;)
  298. End If
  299. Set _GetUNOService = .FolderPicker
  300. Case &quot;FunctionAccess&quot;
  301. If IsEmpty(.FunctionAccess) Or IsNull(.FunctionAccess) Then
  302. Set .FunctionAccess = CreateUnoService(&quot;com.sun.star.sheet.FunctionAccess&quot;)
  303. End If
  304. Set _GetUNOService = .FunctionAccess
  305. Case &quot;Introspection&quot;
  306. If IsEmpty(.Introspection) Or IsNull(.Introspection) Then
  307. Set .Introspection = CreateUnoService(&quot;com.sun.star.beans.Introspection&quot;)
  308. End If
  309. Set _GetUNOService = .Introspection
  310. Case &quot;Locale&quot;
  311. If IsEmpty(.Locale) Or IsNull(.Locale) Then
  312. .Locale = CreateUnoStruct(&quot;com.sun.star.lang.Locale&quot;)
  313. &apos; Derived from the Tools library
  314. Set oConfigProvider = createUnoService(&quot;com.sun.star.configuration.ConfigurationProvider&quot;)
  315. vNodePath = Array() : ReDim vNodePath(0)
  316. vNodePath(0) = New com.sun.star.beans.PropertyValue
  317. vNodePath(0).Name = &quot;nodepath&quot; : vNodePath(0).Value = &quot;org.openoffice.Setup/L10N&quot;
  318. sLocale = oConfigProvider.createInstanceWithArguments(&quot;com.sun.star.configuration.ConfigurationAccess&quot;, vNodePath()).getByName(&quot;ooLocale&quot;)
  319. .Locale.Language = Left(sLocale, 2)
  320. .Locale.Country = Right(sLocale, 2)
  321. End If
  322. Set _GetUNOService = .Locale
  323. Case &quot;MacroExpander&quot;
  324. Set oDefaultContext = GetDefaultContext()
  325. If Not IsNull(oDefaultContext) Then Set _GetUNOService = oDefaultContext.getValueByName(&quot;/singletons/com.sun.star.util.theMacroExpander&quot;)
  326. Case &quot;MailService&quot;
  327. If IsEmpty(.MailService) Or IsNull(.MailService) Then
  328. If GetGuiType = 1 Then &apos; Windows
  329. Set .MailService = CreateUnoService(&quot;com.sun.star.system.SimpleSystemMail&quot;)
  330. Else
  331. Set .MailService = CreateUnoService(&quot;com.sun.star.system.SimpleCommandMail&quot;)
  332. End If
  333. End If
  334. Set _GetUNOService = .MailService
  335. Case &quot;PathSettings&quot;
  336. If IsEmpty(.PathSettings) Or IsNull(.PathSettings) Then
  337. Set .PathSettings = CreateUnoService(&quot;com.sun.star.util.PathSettings&quot;)
  338. End If
  339. Set _GetUNOService = .PathSettings
  340. Case &quot;PathSubstitution&quot;
  341. If IsEmpty(.PathSubstitution) Or IsNull(.PathSubstitution) Then
  342. Set .PathSubstitution = CreateUnoService(&quot;com.sun.star.util.PathSubstitution&quot;)
  343. End If
  344. Set _GetUNOService = .PathSubstitution
  345. Case &quot;ScriptProvider&quot;
  346. If IsMissing(pvArg) Then pvArg = SF_Session.SCRIPTISAPPLICATION
  347. Select Case LCase(pvArg)
  348. Case SF_Session.SCRIPTISEMBEDDED &apos; Document
  349. If Not IsNull(ThisComponent) Then Set _GetUNOService = ThisComponent.getScriptProvider()
  350. Case Else
  351. If IsEmpty(.ScriptProvider) Or IsNull(.ScriptProvider) Then
  352. Set .ScriptProvider = _
  353. CreateUnoService(&quot;com.sun.star.script.provider.MasterScriptProviderFactory&quot;).createScriptProvider(&quot;&quot;)
  354. End If
  355. Set _GetUNOService = .ScriptProvider
  356. End Select
  357. Case &quot;SearchOptions&quot;
  358. If IsEmpty(.SearchOptions) Or IsNull(.SearchOptions) Then
  359. Set .SearchOptions = New com.sun.star.util.SearchOptions
  360. With .SearchOptions
  361. .algorithmType = com.sun.star.util.SearchAlgorithms.REGEXP
  362. .searchFlag = 0
  363. End With
  364. End If
  365. Set _GetUNOService = .SearchOptions
  366. Case &quot;SystemShellExecute&quot;
  367. If IsEmpty(.SystemShellExecute) Or IsNull(.SystemShellExecute) Then
  368. Set .SystemShellExecute = CreateUnoService(&quot;com.sun.star.system.SystemShellExecute&quot;)
  369. End If
  370. Set _GetUNOService = .SystemShellExecute
  371. Case &quot;TextSearch&quot;
  372. If IsEmpty(.TextSearch) Or IsNull(.TextSearch) Then
  373. Set .TextSearch = CreateUnoService(&quot;com.sun.star.util.TextSearch&quot;)
  374. End If
  375. Set _GetUNOService = .TextSearch
  376. Case &quot;URLTransformer&quot;
  377. If IsEmpty(.URLTransformer) Or IsNull(.URLTransformer) Then
  378. Set .URLTransformer = CreateUnoService(&quot;com.sun.star.util.URLTransformer&quot;)
  379. End If
  380. Set _GetUNOService = .URLTransformer
  381. Case Else
  382. End Select
  383. End With
  384. End Function &apos; ScriptForge.SF_Utils._GetUNOService
  385. REM -----------------------------------------------------------------------------
  386. Public Sub _InitializeRoot(Optional ByVal pbForce As Boolean)
  387. &apos;&apos;&apos; Initialize _SF_ as SF_Root basic object
  388. &apos;&apos;&apos; Args:
  389. &apos;&apos;&apos; pbForce = True forces the reinit (default = False)
  390. If IsMissing(pbForce) Then pbForce = False
  391. If pbForce Then Set _SF_ = Nothing
  392. If IsEmpty(_SF_) Or IsNull(_SF_) Then
  393. Set _SF_ = New SF_Root
  394. Set _SF_.[Me] = _SF_
  395. &apos; Localization
  396. _SF_._LoadLocalizedInterface()
  397. End If
  398. End Sub &apos; ScriptForge.SF_Utils._InitializeRoot
  399. REM -----------------------------------------------------------------------------
  400. Public Function _MakePropertyValue(ByVal psName As String _
  401. , ByRef pvValue As Variant _
  402. ) As com.sun.star.beans.PropertyValue
  403. &apos;&apos;&apos; Create and return a new com.sun.star.beans.PropertyValue
  404. Dim oPropertyValue As New com.sun.star.beans.PropertyValue
  405. With oPropertyValue
  406. .Name = psName
  407. .Value = SF_Utils._CPropertyValue(pvValue)
  408. End With
  409. _MakePropertyValue() = oPropertyValue
  410. End Function &apos; ScriptForge.SF_Utils._MakePropertyValue
  411. REM -----------------------------------------------------------------------------
  412. Public Function _Repr(ByVal pvArg As Variant, Optional ByVal plMax As Long) As String
  413. &apos;&apos;&apos; Convert pvArg into a readable string (truncated if length &gt; plMax)
  414. &apos;&apos;&apos; Args
  415. &apos;&apos;&apos; pvArg: may be of any type
  416. &apos;&apos;&apos; plMax: maximum length of the resulting string (default = 32K)
  417. Dim sArg As String &apos; Return value
  418. Dim oObject As Object &apos; Alias of argument to avoid &quot;Object variable not set&quot;
  419. Dim sObject As String &apos; Object representation
  420. Dim sObjectType As String &apos; ObjectType attribute of Basic objects
  421. Dim sLength As String &apos; String length as a string
  422. Dim i As Long
  423. Const cstBasicObject = &quot;com.sun.star.script.NativeObjectWrapper&quot;
  424. Const cstMaxLength = 2^15 - 1 &apos; 32767
  425. Const cstByteLength = 25
  426. Const cstEtc = &quot; … &quot;
  427. If IsMissing(plMax) Or plMax = 0 Then plMax = cstMaxLength
  428. If IsArray(pvArg) Then
  429. sArg = SF_Array._Repr(pvArg)
  430. Else
  431. Select Case VarType(pvArg)
  432. Case V_EMPTY : sArg = &quot;[EMPTY]&quot;
  433. Case V_NULL : sArg = &quot;[NULL]&quot;
  434. Case V_OBJECT
  435. If IsNull(pvArg) Then
  436. sArg = &quot;[NULL]&quot;
  437. Else
  438. sObject = SF_Session.UnoObjectType(pvArg)
  439. If sObject = &quot;&quot; Or sObject = cstBasicObject Then &apos; Not a UNO object
  440. &apos; Test if argument is a ScriptForge object
  441. sObjectType = &quot;&quot;
  442. On Local Error Resume Next
  443. Set oObject = pvArg
  444. sObjectType = oObject.ObjectType
  445. On Error GoTo 0
  446. If sObjectType = &quot;&quot; Then
  447. sArg = &quot;[OBJECT]&quot;
  448. ElseIf Left(sObjectType, 3) = &quot;SF_&quot; Then
  449. sArg = &quot;[&quot; &amp; sObjectType &amp; &quot;]&quot;
  450. Else
  451. sArg = oObject._Repr()
  452. End If
  453. Else
  454. sArg = &quot;[&quot; &amp; sObject &amp; &quot;]&quot;
  455. End If
  456. End If
  457. Case V_VARIANT : sArg = &quot;[VARIANT]&quot;
  458. Case V_STRING
  459. sArg = SF_String._Repr(pvArg)
  460. Case V_BOOLEAN : sArg = Iif(pvArg, &quot;[TRUE]&quot;, &quot;[FALSE]&quot;)
  461. Case V_BYTE : sArg = Right(&quot;00&quot; &amp; Hex(pvArg), 2)
  462. Case V_SINGLE, V_DOUBLE, V_CURRENCY
  463. sArg = Format(pvArg)
  464. If InStr(1, sArg, &quot;E&quot;, 1) = 0 Then sArg = Format(pvArg, &quot;##0.0##&quot;)
  465. sArg = Replace(sArg, &quot;,&quot;, &quot;.&quot;) &apos;Force decimal point
  466. Case V_BIGINT : sArg = CStr(CLng(pvArg))
  467. Case V_DATE : sArg = _CDateToIso(pvArg)
  468. Case Else : sArg = CStr(pvArg)
  469. End Select
  470. End If
  471. If Len(sArg) &gt; plMax Then
  472. sLength = &quot;(&quot; &amp; Len(sArg) &amp; &quot;)&quot;
  473. sArg = Left(sArg, plMax - Len(cstEtc) - Len(slength)) &amp; cstEtc &amp; sLength
  474. End If
  475. _Repr = sArg
  476. End Function &apos; ScriptForge.SF_Utils._Repr
  477. REM -----------------------------------------------------------------------------
  478. Private Function _ReprValues(Optional ByVal pvArgs As Variant _
  479. , Optional ByVal plMax As Long _
  480. ) As String
  481. &apos;&apos;&apos; Convert an array of values to a comma-separated list of readable strings
  482. Dim sValues As String &apos; Return value
  483. Dim sValue As String &apos; A single value
  484. Dim vValue As Variant &apos; A single item in the argument
  485. Dim i As Long &apos; Items counter
  486. Const cstMax = 20 &apos; Maximum length of single string
  487. Const cstContinue = &quot;…&quot; &apos; Unicode continuation char U+2026
  488. _ReprValues = &quot;&quot;
  489. If IsMissing(pvArgs) Then Exit Function
  490. If Not IsArray(pvArgs) Then pvArgs = Array(pvArgs)
  491. sValues = &quot;&quot;
  492. For i = 0 To UBound(pvArgs)
  493. vValue = pvArgs(i)
  494. If i &lt; plMax Then
  495. If VarType(vValue) = V_STRING Then sValue = &quot;&quot;&quot;&quot; &amp; vValue &amp; &quot;&quot;&quot;&quot; Else sValue = SF_Utils._Repr(vValue, cstMax)
  496. If Len(sValues) = 0 Then sValues = sValue Else sValues = sValues &amp; &quot;, &quot; &amp; sValue
  497. ElseIf i &lt; UBound(pvArgs) Then
  498. sValues = sValues &amp; &quot;, &quot; &amp; cstContinue
  499. Exit For
  500. End If
  501. Next i
  502. _ReprValues = sValues
  503. End Function &apos; ScriptForge.SF_Utils._ReprValues
  504. REM -----------------------------------------------------------------------------
  505. Public Sub _SetPropertyValue(ByRef pvPropertyValue As Variant _
  506. , ByVal psName As String _
  507. , ByRef pvValue As Variant _
  508. )
  509. &apos;&apos;&apos; Update the 1st argument (passed by reference), which is an array of property values
  510. &apos;&apos;&apos; If the property psName exists, update it with pvValue, otherwise create it on top of the array
  511. Dim oPropertyValue As New com.sun.star.beans.PropertyValue
  512. Dim lIndex As Long &apos; Found entry
  513. Dim vValue As Variant &apos; Alias of pvValue
  514. Dim i As Long
  515. lIndex = -1
  516. For i = 0 To UBound(pvPropertyValue)
  517. If pvPropertyValue(i).Name = psName Then
  518. lIndex = i
  519. Exit For
  520. End If
  521. Next i
  522. If lIndex &lt; 0 Then &apos; Not found
  523. lIndex = UBound(pvPropertyValue) + 1
  524. ReDim Preserve pvPropertyValue(0 To lIndex)
  525. Set oPropertyValue = SF_Utils._MakePropertyValue(psName, pvValue)
  526. pvPropertyValue(lIndex) = oPropertyValue
  527. Else &apos; psName exists already in array of property values
  528. pvPropertyValue(lIndex).Value = SF_Utils._CPropertyValue(pvValue)
  529. End If
  530. End Sub &apos; ScriptForge.SF_Utils._SetPropertyValue
  531. REM -----------------------------------------------------------------------------
  532. Private Function _TypeNames(Optional ByVal pvArgs As Variant) As String
  533. &apos;&apos;&apos; Converts the array of VarTypes to a comma-separated list of TypeNames
  534. Dim sTypes As String &apos; Return value
  535. Dim sType As String &apos; A single type
  536. Dim iType As Integer &apos; A single item of the argument
  537. _TypeNames = &quot;&quot;
  538. If IsMissing(pvArgs) Then Exit Function
  539. If Not IsArray(pvArgs) Then pvArgs = Array(pvArgs)
  540. sTypes = &quot;&quot;
  541. For Each iType In pvArgs
  542. Select Case iType
  543. Case V_EMPTY : sType = &quot;Empty&quot;
  544. Case V_NULL : sType = &quot;Null&quot;
  545. Case V_INTEGER : sType = &quot;Integer&quot;
  546. Case V_LONG : sType = &quot;Long&quot;
  547. Case V_SINGLE : sType = &quot;Single&quot;
  548. Case V_DOUBLE : sType = &quot;Double&quot;
  549. Case V_CURRENCY : sType = &quot;Currency&quot;
  550. Case V_DATE : sType = &quot;Date&quot;
  551. Case V_STRING : sType = &quot;String&quot;
  552. Case V_OBJECT : sType = &quot;Object&quot;
  553. Case V_BOOLEAN : sType = &quot;Boolean&quot;
  554. Case V_VARIANT : sType = &quot;Variant&quot;
  555. Case V_DECIMAL : sType = &quot;Decimal&quot;
  556. Case &gt;= V_ARRAY : sType = &quot;Array&quot;
  557. Case V_NUMERIC : sType = &quot;Numeric&quot;
  558. End Select
  559. If Len(sTypes) = 0 Then sTypes = sType Else sTypes = sTypes &amp; &quot;, &quot; &amp; sType
  560. Next iType
  561. _TypeNames = sTypes
  562. End Function &apos; ScriptForge.SF_Utils._TypeNames
  563. REM -----------------------------------------------------------------------------
  564. Public Function _Validate(Optional ByRef pvArgument As Variant _
  565. , ByVal psName As String _
  566. , Optional ByVal pvTypes As Variant _
  567. , Optional ByVal pvValues As Variant _
  568. , Optional ByVal pvRegex As Variant _
  569. , Optional ByVal pvObjectType As Variant _
  570. ) As Boolean
  571. &apos;&apos;&apos; Validate the arguments set by user scripts
  572. &apos;&apos;&apos; The arguments of the function define the validation rules
  573. &apos;&apos;&apos; This function ignores arrays. Use _ValidateArray instead
  574. &apos;&apos;&apos; Args:
  575. &apos;&apos;&apos; pvArgument: the argument to (in)validate
  576. &apos;&apos;&apos; psName: the documented name of the argument (can be inserted in an error message)
  577. &apos;&apos;&apos; pvTypes: array of allowed VarTypes
  578. &apos;&apos;&apos; pvValues: array of allowed values
  579. &apos;&apos;&apos; pvRegex: regular expression to comply with
  580. &apos;&apos;&apos; pvObjectType: mandatory Basic class
  581. &apos;&apos;&apos; Return: True if validation OK
  582. &apos;&apos;&apos; Otherwise an error is raised
  583. &apos;&apos;&apos; Exceptions:
  584. &apos;&apos;&apos; ARGUMENTERROR
  585. Dim iVarType As Integer &apos; Extended VarType of argument
  586. Dim bValid As Boolean &apos; Returned value
  587. Dim oArgument As Variant &apos; Workaround &quot;Object variable not set&quot; error on 1st executable statement
  588. Const cstMaxLength = 256 &apos; Maximum length of readable value
  589. Const cstMaxValues = 10 &apos; Maximum number of allowed items to list in an error message
  590. &apos; To avoid useless recursions, keep main function, only increase stack depth
  591. _SF_.StackLevel = _SF_.StackLevel + 1
  592. On Local Error GoTo Finally &apos; Do never interrupt
  593. Try:
  594. bValid = True
  595. If IsMissing(pvArgument) Then GoTo CatchMissing
  596. If IsMissing(pvRegex) Or IsEmpty(pvRegex) Then pvRegex = &quot;&quot;
  597. If IsMissing(pvObjectType) Or IsEmpty(pvObjectType) Then pvObjectType = &quot;&quot;
  598. iVarType = SF_Utils._VarTypeExt(pvArgument)
  599. &apos; Arrays NEVER pass validation
  600. If iVarType &gt;= V_ARRAY Then
  601. bValid = False
  602. Else
  603. &apos; Check existence of argument
  604. bValid = iVarType &lt;&gt; V_NULL And iVarType &lt;&gt; V_EMPTY
  605. &apos; Check if argument&apos;s VarType is valid
  606. If bValid And Not IsMissing(pvTypes) Then
  607. If Not IsArray(pvTypes) Then bValid = ( pvTypes = iVarType ) Else bValid = SF_Array.Contains(pvTypes, iVarType)
  608. End If
  609. &apos; Check if argument&apos;s value is valid
  610. If bValid And Not IsMissing(pvValues) Then
  611. If Not IsArray(pvValues) Then pvValues = Array(pvValues)
  612. bValid = SF_Array.Contains(pvValues, pvArgument, CaseSensitive := False)
  613. End If
  614. &apos; Check regular expression
  615. If bValid And Len(pvRegex) &gt; 0 And iVarType = V_STRING Then
  616. If Len(pvArgument) &gt; 0 Then bValid = SF_String.IsRegex(pvArgument, pvRegex, CaseSensitive := False)
  617. End If
  618. &apos; Check instance types
  619. If bValid And Len(pvObjectType) &gt; 0 And iVarType = V_OBJECT Then
  620. Set oArgument = pvArgument
  621. bValid = ( pvObjectType = oArgument.ObjectType )
  622. End If
  623. End If
  624. If Not bValid Then
  625. &apos;&apos;&apos; Library: ScriptForge
  626. &apos;&apos;&apos; Service: Array
  627. &apos;&apos;&apos; Method: Contains
  628. &apos;&apos;&apos; Arguments: Array_1D, ToFind, [CaseSensitive=False], [SortOrder=&quot;&quot;]
  629. &apos;&apos;&apos; A serious error has been detected on argument SortOrder
  630. &apos;&apos;&apos; Rules: SortOrder is of type String
  631. &apos;&apos;&apos; SortOrder must contain one of next values: &quot;ASC&quot;, &quot;DESC&quot;, &quot;&quot;
  632. &apos;&apos;&apos; Actual value: &quot;Ascending&quot;
  633. SF_Exception.RaiseFatal(ARGUMENTERROR _
  634. , SF_Utils._Repr(pvArgument, cstMaxLength), psName, SF_Utils._TypeNames(pvTypes) _
  635. , SF_Utils._ReprValues(pvValues, cstMaxValues), pvRegex, pvObjectType _
  636. )
  637. End If
  638. Finally:
  639. _Validate = bValid
  640. _SF_.StackLevel = _SF_.StackLevel - 1
  641. Exit Function
  642. CatchMissing:
  643. bValid = False
  644. SF_Exception.RaiseFatal(MISSINGARGERROR, psName)
  645. GoTo Finally
  646. End Function &apos; ScriptForge.SF_Utils._Validate
  647. REM -----------------------------------------------------------------------------
  648. Public Function _ValidateArray(Optional ByRef pvArray As Variant _
  649. , ByVal psName As String _
  650. , Optional ByVal piDimensions As Integer _
  651. , Optional ByVal piType As Integer _
  652. , Optional ByVal pbNotNull As Boolean _
  653. ) As Boolean
  654. &apos;&apos;&apos; Validate the (array) arguments set by user scripts
  655. &apos;&apos;&apos; The arguments of the function define the validation rules
  656. &apos;&apos;&apos; This function ignores non-arrays. Use _Validate instead
  657. &apos;&apos;&apos; Args:
  658. &apos;&apos;&apos; pvArray: the argument to (in)validate
  659. &apos;&apos;&apos; psName: the documented name of the array (can be inserted in an error message)
  660. &apos;&apos;&apos; piDimensions: the # of dimensions the array must have. 0 = Any (default)
  661. &apos;&apos;&apos; piType: (default = -1, i.e. not applicable)
  662. &apos;&apos;&apos; For 2D arrays, the 1st column is checked
  663. &apos;&apos;&apos; 0 =&gt; all items must be any out of next types: string, date or numeric,
  664. &apos;&apos;&apos; but homogeneously: all strings or all dates or all numeric
  665. &apos;&apos;&apos; V_STRING or V_DATE or V_NUMERIC =&gt; that specific type is required
  666. &apos;&apos;&apos; pbNotNull: piType must be &gt;=0, otherwise ignored
  667. &apos;&apos;&apos; If True: Empty, Null items are rejected
  668. &apos;&apos;&apos; Return: True if validation OK
  669. &apos;&apos;&apos; Otherwise an error is raised
  670. &apos;&apos;&apos; Exceptions:
  671. &apos;&apos;&apos; ARRAYERROR
  672. Dim iVarType As Integer &apos; VarType of argument
  673. Dim vItem As Variant &apos; Array item
  674. Dim iItemType As Integer &apos; VarType of individual items of argument
  675. Dim iDims As Integer &apos; Number of dimensions of the argument
  676. Dim bValid As Boolean &apos; Returned value
  677. Dim iArrayType As Integer &apos; Static array type
  678. Dim iFirstItemType As Integer &apos; Type of 1st non-null/empty item
  679. Dim sType As String &apos; Allowed item types as a string
  680. Dim i As Long
  681. Const cstMaxLength = 256 &apos; Maximum length of readable value
  682. &apos; To avoid useless recursions, keep main function, only increase stack depth
  683. _SF_.StackLevel = _SF_.StackLevel + 1
  684. On Local Error GoTo Finally &apos; Do never interrupt
  685. Try:
  686. bValid = True
  687. If IsMissing(pvArray) Then GoTo CatchMissing
  688. If IsMissing(piDimensions) Then piDimensions = 0
  689. If IsMissing(piType) Then piType = -1
  690. If IsMissing(pbNotNull) Then pbNotNull = False
  691. iVarType = VarType(pvArray)
  692. &apos; Scalars NEVER pass validation
  693. If iVarType &lt; V_ARRAY Then
  694. bValid = False
  695. Else
  696. &apos; Check dimensions
  697. iDims = SF_Array.CountDims(pvArray)
  698. If iDims &gt; 2 Then bValid = False &apos; Only 1D and 2D arrays
  699. If bValid And piDimensions &gt; 0 Then
  700. bValid = ( iDims = piDimensions Or (iDims = 0 And piDimensions = 1) ) &apos; Allow empty vectors
  701. End If
  702. &apos; Check VarType and Empty/Null status of the array items
  703. If bValid And iDims = 1 And piType &gt;= 0 Then
  704. iArrayType = SF_Array._StaticType(pvArray)
  705. If (piType = 0 And iArrayType &gt; 0) Or (piType &gt; 0 And iArrayType = piType) Then
  706. &apos; If static array of the right VarType ..., OK
  707. Else
  708. &apos; Go through array and check individual items
  709. iFirstItemType = -1
  710. For i = LBound(pvArray, 1) To UBound(pvArray, 1)
  711. If iDims = 1 Then vItem = pvArray(i) Else vItem = pvArray(i, LBound(pvArray, 2))
  712. iItemType = SF_Utils._VarTypeExt(vItem)
  713. If iItemType &gt; V_NULL Then &apos; Exclude Empty and Null
  714. &apos; Initialization at first non-null item
  715. If iFirstItemType &lt; 0 Then
  716. iFirstItemType = iItemType
  717. If piType &gt; 0 Then bValid = ( iFirstItemType = piType ) Else bValid = SF_Array.Contains(Array(V_STRING, V_DATE, V_NUMERIC), iFirstItemType)
  718. Else
  719. bValid = (iItemType = iFirstItemType)
  720. End If
  721. Else
  722. bValid = Not pbNotNull
  723. End If
  724. If Not bValid Then Exit For
  725. Next i
  726. End If
  727. End If
  728. End If
  729. If Not bValid Then
  730. &apos;&apos;&apos; Library: ScriptForge
  731. &apos;&apos;&apos; Service: Array
  732. &apos;&apos;&apos; Method: Contains
  733. &apos;&apos;&apos; Arguments: Array_1D, ToFind, [CaseSensitive=False], [SortOrder=&quot;&quot;|&quot;ASC&quot;|&quot;DESC&quot;]
  734. &apos;&apos;&apos; An error was detected on argument Array_1D
  735. &apos;&apos;&apos; Rules: Array_1D is of type Array
  736. &apos;&apos;&apos; Array_1D must have maximum 1 dimension
  737. &apos;&apos;&apos; Array_1D must have all elements of the same type: either String, Date or Numeric
  738. &apos;&apos;&apos; Actual value: (0:2, 0:3)
  739. sType = &quot;&quot;
  740. If piType = 0 Then
  741. sType = &quot;String, Date, Numeric&quot;
  742. ElseIf piType &gt; 0 Then
  743. sType = SF_Utils._TypeNames(piType)
  744. End If
  745. SF_Exception.RaiseFatal(ARRAYERROR _
  746. , SF_Utils._Repr(pvArray, cstMaxLength), psName, piDimensions, sType, pbNotNull)
  747. End If
  748. Finally:
  749. _ValidateArray = bValid
  750. _SF_.StackLevel = _SF_.StackLevel - 1
  751. Exit Function
  752. CatchMissing:
  753. bValid = False
  754. SF_Exception.RaiseFatal(MISSINGARGERROR, psName)
  755. GoTo Finally
  756. End Function &apos; ScriptForge.SF_Utils._ValidateArray
  757. REM -----------------------------------------------------------------------------
  758. Public Function _ValidateFile(Optional ByRef pvArgument As Variant _
  759. , ByVal psName As String _
  760. , Optional ByVal pbWildCards As Boolean _
  761. , Optional ByVal pbSpace As Boolean _
  762. )
  763. &apos;&apos;&apos; Validate the argument as a valid FileName
  764. &apos;&apos;&apos; Args:
  765. &apos;&apos;&apos; pvArgument: the argument to (in)validate
  766. &apos;&apos;&apos; pbWildCards: if True, wildcard characters are accepted in the last component of the 1st argument
  767. &apos;&apos;&apos; pbSpace: if True, the argument may be an empty string. Default = False
  768. &apos;&apos;&apos; Return: True if validation OK
  769. &apos;&apos;&apos; Otherwise an error is raised
  770. &apos;&apos;&apos; Exceptions:
  771. &apos;&apos;&apos; ARGUMENTERROR
  772. Dim iVarType As Integer &apos; VarType of argument
  773. Dim sFile As String &apos; Alias for argument
  774. Dim bValid As Boolean &apos; Returned value
  775. Dim sFileNaming As String &apos; Alias of SF_FileSystem.FileNaming
  776. Dim oArgument As Variant &apos; Workaround &quot;Object variable not set&quot; error on 1st executable statement
  777. Const cstMaxLength = 256 &apos; Maximum length of readable value
  778. &apos; To avoid useless recursions, keep main function, only increase stack depth
  779. _SF_.StackLevel = _SF_.StackLevel + 1
  780. On Local Error GoTo Finally &apos; Do never interrupt
  781. Try:
  782. bValid = True
  783. If IsMissing(pvArgument) Then GoTo CatchMissing
  784. If IsMissing(pbWildCards) Then pbWildCards = False
  785. If IsMissing(pbSpace) Then pbSpace = False
  786. iVarType = VarType(pvArgument)
  787. &apos; Arrays NEVER pass validation
  788. If iVarType &gt;= V_ARRAY Then
  789. bValid = False
  790. Else
  791. &apos; Argument must be a string containing a valid file name
  792. bValid = ( iVarType = V_STRING )
  793. If bValid Then
  794. bValid = ( Len(pvArgument) &gt; 0 Or pbSpace )
  795. If bValid And Len(pvArgument) &gt; 0 Then
  796. &apos; Wildcards are replaced by arbitrary alpha characters
  797. If pbWildCards Then
  798. sFile = Replace(Replace(pvArgument, &quot;?&quot;, &quot;Z&quot;), &quot;*&quot;, &quot;A&quot;)
  799. Else
  800. sFile = pvArgument
  801. bValid = ( InStr(sFile, &quot;?&quot;) + InStr(sFile, &quot;*&quot;) = 0 )
  802. End If
  803. &apos; Check file format without wildcards
  804. If bValid Then
  805. With SF_FileSystem
  806. sFileNaming = .FileNaming
  807. Select Case sFileNaming
  808. Case &quot;ANY&quot; : bValid = SF_String.IsUrl(ConvertToUrl(sFile))
  809. Case &quot;URL&quot; : bValid = SF_String.IsUrl(sFile)
  810. Case &quot;SYS&quot; : bValid = SF_String.IsFileName(sFile)
  811. End Select
  812. End With
  813. End If
  814. &apos; Check that wildcards are only present in last component
  815. If bValid And pbWildCards Then
  816. sFile = SF_FileSystem.GetParentFolderName(pvArgument)
  817. bValid = ( InStr(sFile, &quot;*&quot;) + InStr(sFile, &quot;?&quot;) + InStr(sFile,&quot;%3F&quot;) = 0 ) &apos; ConvertToUrl replaces ? by %3F
  818. End If
  819. End If
  820. End If
  821. End If
  822. If Not bValid Then
  823. &apos;&apos;&apos; Library: ScriptForge
  824. &apos;&apos;&apos; Service: FileSystem
  825. &apos;&apos;&apos; Method: CopyFile
  826. &apos;&apos;&apos; Arguments: Source, Destination
  827. &apos;&apos;&apos; A serious error has been detected on argument Source
  828. &apos;&apos;&apos; Rules: Source is of type String
  829. &apos;&apos;&apos; Source must be a valid file name expressed in operating system notation
  830. &apos;&apos;&apos; Source may contain one or more wildcard characters in its last component
  831. &apos;&apos;&apos; Actual value: /home/jean-*/SomeFile.odt
  832. SF_Exception.RaiseFatal(FILEERROR _
  833. , SF_Utils._Repr(pvArgument, cstMaxLength), psName, pbWildCards)
  834. End If
  835. Finally:
  836. _ValidateFile = bValid
  837. _SF_.StackLevel = _SF_.StackLevel - 1
  838. Exit Function
  839. CatchMissing:
  840. bValid = False
  841. SF_Exception.RaiseFatal(MISSINGARGERROR, psName)
  842. GoTo Finally
  843. End Function &apos; ScriptForge.SF_Utils._ValidateFile
  844. REM -----------------------------------------------------------------------------
  845. Public Function _VarTypeExt(ByRef pvValue As Variant) As Integer
  846. &apos;&apos;&apos; Return the VarType of the argument but all numeric types are aggregated into V_NUMERIC
  847. &apos;&apos;&apos; Args:
  848. &apos;&apos;&apos; pvValue: value to examine
  849. &apos;&apos;&apos; Return:
  850. &apos;&apos;&apos; The extended VarType
  851. Dim iType As Integer &apos; VarType of argument
  852. iType = VarType(pvValue)
  853. Select Case iType
  854. Case V_INTEGER, V_LONG, V_SINGLE, V_DOUBLE, V_CURRENCY, V_BIGINT, V_DECIMAL
  855. _VarTypeExt = V_NUMERIC
  856. Case Else : _VarTypeExt = iType
  857. End Select
  858. End Function &apos; ScriptForge.SF_Utils._VarTypeExt
  859. REM ================================================= END OF SCRIPTFORGE.SF_UTILS
  860. </script:module>