SF_Document.xba 67 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507
  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_Document" 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 SFDocuments 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_Document
  13. &apos;&apos;&apos; ===========
  14. &apos;&apos;&apos;
  15. &apos;&apos;&apos; The SFDocuments library gathers a number of methods and properties making easy
  16. &apos;&apos;&apos; managing and manipulating LibreOffice documents
  17. &apos;&apos;&apos;
  18. &apos;&apos;&apos; Some methods are generic for all types of documents: they are combined in the
  19. &apos;&apos;&apos; current SF_Document module
  20. &apos;&apos;&apos; - saving, closing documents
  21. &apos;&apos;&apos; - accessing their standard or custom properties
  22. &apos;&apos;&apos; Specific properties and methods are implemented in the concerned subclass(es) SF_Calc, SF_Base, ...
  23. &apos;&apos;&apos;
  24. &apos;&apos;&apos; Documents might contain forms. The current service gives access to the &quot;SFDocuments.Form&quot; service
  25. &apos;&apos;&apos;
  26. &apos;&apos;&apos; To workaround the absence of class inheritance in LibreOffice Basic, some redundancy is necessary
  27. &apos;&apos;&apos; Each subclass MUST implement also the generic methods and properties, even if they only call
  28. &apos;&apos;&apos; the parent methods and properties implemented below
  29. &apos;&apos;&apos; They should also duplicate some generic private members as a subset of their own set of members
  30. &apos;&apos;&apos;
  31. &apos;&apos;&apos; The current module is closely related to the &quot;UI&quot; and &quot;FileSystem&quot; services
  32. &apos;&apos;&apos; of the ScriptForge library
  33. &apos;&apos;&apos;
  34. &apos;&apos;&apos; Service invocation examples:
  35. &apos;&apos;&apos; 1) From the UI service
  36. &apos;&apos;&apos; Dim ui As Object, oDoc As Object
  37. &apos;&apos;&apos; Set ui = CreateScriptService(&quot;UI&quot;)
  38. &apos;&apos;&apos; Set oDoc = ui.GetDocument(&quot;Untitled 1&quot;)
  39. &apos;&apos;&apos; &apos; or Set oDoc = ui.CreateDocument(&quot;Calc&quot;, ...)
  40. &apos;&apos;&apos; &apos; or Set oDoc = ui.OpenDocument(&quot;C:\Me\MyFile.odt&quot;)
  41. &apos;&apos;&apos; 2) Directly if the document is already opened
  42. &apos;&apos;&apos; Dim oDoc As Object
  43. &apos;&apos;&apos; Set oDoc = CreateScriptService(&quot;SFDocuments.Document&quot;, &quot;Untitled 1&quot;) &apos; Default = ActiveWindow
  44. &apos;&apos;&apos; &apos; The substring &quot;SFDocuments.&quot; in the service name is optional
  45. &apos;&apos;&apos;
  46. &apos;&apos;&apos; Detailed user documentation:
  47. &apos;&apos;&apos; https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03/sf_document.html?DbPAR=BASIC
  48. &apos;&apos;&apos;
  49. &apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
  50. REM ================================================================== EXCEPTIONS
  51. Private Const DOCUMENTDEADERROR = &quot;DOCUMENTDEADERROR&quot;
  52. Private Const DOCUMENTSAVEERROR = &quot;DOCUMENTSAVEERROR&quot;
  53. Private Const DOCUMENTSAVEASERROR = &quot;DOCUMENTSAVEASERROR&quot;
  54. Private Const DOCUMENTREADONLYERROR = &quot;DOCUMENTREADONLYERROR&quot;
  55. Private Const FORMDEADERROR = &quot;FORMDEADERROR&quot;
  56. REM ============================================================= PRIVATE MEMBERS
  57. Private [Me] As Object
  58. Private [_Parent] As Object
  59. Private [_SubClass] As Object &apos; Subclass instance
  60. Private ObjectType As String &apos; Must be DOCUMENT
  61. Private ServiceName As String
  62. &apos; Window description
  63. Private _Component As Object &apos; com.sun.star.lang.XComponent
  64. Private _Frame As Object &apos; com.sun.star.comp.framework.Frame
  65. Private _WindowName As String &apos; Object Name
  66. Private _WindowTitle As String &apos; Only mean to identify new documents
  67. Private _WindowFileName As String &apos; URL of file name
  68. Private _DocumentType As String &apos; Writer, Calc, ...
  69. &apos; Properties (work variables - real properties could have been set manually by user)
  70. Private _DocumentProperties As Object &apos; Dictionary of document properties
  71. Private _CustomProperties As Object &apos; Dictionary of custom properties
  72. REM ============================================================ MODULE CONSTANTS
  73. Const ISDOCFORM = 1 &apos; Form is stored in a Writer document
  74. REM ====================================================== CONSTRUCTOR/DESTRUCTOR
  75. REM -----------------------------------------------------------------------------
  76. Private Sub Class_Initialize()
  77. Set [Me] = Nothing
  78. Set [_Parent] = Nothing
  79. Set [_SubClass] = Nothing
  80. ObjectType = &quot;DOCUMENT&quot;
  81. ServiceName = &quot;SFDocuments.Document&quot;
  82. Set _Component = Nothing
  83. Set _Frame = Nothing
  84. _WindowName = &quot;&quot;
  85. _WindowTitle = &quot;&quot;
  86. _WindowFileName = &quot;&quot;
  87. _DocumentType = &quot;&quot;
  88. Set _DocumentProperties = Nothing
  89. Set _CustomProperties = Nothing
  90. End Sub &apos; SFDocuments.SF_Document Constructor
  91. REM -----------------------------------------------------------------------------
  92. Private Sub Class_Terminate()
  93. Call Class_Initialize()
  94. End Sub &apos; SFDocuments.SF_Document Destructor
  95. REM -----------------------------------------------------------------------------
  96. Public Function Dispose() As Variant
  97. Call Class_Terminate()
  98. Set Dispose = Nothing
  99. End Function &apos; SFDocuments.SF_Document Explicit Destructor
  100. REM ================================================================== PROPERTIES
  101. REM -----------------------------------------------------------------------------
  102. Property Get CustomProperties() As Variant
  103. &apos;&apos;&apos; Returns a dictionary of all custom properties of the document
  104. CustomProperties = _PropertyGet(&quot;CustomProperties&quot;)
  105. End Property &apos; SFDocuments.SF_Document.CustomProperties
  106. REM -----------------------------------------------------------------------------
  107. Property Let CustomProperties(Optional ByVal pvCustomProperties As Variant)
  108. &apos;&apos;&apos; Sets the updatable custom properties
  109. &apos;&apos;&apos; The argument is a dictionary
  110. Dim vPropertyValues As Variant &apos; Array of com.sun.star.beans.PropertyValue
  111. Dim vCustomProperties As Variant &apos; Alias of argument
  112. Dim oUserdefinedProperties As Object &apos; Custom properties object
  113. Dim vOldPropertyValues As Variant &apos; Array of (to remove) existing user defined properties
  114. Dim oProperty As Object &apos; Single com.sun.star.beans.PropertyValues
  115. Dim sProperty As String &apos; Property name
  116. Dim vKeys As Variant &apos; Array of dictionary keys
  117. Dim vItems As Variant &apos; Array of dictionary items
  118. Dim vValue As Variant &apos; Value to store in property
  119. Dim iAttribute As Integer &apos; com.sun.star.beans.PropertyAttribute.REMOVEABLE
  120. Dim i As Long
  121. Const cstThisSub = &quot;SFDocuments.Document.setCustomProperties&quot;
  122. Const cstSubArgs = &quot;CustomProperties&quot;
  123. On Local Error GoTo Catch
  124. Check:
  125. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  126. If Not _IsStillAlive(True) Then GoTo Finally
  127. If Not ScriptForge.SF_Utils._Validate(pvCustomProperties, &quot;CustomProperties&quot;, ScriptForge.V_OBJECT, , , &quot;DICTIONARY&quot;) Then GoTo Finally
  128. End If
  129. Try:
  130. Set oUserDefinedProperties = _Component.getDocumentProperties().UserDefinedProperties
  131. Set vCustomProperties = pvCustomProperties &apos; To avoid &quot;Object variable not set&quot; error
  132. With vCustomProperties
  133. &apos; All existing custom properties must first be removed to avoid type conflicts
  134. vOldPropertyValues = oUserDefinedProperties.getPropertyValues
  135. For Each oProperty In vOldPropertyValues
  136. sProperty = oProperty.Name
  137. oUserDefinedProperties.removeProperty(sProperty)
  138. Next oProperty
  139. &apos; Insert new properties one by one after type adjustment (dates, arrays, numbers)
  140. vKeys = .Keys
  141. vItems = .Items
  142. iAttribute = com.sun.star.beans.PropertyAttribute.REMOVEABLE
  143. For i = 0 To UBound(vKeys)
  144. If VarType(vItems(i)) = V_DATE Then
  145. vValue = ScriptForge.SF_Utils._CDateToUnoDate(vItems(i))
  146. ElseIf IsArray(vItems(i)) Then
  147. vValue = Null
  148. ElseIf ScriptForge.SF_Utils._VarTypeExt(vItems(i)) = ScriptForge.V_NUMERIC Then
  149. vValue = CreateUnoValue(&quot;double&quot;, vItems(i))
  150. Else
  151. vValue = vItems(i)
  152. End If
  153. oUserDefinedProperties.addProperty(vKeys(i), iAttribute, vValue)
  154. Next i
  155. &apos; Declare the document as changed
  156. _Component.setModified(True)
  157. End With
  158. &apos; Reload custom properties in current object instance
  159. _PropertyGet(&quot;CustomProperties&quot;)
  160. Finally:
  161. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  162. Exit Property
  163. Catch:
  164. GoTo Finally
  165. End Property &apos; SFDocuments.SF_Document.CustomProperties
  166. REM -----------------------------------------------------------------------------
  167. Property Get Description() As Variant
  168. &apos;&apos;&apos; Returns the updatable document property Description
  169. Description = _PropertyGet(&quot;Description&quot;)
  170. End Property &apos; SFDocuments.SF_Document.Description
  171. REM -----------------------------------------------------------------------------
  172. Property Let Description(Optional ByVal pvDescription As Variant)
  173. &apos;&apos;&apos; Sets the updatable document property Description
  174. &apos;&apos;&apos; If multilined, separate lines by &quot;\n&quot; escape sequence or by hard breaks
  175. Dim sDescription As String &apos; Alias of pvDescription
  176. Const cstThisSub = &quot;SFDocuments.Document.setDescription&quot;
  177. Const cstSubArgs = &quot;Description&quot;
  178. Check:
  179. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  180. If Not _IsStillAlive(True) Then GoTo Finally
  181. If Not ScriptForge.SF_Utils._Validate(pvDescription, &quot;Description&quot;, V_STRING) Then GoTo Finally
  182. End If
  183. Try:
  184. &apos; Update in UNO component object and in current instance
  185. sDescription = Replace(pvDescription, &quot;\n&quot;, ScriptForge.SF_String.sfNEWLINE)
  186. _Component.DocumentProperties.Description = sDescription
  187. If Not IsNull(_DocumentProperties) Then _DocumentProperties.ReplaceItem(&quot;Description&quot;, sdescription)
  188. Finally:
  189. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  190. Exit Property
  191. End Property &apos; SFDocuments.SF_Document.Description
  192. REM -----------------------------------------------------------------------------
  193. Property Get DocumentProperties() As Variant
  194. &apos;&apos;&apos; Returns a dictionary of all standard document properties, custom properties are excluded
  195. DocumentProperties = _PropertyGet(&quot;DocumentProperties&quot;)
  196. End Property &apos; SFDocuments.SF_Document.DocumentProperties
  197. REM -----------------------------------------------------------------------------
  198. Property Get DocumentType() As String
  199. &apos;&apos;&apos; Returns &quot;Base&quot;, &quot;Calc&quot;, &quot;Draw&quot;, ... or &quot;Writer&quot;
  200. DocumentType = _PropertyGet(&quot;DocumentType&quot;)
  201. End Property &apos; SFDocuments.SF_Document.DocumentType
  202. REM -----------------------------------------------------------------------------
  203. Property Get ExportFilters() As Variant
  204. &apos;&apos;&apos; Returns the list of the export filter names applicable to the current document
  205. &apos;&apos;&apos; as a zero-based array of strings
  206. &apos;&apos;&apos; Import/Export filters are included
  207. ExportFilters = _PropertyGet(&quot;ExportFilters&quot;)
  208. End Property &apos; SFDocuments.SF_Document.ExportFilters
  209. REM -----------------------------------------------------------------------------
  210. Property Get ImportFilters() As Variant
  211. &apos;&apos;&apos; Returns the list of the import filter names applicable to the current document
  212. &apos;&apos;&apos; as a zero-based array of strings
  213. &apos;&apos;&apos; Import/Export filters are included
  214. ImportFilters = _PropertyGet(&quot;ImportFilters&quot;)
  215. End Property &apos; SFDocuments.SF_Document.ImportFilters
  216. REM -----------------------------------------------------------------------------
  217. Property Get IsBase() As Boolean
  218. IsBase = _PropertyGet(&quot;IsBase&quot;)
  219. End Property &apos; SFDocuments.SF_Document.IsBase
  220. REM -----------------------------------------------------------------------------
  221. Property Get IsCalc() As Boolean
  222. IsCalc = _PropertyGet(&quot;IsCalc&quot;)
  223. End Property &apos; SFDocuments.SF_Document.IsCalc
  224. REM -----------------------------------------------------------------------------
  225. Property Get IsDraw() As Boolean
  226. IsDraw = _PropertyGet(&quot;IsDraw&quot;)
  227. End Property &apos; SFDocuments.SF_Document.IsDraw
  228. REM -----------------------------------------------------------------------------
  229. Property Get IsImpress() As Boolean
  230. IsImpress = _PropertyGet(&quot;IsImpress&quot;)
  231. End Property &apos; SFDocuments.SF_Document.IsImpress
  232. REM -----------------------------------------------------------------------------
  233. Property Get IsMath() As Boolean
  234. IsMath = _PropertyGet(&quot;IsMath&quot;)
  235. End Property &apos; SFDocuments.SF_Document.IsMath
  236. REM -----------------------------------------------------------------------------
  237. Property Get IsWriter() As Boolean
  238. IsWriter = _PropertyGet(&quot;IsWriter&quot;)
  239. End Property &apos; SFDocuments.SF_Document.IsWriter
  240. REM -----------------------------------------------------------------------------
  241. Property Get Keywords() As Variant
  242. &apos;&apos;&apos; Returns the updatable document property Keywords
  243. Keywords = _PropertyGet(&quot;Keywords&quot;)
  244. End Property &apos; SFDocuments.SF_Document.Keywords
  245. REM -----------------------------------------------------------------------------
  246. Property Let Keywords(Optional ByVal pvKeywords As Variant)
  247. &apos;&apos;&apos; Sets the updatable document property Keywords
  248. Dim vKeywords As Variant &apos; Alias of pvKeywords
  249. Const cstThisSub = &quot;SFDocuments.Document.setKeywords&quot;
  250. Const cstSubArgs = &quot;Keywords&quot;
  251. Check:
  252. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  253. If Not _IsStillAlive(True) Then GoTo Finally
  254. If Not ScriptForge.SF_Utils._Validate(pvKeywords, &quot;Keywords&quot;, V_STRING) Then GoTo Finally
  255. End If
  256. Try:
  257. &apos; Update in UNO component object and in current instance
  258. vKeywords = ScriptForge.SF_Array.TrimArray(Split(pvKeywords, &quot;,&quot;))
  259. _Component.DocumentProperties.Keywords = vKeywords
  260. If Not IsNull(_DocumentProperties) Then _DocumentProperties.ReplaceItem(&quot;Keywords&quot;, Join(vKeywords, &quot;, &quot;))
  261. Finally:
  262. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  263. Exit Property
  264. End Property &apos; SFDocuments.SF_Document.Keywords
  265. REM -----------------------------------------------------------------------------
  266. Property Get Readonly() As Boolean
  267. &apos;&apos;&apos; Returns True if the document must not be modified
  268. Readonly = _PropertyGet(&quot;Readonly&quot;)
  269. End Property &apos; SFDocuments.SF_Document.Readonly
  270. REM -----------------------------------------------------------------------------
  271. Property Get Subject() As Variant
  272. &apos;&apos;&apos; Returns the updatable document property Subject
  273. Subject = _PropertyGet(&quot;Subject&quot;)
  274. End Property &apos; SFDocuments.SF_Document.Subject
  275. REM -----------------------------------------------------------------------------
  276. Property Let Subject(Optional ByVal pvSubject As Variant)
  277. &apos;&apos;&apos; Sets the updatable document property Subject
  278. Const cstThisSub = &quot;SFDocuments.Document.setSubject&quot;
  279. Const cstSubArgs = &quot;Subject&quot;
  280. Check:
  281. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  282. If Not _IsStillAlive(True) Then GoTo Finally
  283. If Not ScriptForge.SF_Utils._Validate(pvSubject, &quot;Subject&quot;, V_STRING) Then GoTo Finally
  284. End If
  285. Try:
  286. &apos; Update in UNO component object and in current instance
  287. _Component.DocumentProperties.Subject = pvSubject
  288. If Not IsNull(_DocumentProperties) Then _DocumentProperties.ReplaceItem(&quot;Subject&quot;, pvSubject)
  289. Finally:
  290. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  291. Exit Property
  292. End Property &apos; SFDocuments.SF_Document.Subject
  293. REM -----------------------------------------------------------------------------
  294. Property Get Title() As Variant
  295. &apos;&apos;&apos; Returns the updatable document property Title
  296. Title = _PropertyGet(&quot;Title&quot;)
  297. End Property &apos; SFDocuments.SF_Document.Title
  298. REM -----------------------------------------------------------------------------
  299. Property Let Title(Optional ByVal pvTitle As Variant)
  300. &apos;&apos;&apos; Sets the updatable document property Title
  301. Const cstThisSub = &quot;SFDocuments.Document.setTitle&quot;
  302. Const cstSubArgs = &quot;Title&quot;
  303. Check:
  304. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  305. If Not _IsStillAlive(True) Then GoTo Finally
  306. If Not ScriptForge.SF_Utils._Validate(pvTitle, &quot;Title&quot;, V_STRING) Then GoTo Finally
  307. End If
  308. Try:
  309. &apos; Update in UNO component object and in current instance
  310. _Component.DocumentProperties.Title = pvTitle
  311. If Not IsNull(_DocumentProperties) Then _DocumentProperties.ReplaceItem(&quot;Title&quot;, pvTitle)
  312. Finally:
  313. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  314. Exit Property
  315. End Property &apos; SFDocuments.SF_Document.Title
  316. REM -----------------------------------------------------------------------------
  317. Property Get XComponent() As Variant
  318. &apos;&apos;&apos; Returns the com.sun.star.lang.XComponent UNO object representing the document
  319. XComponent = _PropertyGet(&quot;XComponent&quot;)
  320. End Property &apos; SFDocuments.SF_Document.XComponent
  321. REM ===================================================================== METHODS
  322. REM -----------------------------------------------------------------------------
  323. Public Function Activate() As Boolean
  324. &apos;&apos;&apos; Make the current document active
  325. &apos;&apos;&apos; Args:
  326. &apos;&apos;&apos; Returns:
  327. &apos;&apos;&apos; True if the document could be activated
  328. &apos;&apos;&apos; Otherwise, there is no change in the actual user interface
  329. &apos;&apos;&apos; Examples:
  330. &apos;&apos;&apos; oDoc.Activate()
  331. Dim bActivate As Boolean &apos; Return value
  332. Dim oContainer As Object &apos; com.sun.star.awt.XWindow
  333. Const cstThisSub = &quot;SFDocuments.Document.Activate&quot;
  334. Const cstSubArgs = &quot;&quot;
  335. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  336. bActivate = False
  337. Check:
  338. ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
  339. If Not _IsStillAlive() Then GoTo Finally
  340. Try:
  341. Set oContainer = _Frame.ContainerWindow
  342. With oContainer
  343. If .isVisible() = False Then .setVisible(True)
  344. .IsMinimized = False
  345. .setFocus()
  346. .toFront() &apos; Force window change in Linux
  347. Wait 1 &apos; Bypass desynchro issue in Linux
  348. End With
  349. bActivate = True
  350. Finally:
  351. Activate = bActivate
  352. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  353. Exit Function
  354. Catch:
  355. GoTo Finally
  356. End Function &apos; SFDocuments.SF_Document.Activate
  357. REM -----------------------------------------------------------------------------
  358. Public Function CloseDocument(Optional ByVal SaveAsk As Variant) As Boolean
  359. &apos;&apos;&apos; Close the document. Does nothing if the document is already closed
  360. &apos;&apos;&apos; regardless of how the document was closed, manually or by program
  361. &apos;&apos;&apos; Args:
  362. &apos;&apos;&apos; SaveAsk: If True (default), the user is invited to confirm or not the writing of the changes on disk
  363. &apos;&apos;&apos; No effect if the document was not modified
  364. &apos;&apos;&apos; Returns:
  365. &apos;&apos;&apos; False if the user declined to close
  366. &apos;&apos;&apos; Examples:
  367. &apos;&apos;&apos; If oDoc.CloseDocument() Then
  368. &apos;&apos;&apos; &apos; ...
  369. Dim bClosed As Boolean &apos; return value
  370. Dim oDispatch &apos; com.sun.star.frame.DispatchHelper
  371. Const cstThisSub = &quot;SFDocuments.Document.CloseDocument&quot;
  372. Const cstSubArgs = &quot;[SaveAsk=True]&quot;
  373. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  374. bClosed = False
  375. Check:
  376. If IsMissing(SaveAsk) Or IsEmpty(SaveAsk) Then SaveAsk = True
  377. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  378. If Not _IsStillAlive() Then GoTo Finally
  379. If Not ScriptForge.SF_Utils._Validate(SaveAsk, &quot;SaveAsk&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
  380. End If
  381. Try:
  382. If SaveAsk And _Component.IsModified Then &apos; Execute closure with the File/Close menu command
  383. Activate()
  384. RunCommand(&quot;CloseDoc&quot;)
  385. bClosed = _IsStillAlive(, False) &apos; Do not raise error
  386. Else
  387. _Frame.close(True)
  388. _Frame.dispose()
  389. bClosed = True
  390. End If
  391. Finally:
  392. If bClosed Then Dispose()
  393. CloseDocument = bClosed
  394. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  395. Exit Function
  396. Catch:
  397. GoTo Finally
  398. End Function &apos; SFDocuments.SF_Document.CloseDocument
  399. REM -----------------------------------------------------------------------------
  400. Public Function CreateMenu(Optional ByVal MenuHeader As Variant _
  401. , Optional ByVal Before As Variant _
  402. , Optional ByVal SubmenuChar As Variant _
  403. , Optional ByRef _Document As Variant _
  404. ) As Object
  405. &apos;&apos;&apos; Create a new menu entry in the document&apos;s menubar
  406. &apos;&apos;&apos; The menu is not intended to be saved neither in the LibreOffice global environment, nor in the document
  407. &apos;&apos;&apos; The method returns a SFWidgets.Menu instance. Its methods let define the menu further.
  408. &apos;&apos;&apos; Args:
  409. &apos;&apos;&apos; MenuHeader: the name/header of the menu
  410. &apos;&apos;&apos; Before: the place where to put the new menu on the menubar (string or number &gt;= 1)
  411. &apos;&apos;&apos; When not found =&gt; last position
  412. &apos;&apos;&apos; SubmenuChar: the delimiter used in menu trees. Default = &quot;&gt;&quot;
  413. &apos;&apos;&apos; _Document: undocumented argument to designate the document where the menu will be located
  414. &apos;&apos;&apos; Returns:
  415. &apos;&apos;&apos; A SFWidgets.Menu instance or Nothing
  416. &apos;&apos;&apos; Examples:
  417. &apos;&apos;&apos; Dim oMenu As Object
  418. &apos;&apos;&apos; Set oMenu = oDoc.CreateMenu(&quot;My menu&quot;, Before := &quot;Styles&quot;)
  419. &apos;&apos;&apos; With oMenu
  420. &apos;&apos;&apos; .AddItem(&quot;Item 1&quot;, Command := &quot;About&quot;)
  421. &apos;&apos;&apos; &apos;...
  422. &apos;&apos;&apos; .Dispose() &apos; When definition is complete, the menu instance may be disposed
  423. &apos;&apos;&apos; End With
  424. &apos;&apos;&apos; &apos; ...
  425. Dim oMenu As Object &apos; return value
  426. Const cstThisSub = &quot;SFDocuments.Document.CreateMenu&quot;
  427. Const cstSubArgs = &quot;MenuHeader, [Before=&quot;&quot;&quot;&quot;], [SubmenuChar=&quot;&quot;&gt;&quot;&quot;]&quot;
  428. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  429. Set oMenu = Nothing
  430. Check:
  431. If IsMissing(Before) Or IsEmpty(Before) Then Before = &quot;&quot;
  432. If IsMissing(SubmenuChar) Or IsEmpty(SubmenuChar) Then SubmenuChar = &quot;&quot;
  433. If IsMissing(_Document) Or IsEmpty(_Document) Or IsNull(_Document) Then Set _Document = _Component
  434. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  435. If Not _IsStillAlive() Then GoTo Finally
  436. If Not ScriptForge.SF_Utils._Validate(MenuHeader, &quot;MenuHeader&quot;, V_STRING) Then GoTo Finally
  437. If Not ScriptForge.SF_Utils._Validate(Before, &quot;Before&quot;, V_STRING) Then GoTo Finally
  438. If Not ScriptForge.SF_Utils._Validate(SubmenuChar, &quot;SubmenuChar&quot;, V_STRING) Then GoTo Finally
  439. End If
  440. Try:
  441. Set oMenu = ScriptForge.SF_Services.CreateScriptService(&quot;SFWidgets.Menu&quot;, _Document, MenuHeader, Before, SubmenuChar)
  442. Finally:
  443. Set CreateMenu = oMenu
  444. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  445. Exit Function
  446. Catch:
  447. GoTo Finally
  448. End Function &apos; SFDocuments.SF_Document.CreateMenu
  449. REM -----------------------------------------------------------------------------
  450. Public Function ExportAsPDF(Optional ByVal FileName As Variant _
  451. , Optional ByVal Overwrite As Variant _
  452. , Optional ByVal Pages As Variant _
  453. , Optional ByVal Password As Variant _
  454. , Optional ByVal Watermark As Variant _
  455. ) As Boolean
  456. &apos;&apos;&apos; Store the document to the given file location in PDF format
  457. &apos;&apos;&apos; Args:
  458. &apos;&apos;&apos; FileName: Identifies the file where to save. It must follow the SF_FileSystem.FileNaming notation
  459. &apos;&apos;&apos; Overwrite: True if the destination file may be overwritten (default = False)
  460. &apos;&apos;&apos; Pages: the pages to print as a string, like in the user interface. Example: &quot;1-4;10;15-18&quot;. Default = all pages
  461. &apos;&apos;&apos; Password: password to open the document
  462. &apos;&apos;&apos; Watermark: the text for a watermark to be drawn on every page of the exported PDF file
  463. &apos;&apos;&apos; Returns:
  464. &apos;&apos;&apos; False if the document could not be saved
  465. &apos;&apos;&apos; Exceptions:
  466. &apos;&apos;&apos; DOCUMENTSAVEASERROR The destination has its readonly attribute set or overwriting rejected
  467. &apos;&apos;&apos; Examples:
  468. &apos;&apos;&apos; oDoc.ExportAsPDF(&quot;C:\Me\myDoc.pdf&quot;, Overwrite := True)
  469. Dim bSaved As Boolean &apos; return value
  470. Dim oSfa As Object &apos; com.sun.star.ucb.SimpleFileAccess
  471. Dim sFile As String &apos; Alias of FileName
  472. Dim sFilter As String &apos; One of the pdf filter names
  473. Dim vFilterData As Variant &apos; Array of com.sun.star.beans.PropertyValue
  474. Dim vProperties As Variant &apos; Array of com.sun.star.beans.PropertyValue
  475. Dim FSO As Object &apos; SF_FileSystem
  476. Const cstThisSub = &quot;SFDocuments.Document.ExportAsPDF&quot;
  477. Const cstSubArgs = &quot;FileName, [Overwrite=False], [Pages=&quot;&quot;&quot;&quot;], [Password=&quot;&quot;&quot;&quot;], [Watermark=&quot;&quot;&quot;&quot;]&quot;
  478. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo CatchError
  479. bSaved = False
  480. Check:
  481. If IsMissing(Overwrite) Or IsEmpty(Overwrite) Then Overwrite = False
  482. If IsMissing(Pages) Or IsEmpty(Pages) Then Pages = &quot;&quot;
  483. If IsMissing(Password) Or IsEmpty(Password) Then Password = &quot;&quot;
  484. If IsMissing(Watermark) Or IsEmpty(Watermark) Then Watermark = &quot;&quot;
  485. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  486. If Not _IsStillAlive() Then GoTo Finally
  487. If Not SF_Utils._ValidateFile(FileName, &quot;FileName&quot;) Then GoTo Finally
  488. If Not SF_Utils._Validate(Overwrite, &quot;Overwrite&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
  489. If Not SF_Utils._Validate(Pages, &quot;Pages&quot;, V_STRING) Then GoTo Finally
  490. If Not SF_Utils._Validate(Password, &quot;Password&quot;, V_STRING) Then GoTo Finally
  491. If Not SF_Utils._Validate(Watermark, &quot;Watermark&quot;, V_STRING) Then GoTo Finally
  492. End If
  493. &apos; Check destination file overwriting
  494. Set FSO = CreateScriptService(&quot;FileSystem&quot;)
  495. sFile = FSO._ConvertToUrl(FileName)
  496. If FSO.FileExists(FileName) Then
  497. If Overwrite = False Then GoTo CatchError
  498. Set oSfa = ScriptForge.SF_Utils._GetUNOService(&quot;FileAccess&quot;)
  499. If oSfa.isReadonly(sFile) Then GoTo CatchError
  500. End If
  501. Try:
  502. &apos; Setup arguments
  503. sFilter = LCase(_DocumentType) &amp; &quot;_pdf_Export&quot;
  504. &apos; FilterData parameters are added only if they are meaningful
  505. vFilterData = Array()
  506. If Len(Pages) &gt; 0 Then
  507. vFilterData = ScriptForge.SF_Array.Append(vFilterData _
  508. , ScriptForge.SF_Utils._MakePropertyValue(&quot;PageRange&quot;, Pages))
  509. End If
  510. If Len(Password) &gt; 0 Then
  511. vFilterData = ScriptForge.SF_Array.Append(vFilterData _
  512. , ScriptForge.SF_Utils._MakePropertyValue(&quot;EncryptFile&quot;, True) _
  513. , ScriptForge.SF_Utils._MakePropertyValue(&quot;DocumentOpenPassword&quot;, Password))
  514. End If
  515. If Len(Watermark) &gt; 0 Then
  516. vFilterData = ScriptForge.SF_Array.Append(vFilterData _
  517. , ScriptForge.SF_Utils._MakePropertyValue(&quot;Watermark&quot;, Watermark))
  518. End If
  519. &apos; Finalize properties and export
  520. vProperties = Array( _
  521. ScriptForge.SF_Utils._MakePropertyValue(&quot;FilterName&quot;, sFilter) _
  522. , ScriptForge.SF_Utils._MakePropertyValue(&quot;FilterData&quot;, vFilterData))
  523. _Component.StoreToURL(sFile, vProperties)
  524. bSaved = True
  525. Finally:
  526. ExportAsPDF = bSaved
  527. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  528. Exit Function
  529. Catch:
  530. GoTo Finally
  531. CatchError:
  532. ScriptForge.SF_Exception.RaiseFatal(DOCUMENTSAVEASERROR, &quot;FileName&quot;, FileName, &quot;Overwrite&quot;, Overwrite _
  533. , &quot;FilterName&quot;, &quot;PDF Export&quot;)
  534. GoTo Finally
  535. End Function &apos; SFDocuments.SF_Document.ExportAsPDF
  536. REM -----------------------------------------------------------------------------
  537. Public Function GetProperty(Optional ByVal PropertyName As Variant) As Variant
  538. &apos;&apos;&apos; Return the actual value of the given property
  539. &apos;&apos;&apos; Args:
  540. &apos;&apos;&apos; PropertyName: the name of the property as a string
  541. &apos;&apos;&apos; Returns:
  542. &apos;&apos;&apos; The actual value of the property
  543. &apos;&apos;&apos; If the property does not exist, returns Null
  544. &apos;&apos;&apos; Exceptions:
  545. &apos;&apos;&apos; see the exceptions of the individual properties
  546. &apos;&apos;&apos; Examples:
  547. &apos;&apos;&apos; myModel.GetProperty(&quot;MyProperty&quot;)
  548. Const cstThisSub = &quot;SFDocuments.Document.GetProperty&quot;
  549. Const cstSubArgs = &quot;&quot;
  550. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  551. GetProperty = Null
  552. Check:
  553. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  554. If Not ScriptForge.SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
  555. End If
  556. Try:
  557. GetProperty = _PropertyGet(PropertyName)
  558. Finally:
  559. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  560. Exit Function
  561. Catch:
  562. GoTo Finally
  563. End Function &apos; SFDocuments.SF_Document.GetProperty
  564. REM -----------------------------------------------------------------------------
  565. Public Function Methods() As Variant
  566. &apos;&apos;&apos; Return the list of public methods of the Document service as an array
  567. Methods = Array( _
  568. &quot;Activate&quot; _
  569. , &quot;CloseDocument&quot; _
  570. , &quot;CreateMenu&quot; _
  571. , &quot;ExportAsPDF&quot; _
  572. , &quot;PrintOut&quot; _
  573. , &quot;RemoveMenu&quot; _
  574. , &quot;RunCommand&quot; _
  575. , &quot;Save&quot; _
  576. , &quot;SaveAs&quot; _
  577. , &quot;SaveCopyAs&quot; _
  578. , &quot;SetPrinter&quot; _
  579. )
  580. End Function &apos; SFDocuments.SF_Document.Methods
  581. REM -----------------------------------------------------------------------------
  582. Public Function PrintOut(Optional ByVal Pages As Variant _
  583. , Optional ByVal Copies As Variant _
  584. , Optional ByRef _Document As Variant _
  585. ) As Boolean
  586. &apos;&apos;&apos; Send the content of the document to the printer.
  587. &apos;&apos;&apos; The printer might be defined previously by default, by the user or by the SetPrinter() method
  588. &apos;&apos;&apos; Args:
  589. &apos;&apos;&apos; Pages: the pages to print as a string, like in the user interface. Example: &quot;1-4;10;15-18&quot;. Default = all pages
  590. &apos;&apos;&apos; Copies: the number of copies
  591. &apos;&apos;&apos; _Document: undocumented argument to designate the document to print when called from a subclass
  592. &apos;&apos;&apos; Returns:
  593. &apos;&apos;&apos; True when successful
  594. &apos;&apos;&apos; Examples:
  595. &apos;&apos;&apos; oDoc.PrintOut(&quot;1-4;10;15-18&quot;, Copies := 2)
  596. Dim bPrint As Boolean &apos; Return value
  597. Dim vPrintGoal As Variant &apos; Array of property values
  598. Const cstThisSub = &quot;SFDocuments.Document.PrintOut&quot;
  599. Const cstSubArgs = &quot;[Pages=&quot;&quot;&quot;&quot;], [Copies=1]&quot;
  600. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  601. bPrint = False
  602. Check:
  603. If IsMissing(Pages) Or IsEmpty(Pages) Then Pages = &quot;&quot;
  604. If IsMissing(Copies) Or IsEmpty(Copies) Then Copies = 1
  605. If IsMissing(_Document) Or IsEmpty(_Document) Or IsNull(_Document) Then Set _Document = _Component
  606. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  607. If Not _IsStillAlive() Then GoTo Finally
  608. If Not ScriptForge.SF_Utils._Validate(Pages, &quot;Pages&quot;, V_STRING) Then GoTo Finally
  609. If Not ScriptForge.SF_Utils._Validate(Copies, &quot;Copies&quot;, ScriptForge.V_NUMERIC) Then GoTo Finally
  610. End If
  611. Try:
  612. vPrintGoal = Array( _
  613. ScriptForge.SF_Utils._MakePropertyValue(&quot;CopyCount&quot;, CInt(Copies)) _
  614. , ScriptForge.SF_Utils._MakePropertyValue(&quot;Collate&quot;, True) _
  615. , ScriptForge.SF_Utils._MakePropertyValue(&quot;Pages&quot;, Pages) _
  616. , ScriptForge.SF_Utils._MakePropertyValue(&quot;Wait&quot;, False) _
  617. )
  618. _Document.Print(vPrintGoal)
  619. bPrint = True
  620. Finally:
  621. PrintOut = bPrint
  622. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  623. Exit Function
  624. Catch:
  625. GoTo Finally
  626. End Function &apos; SFDocuments.SF_Document.PrintOut
  627. REM -----------------------------------------------------------------------------
  628. Public Function Properties() As Variant
  629. &apos;&apos;&apos; Return the list or properties of the Document class as an array
  630. Properties = Array( _
  631. &quot;CustomProperties&quot; _
  632. , &quot;Description&quot; _
  633. , &quot;DocumentProperties&quot; _
  634. , &quot;DocumentType&quot; _
  635. , &quot;ExportFilters&quot; _
  636. , &quot;ImportFilters&quot; _
  637. , &quot;IsBase&quot; _
  638. , &quot;IsCalc&quot; _
  639. , &quot;IsDraw&quot; _
  640. , &quot;IsImpress&quot; _
  641. , &quot;IsMath&quot; _
  642. , &quot;IsWriter&quot; _
  643. , &quot;Keywords&quot; _
  644. , &quot;Readonly&quot; _
  645. , &quot;Subject&quot; _
  646. , &quot;Title&quot; _
  647. , &quot;XComponent&quot; _
  648. )
  649. End Function &apos; SFDocuments.SF_Document.Properties
  650. REM -----------------------------------------------------------------------------
  651. Public Function RemoveMenu(Optional ByVal MenuHeader As Variant _
  652. , Optional ByRef _Document As Variant _
  653. ) As Boolean
  654. &apos;&apos;&apos; Remove a menu entry in the document&apos;s menubar
  655. &apos;&apos;&apos; The removal is not intended to be saved neither in the LibreOffice global environment, nor in the document
  656. &apos;&apos;&apos; Args:
  657. &apos;&apos;&apos; MenuHeader: the name/header of the menu, without tilde &quot;~&quot;, as a case-sensitive string
  658. &apos;&apos;&apos; _Document: undocumented argument to designate the document where the menu is located
  659. &apos;&apos;&apos; Returns:
  660. &apos;&apos;&apos; True when successful
  661. &apos;&apos;&apos; Examples:
  662. &apos;&apos;&apos; oDoc.RemoveMenu(&quot;File&quot;)
  663. &apos;&apos;&apos; &apos; ...
  664. Dim bRemove As Boolean &apos; Return value
  665. Dim oLayout As Object &apos; com.sun.star.comp.framework.LayoutManager
  666. Dim oMenuBar As Object &apos; com.sun.star.awt.XMenuBar or stardiv.Toolkit.VCLXMenuBar
  667. Dim sName As String &apos; Menu name
  668. Dim iMenuId As Integer &apos; Menu identifier
  669. Dim iMenuPosition As Integer &apos; Menu position &gt;= 0
  670. Dim i As Integer
  671. Const cstTilde = &quot;~&quot;
  672. Const cstThisSub = &quot;SFDocuments.Document.RemoveMenu&quot;
  673. Const cstSubArgs = &quot;MenuHeader&quot;
  674. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  675. bRemove = False
  676. Check:
  677. If IsMissing(_Document) Or IsEmpty(_Document) Or IsNull(_Document) Then Set _Document = _Component
  678. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  679. If Not _IsStillAlive() Then GoTo Finally
  680. If Not ScriptForge.SF_Utils._Validate(MenuHeader, &quot;MenuHeader&quot;, V_STRING) Then GoTo Finally
  681. End If
  682. Try:
  683. Set oLayout = _Document.CurrentController.Frame.LayoutManager
  684. Set oMenuBar = oLayout.getElement(&quot;private:resource/menubar/menubar&quot;).XMenuBar
  685. &apos; Search the menu identifier to remove by its name, Mark its position
  686. With oMenuBar
  687. iMenuPosition = -1
  688. For i = 0 To .ItemCount - 1
  689. iMenuId = .getItemId(i)
  690. sName = Replace(.getItemText(iMenuId), cstTilde, &quot;&quot;)
  691. If MenuHeader= sName Then
  692. iMenuPosition = i
  693. Exit For
  694. End If
  695. Next i
  696. &apos; Remove the found menu item
  697. If iMenuPosition &gt;= 0 Then
  698. .removeItem(iMenuPosition, 1)
  699. bRemove = True
  700. End If
  701. End With
  702. Finally:
  703. RemoveMenu = bRemove
  704. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  705. Exit Function
  706. Catch:
  707. GoTo Finally
  708. End Function &apos; SFDocuments.SF_Document.RemoveMenu
  709. REM -----------------------------------------------------------------------------
  710. Public Sub RunCommand(Optional ByVal Command As Variant _
  711. , ParamArray Args As Variant _
  712. )
  713. &apos;&apos;&apos; Run on the current document window the given menu command. The command is executed with or without arguments
  714. &apos;&apos;&apos; A few typical commands:
  715. &apos;&apos;&apos; Save, SaveAs, ExportToPDF, SetDocumentProperties, Undo, Copy, Paste, ...
  716. &apos;&apos;&apos; Dozens can be found on next page: https://wiki.documentfoundation.org/Development/DispatchCommands
  717. &apos;&apos;&apos; Args:
  718. &apos;&apos;&apos; Command: Case-sensitive. The command itself is not checked.
  719. &apos;&apos;&apos; If the command does not contain the &quot;.uno:&quot; prefix, it is added.
  720. &apos;&apos;&apos; If nothing happens, then the command is probably wrong
  721. &apos;&apos;&apos; Args: Pairs of arguments name (string), value (any)
  722. &apos;&apos;&apos; Returns:
  723. &apos;&apos;&apos; Examples:
  724. &apos;&apos;&apos; oDoc.RunCommand(&quot;EditDoc&quot;, &quot;Editable&quot;, False) &apos; Toggle edit mode
  725. Dim vArgs As Variant &apos; Alias of Args
  726. Dim oDispatch &apos; com.sun.star.frame.DispatchHelper
  727. Dim vProps As Variant &apos; Array of PropertyValues
  728. Dim vValue As Variant &apos; A single value argument
  729. Dim sCommand As String &apos; Alias of Command
  730. Dim i As Long
  731. Const cstPrefix = &quot;.uno:&quot;
  732. Const cstThisSub = &quot;SFDocuments.Document.RunCommand&quot;
  733. Const cstSubArgs = &quot;Command, [arg0Name, arg0Value], [arg1Name, arg1Value], ...&quot;
  734. If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  735. Check:
  736. &apos; When called from a subclass (Calc, Writer, ..) the arguments are gathered into one single array item
  737. vArgs = Args
  738. If IsArray(Args) Then
  739. If UBound(Args) &gt;= 0 Then
  740. If IsArray(Args(0)) Then vArgs = Args(0)
  741. End If
  742. End If
  743. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  744. If Not _IsStillAlive() Then GoTo Finally
  745. If Not ScriptForge.SF_Utils._Validate(Command, &quot;Command&quot;, V_STRING) Then GoTo Finally
  746. If Not ScriptForge.SF_Utils._ValidateArray(vArgs, &quot;Args&quot;, 1) Then GoTo Finally
  747. For i = 0 To UBound(vArgs) - 1 Step 2
  748. If Not ScriptForge.SF_Utils._Validate(vArgs(i), &quot;Arg&quot; &amp; CStr(i/2) &amp; &quot;Name&quot;, V_STRING) Then GoTo Finally
  749. Next i
  750. End If
  751. Try:
  752. &apos; Build array of property values
  753. vProps = Array()
  754. For i = 0 To UBound(vArgs) - 1 Step 2
  755. If IsEmpty(vArgs(i + 1)) Then vValue = Null Else vValue = vArgs(i + 1)
  756. vProps = ScriptForge.SF_Array.Append(vProps, ScriptForge.SF_Utils._MakePropertyValue(vArgs(i), vValue))
  757. Next i
  758. Set oDispatch = ScriptForge.SF_Utils._GetUNOService(&quot;DispatchHelper&quot;)
  759. If ScriptForge.SF_String.StartsWith(Command, cstPrefix) Then sCommand = Command Else sCommand = cstPrefix &amp; Command
  760. oDispatch.executeDispatch(_Frame, sCommand, &quot;&quot;, 0, vProps)
  761. Finally:
  762. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  763. Exit Sub
  764. Catch:
  765. GoTo Finally
  766. End Sub &apos; SFDocuments.SF_Document.RunCommand
  767. REM -----------------------------------------------------------------------------
  768. Public Function Save() As Boolean
  769. &apos;&apos;&apos; Store the document to the file location from which it was loaded
  770. &apos;&apos;&apos; Ignored if the document was not modified
  771. &apos;&apos;&apos; Args:
  772. &apos;&apos;&apos; Returns:
  773. &apos;&apos;&apos; False if the document could not be saved
  774. &apos;&apos;&apos; Exceptions:
  775. &apos;&apos;&apos; DOCUMENTSAVEERROR The file has been opened readonly or was opened as new and was not yet saved
  776. &apos;&apos;&apos; Examples:
  777. &apos;&apos;&apos; If Not oDoc.Save() Then
  778. &apos;&apos;&apos; &apos; ...
  779. Dim bSaved As Boolean &apos; return value
  780. Const cstThisSub = &quot;SFDocuments.Document.Save&quot;
  781. Const cstSubArgs = &quot;&quot;
  782. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  783. bSaved = False
  784. Check:
  785. ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
  786. If Not _IsStillAlive() Then GoTo Finally
  787. bSaved = False
  788. Try:
  789. With _Component
  790. If .isReadonly() Or Not .hasLocation() Then GoTo CatchReadonly
  791. If .IsModified() Then
  792. .store()
  793. bSaved = True
  794. End If
  795. End With
  796. Finally:
  797. Save = bSaved
  798. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  799. Exit Function
  800. Catch:
  801. GoTo Finally
  802. CatchReadonly:
  803. ScriptForge.SF_Exception.RaiseFatal(DOCUMENTSAVEERROR, &quot;FileName&quot;, _FileIdent())
  804. GoTo Finally
  805. End Function &apos; SFDocuments.SF_Document.Save
  806. REM -----------------------------------------------------------------------------
  807. Public Function SaveAs(Optional ByVal FileName As Variant _
  808. , Optional ByVal Overwrite As Variant _
  809. , Optional ByVal Password As Variant _
  810. , Optional ByVal FilterName As Variant _
  811. , Optional ByVal FilterOptions As Variant _
  812. ) As Boolean
  813. &apos;&apos;&apos; Store the document to the given file location
  814. &apos;&apos;&apos; The new location becomes the new file name on which simple Save method calls will be applied
  815. &apos;&apos;&apos; Args:
  816. &apos;&apos;&apos; FileName: Identifies the file where to save. It must follow the SF_FileSystem.FileNaming notation
  817. &apos;&apos;&apos; Overwrite: True if the destination file may be overwritten (default = False)
  818. &apos;&apos;&apos; Password: Use to protect the document
  819. &apos;&apos;&apos; FilterName: the name of a filter that should be used for saving the document
  820. &apos;&apos;&apos; If present, the filter must exist
  821. &apos;&apos;&apos; FilterOptions: an optional string of options associated with the filter
  822. &apos;&apos;&apos; Returns:
  823. &apos;&apos;&apos; False if the document could not be saved
  824. &apos;&apos;&apos; Exceptions:
  825. &apos;&apos;&apos; DOCUMENTSAVEASERROR The destination has its readonly attribute set or overwriting rejected
  826. &apos;&apos;&apos; Examples:
  827. &apos;&apos;&apos; oDoc.SaveAs(&quot;C:\Me\Copy2.odt&quot;, Overwrite := True)
  828. Dim bSaved As Boolean &apos; return value
  829. Dim oFilterFactory As Object &apos; com.sun.star.document.FilterFactory
  830. Dim oSfa As Object &apos; com.sun.star.ucb.SimpleFileAccess
  831. Dim sFile As String &apos; Alias of FileName
  832. Dim vProperties As Variant &apos; Array of com.sun.star.beans.PropertyValue
  833. Dim FSO As Object &apos; SF_FileSystem
  834. Const cstThisSub = &quot;SFDocuments.Document.SaveAs&quot;
  835. Const cstSubArgs = &quot;FileName, [Overwrite=False], [Password=&quot;&quot;&quot;&quot;], [FilterName=&quot;&quot;&quot;&quot;], [FilterOptions=&quot;&quot;&quot;&quot;]&quot;
  836. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo CatchError
  837. bSaved = False
  838. Check:
  839. If IsMissing(Overwrite) Or IsEmpty(Overwrite) Then Overwrite = False
  840. If IsMissing(Password) Or IsEmpty(Password) Then Password = &quot;&quot;
  841. If IsMissing(FilterName) Or IsEmpty(FilterName) Then FilterName = &quot;&quot;
  842. If IsMissing(FilterOptions) Or IsEmpty(FilterOptions) Then FilterOptions = &quot;&quot;
  843. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  844. If Not _IsStillAlive() Then GoTo Finally
  845. If Not SF_Utils._ValidateFile(FileName, &quot;FileName&quot;) Then GoTo Finally
  846. If Not SF_Utils._Validate(Overwrite, &quot;Overwrite&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
  847. If Not SF_Utils._Validate(Password, &quot;Password&quot;, V_STRING) Then GoTo Finally
  848. If Not SF_Utils._Validate(FilterName, &quot;FilterName&quot;, V_STRING) Then GoTo Finally
  849. If Not SF_Utils._Validate(FilterOptions, &quot;FilterOptions&quot;, V_STRING) Then GoTo Finally
  850. End If
  851. &apos; Check that the filter exists
  852. If Len(FilterName) &gt; 0 Then
  853. Set oFilterFactory = ScriptForge.SF_Utils._GetUNOService(&quot;FilterFactory&quot;)
  854. If Not oFilterFactory.hasByName(FilterName) Then GoTo CatchError
  855. End If
  856. &apos; Check destination file overwriting
  857. Set FSO = CreateScriptService(&quot;FileSystem&quot;)
  858. sFile = FSO._ConvertToUrl(FileName)
  859. If FSO.FileExists(FileName) Then
  860. If Overwrite = False Then GoTo CatchError
  861. Set oSfa = ScriptForge.SF_Utils._GetUNOService(&quot;FileAccess&quot;)
  862. If oSfa.isReadonly(sFile) Then GoTo CatchError
  863. End If
  864. Try:
  865. &apos; Setup arguments
  866. If Len(Password) + Len(FilterName) = 0 Then
  867. vProperties = Array()
  868. Else
  869. vProperties = Array( _
  870. ScriptForge.SF_Utils._MakePropertyValue(&quot;FilterName&quot;, FilterName) _
  871. , ScriptForge.SF_Utils._MakePropertyValue(&quot;FilterOptions&quot;, FilterOptions) _
  872. )
  873. If Len(Password) &gt; 0 Then &apos; Password is to add only if &lt;&gt; &quot;&quot; !?
  874. vProperties = ScriptForge.SF_Array.Append(vProperties _
  875. , ScriptForge.SF_Utils._MakePropertyValue(&quot;Password&quot;, Password))
  876. End If
  877. End If
  878. _Component.StoreAsURL(sFile, vProperties)
  879. &apos; Remind the new file name
  880. _WindowFileName = sFile
  881. _WindowName = FSO.GetName(FileName)
  882. bSaved = True
  883. Finally:
  884. SaveAs = bSaved
  885. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  886. Exit Function
  887. Catch:
  888. GoTo Finally
  889. CatchError:
  890. ScriptForge.SF_Exception.RaiseFatal(DOCUMENTSAVEASERROR, &quot;FileName&quot;, FileName, &quot;Overwrite&quot;, Overwrite _
  891. , &quot;FilterName&quot;, FilterName)
  892. GoTo Finally
  893. End Function &apos; SFDocuments.SF_Document.SaveAs
  894. REM -----------------------------------------------------------------------------
  895. Public Function SaveCopyAs(Optional ByVal FileName As Variant _
  896. , Optional ByVal Overwrite As Variant _
  897. , Optional ByVal Password As Variant _
  898. , Optional ByVal FilterName As Variant _
  899. , Optional ByVal FilterOptions As Variant _
  900. ) As Boolean
  901. &apos;&apos;&apos; Store a copy or export the document to the given file location
  902. &apos;&apos;&apos; The actual location is unchanged
  903. &apos;&apos;&apos; Args:
  904. &apos;&apos;&apos; FileName: Identifies the file where to save. It must follow the SF_FileSystem.FileNaming notation
  905. &apos;&apos;&apos; Overwrite: True if the destination file may be overwritten (default = False)
  906. &apos;&apos;&apos; Password: Use to protect the document
  907. &apos;&apos;&apos; FilterName: the name of a filter that should be used for saving the document
  908. &apos;&apos;&apos; If present, the filter must exist
  909. &apos;&apos;&apos; FilterOptions: an optional string of options associated with the filter
  910. &apos;&apos;&apos; Returns:
  911. &apos;&apos;&apos; False if the document could not be saved
  912. &apos;&apos;&apos; Exceptions:
  913. &apos;&apos;&apos; DOCUMENTSAVEASERROR The destination has its readonly attribute set or overwriting rejected
  914. &apos;&apos;&apos; Examples:
  915. &apos;&apos;&apos; oDoc.SaveCopyAs(&quot;C:\Me\Copy2.odt&quot;, Overwrite := True)
  916. Dim bSaved As Boolean &apos; return value
  917. Dim oFilterFactory As Object &apos; com.sun.star.document.FilterFactory
  918. Dim oSfa As Object &apos; com.sun.star.ucb.SimpleFileAccess
  919. Dim sFile As String &apos; Alias of FileName
  920. Dim vProperties As Variant &apos; Array of com.sun.star.beans.PropertyValue
  921. Dim FSO As Object &apos; SF_FileSystem
  922. Const cstThisSub = &quot;SFDocuments.Document.SaveCopyAs&quot;
  923. Const cstSubArgs = &quot;FileName, [Overwrite=False], [Password=&quot;&quot;&quot;&quot;], [FilterName=&quot;&quot;&quot;&quot;], [FilterOptions=&quot;&quot;&quot;&quot;]&quot;
  924. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo CatchError
  925. bSaved = False
  926. Check:
  927. If IsMissing(Overwrite) Or IsEmpty(Overwrite) Then Overwrite = False
  928. If IsMissing(Password) Or IsEmpty(Password) Then Password = &quot;&quot;
  929. If IsMissing(FilterName) Or IsEmpty(FilterName) Then FilterName = &quot;&quot;
  930. If IsMissing(FilterOptions) Or IsEmpty(FilterOptions) Then FilterOptions = &quot;&quot;
  931. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  932. If Not _IsStillAlive() Then GoTo Finally
  933. If Not SF_Utils._ValidateFile(FileName, &quot;FileName&quot;) Then GoTo Finally
  934. If Not SF_Utils._Validate(Overwrite, &quot;Overwrite&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
  935. If Not SF_Utils._Validate(Password, &quot;Password&quot;, V_STRING) Then GoTo Finally
  936. If Not SF_Utils._Validate(FilterName, &quot;FilterName&quot;, V_STRING) Then GoTo Finally
  937. If Not SF_Utils._Validate(FilterOptions, &quot;FilterOptions&quot;, V_STRING) Then GoTo Finally
  938. End If
  939. &apos; Check that the filter exists
  940. If Len(FilterName) &gt; 0 Then
  941. Set oFilterFactory = ScriptForge.SF_Utils._GetUNOService(&quot;FilterFactory&quot;)
  942. If Not oFilterFactory.hasByName(FilterName) Then GoTo CatchError
  943. End If
  944. &apos; Check destination file overwriting
  945. Set FSO = CreateScriptService(&quot;FileSystem&quot;)
  946. sFile = FSO._ConvertToUrl(FileName)
  947. If FSO.FileExists(FileName) Then
  948. If Overwrite = False Then GoTo CatchError
  949. Set oSfa = ScriptForge.SF_Utils._GetUNOService(&quot;FileAccess&quot;)
  950. If oSfa.isReadonly(sFile) Then GoTo CatchError
  951. End If
  952. Try:
  953. &apos; Setup arguments
  954. If Len(Password) + Len(FilterName) = 0 Then
  955. vProperties = Array()
  956. Else
  957. vProperties = Array( _
  958. ScriptForge.SF_Utils._MakePropertyValue(&quot;FilterName&quot;, FilterName) _
  959. , ScriptForge.SF_Utils._MakePropertyValue(&quot;FilterOptions&quot;, FilterOptions) _
  960. )
  961. If Len(Password) &gt; 0 Then &apos; Password is to add only if &lt;&gt; &quot;&quot; !?
  962. vProperties = ScriptForge.SF_Array.Append(vProperties _
  963. , ScriptForge.SF_Utils._MakePropertyValue(&quot;Password&quot;, Password))
  964. End If
  965. End If
  966. _Component.StoreToURL(sFile, vProperties)
  967. bSaved = True
  968. Finally:
  969. SaveCopyAs = bSaved
  970. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  971. Exit Function
  972. Catch:
  973. GoTo Finally
  974. CatchError:
  975. ScriptForge.SF_Exception.RaiseFatal(DOCUMENTSAVEASERROR, &quot;FileName&quot;, FileName, &quot;Overwrite&quot;, Overwrite _
  976. , &quot;FilterName&quot;, FilterName)
  977. GoTo Finally
  978. End Function &apos; SFDocuments.SF_Document.SaveCopyAs
  979. REM -----------------------------------------------------------------------------
  980. Public Function SetPrinter(Optional ByVal Printer As Variant _
  981. , Optional ByVal Orientation As Variant _
  982. , Optional ByVal PaperFormat As Variant _
  983. , Optional ByRef _PrintComponent As Variant _
  984. ) As Boolean
  985. &apos;&apos;&apos; Define the printer options for the document
  986. &apos;&apos;&apos; Args:
  987. &apos;&apos;&apos; Printer: the name of the printer queue where to print to
  988. &apos;&apos;&apos; When absent or space, the default printer is set
  989. &apos;&apos;&apos; Orientation: either &quot;PORTRAIT&quot; or &quot;LANDSCAPE&quot;. Left unchanged when absent
  990. &apos;&apos;&apos; PaperFormat: one of next values
  991. &apos;&apos;&apos; &quot;A3&quot;, &quot;A4&quot;, &quot;A5&quot;, &quot;B4&quot;, &quot;B5&quot;, &quot;LETTER&quot;, &quot;LEGAL&quot;, &quot;TABLOID&quot;
  992. &apos;&apos;&apos; Left unchanged when absent
  993. &apos;&apos;&apos; _PrintComponent: undocumented argument to determine the component
  994. &apos;&apos;&apos; Useful typically to apply printer settings on a Base form document
  995. &apos;&apos;&apos; Returns:
  996. &apos;&apos;&apos; True when successful
  997. &apos;&apos;&apos; Examples:
  998. &apos;&apos;&apos; oDoc.SetPrinter(Orientation := &quot;PORTRAIT&quot;)
  999. Dim bPrinter As Boolean &apos; Return value
  1000. Dim vPrinters As Variant &apos; Array of known printers
  1001. Dim vOrientations As Variant &apos; Array of allowed paper orientations
  1002. Dim vPaperFormats As Variant &apos; Array of allowed formats
  1003. Dim vPrinterSettings As Variant &apos; Array of property values
  1004. Dim oPropertyValue As New com.sun.star.beans.PropertyValue
  1005. &apos; A single property value item
  1006. Const cstThisSub = &quot;SFDocuments.Document.SetPrinter&quot;
  1007. Const cstSubArgs = &quot;[Printer=&quot;&quot;&quot;&quot;], [Orientation=&quot;&quot;PORTRAIT&quot;&quot;|&quot;&quot;LANDSCAPE&quot;&quot;]&quot; _
  1008. &amp; &quot;, [PaperFormat=&quot;&quot;A3&quot;&quot;|&quot;&quot;A4&quot;&quot;|&quot;&quot;A5&quot;&quot;|&quot;&quot;B4&quot;&quot;|&quot;&quot;B5&quot;&quot;|&quot;&quot;LETTER&quot;&quot;|&quot;&quot;LEGAL&quot;&quot;|&quot;&quot;TABLOID&quot;&quot;&quot;
  1009. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  1010. bPrinter = False
  1011. Check:
  1012. If IsMissing(Printer) Or IsEmpty(Printer) Then Printer = &quot;&quot;
  1013. If IsMissing(Orientation) Or IsEmpty(Orientation) Then Orientation = &quot;&quot;
  1014. If IsMissing(PaperFormat) Or IsEmpty(PaperFormat) Then PaperFormat = &quot;&quot;
  1015. If IsMissing(_PrintComponent) Or IsEmpty(_PrintComponent) Then Set _PrintComponent = _Component
  1016. ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) &apos; Unconditional validation
  1017. If Not _IsStillAlive() Then GoTo Finally
  1018. If VarType(Printer) = V_STRING Then
  1019. vPrinters = ScriptForge.SF_Platform.Printers
  1020. If Len(Printer) &gt; 0 Then
  1021. If Not ScriptForge.SF_Utils._Validate(Printer, &quot;Printer&quot;, V_STRING, vPrinters) Then GoTo Finally
  1022. End If
  1023. Else
  1024. If Not ScriptForge.SF_Utils._Validate(Printer, &quot;Printer&quot;, V_STRING) Then GoTo Finally &apos; Manage here the VarType error
  1025. End If
  1026. If VarType(Orientation) = V_STRING Then
  1027. vOrientations = Array(&quot;PORTRAIT&quot;, &quot;LANDSCAPE&quot;)
  1028. If Len(Orientation) &gt; 0 Then
  1029. If Not ScriptForge.SF_Utils._Validate(Orientation, &quot;Orientation&quot;, V_STRING, vOrientations) Then GoTo Finally
  1030. End If
  1031. Else
  1032. If Not ScriptForge.SF_Utils._Validate(Orientation, &quot;Orientation&quot;, V_STRING) Then GoTo Finally
  1033. End If
  1034. If VarType(PaperFormat) = V_STRING Then
  1035. vPaperFormats = Array(&quot;A3&quot;, &quot;A4&quot;, &quot;A5&quot;, &quot;B4&quot;, &quot;B5&quot;, &quot;LETTER&quot;, &quot;LEGAL&quot;, &quot;TABLOID&quot;)
  1036. If Len(PaperFormat) &gt; 0 Then
  1037. If Not ScriptForge.SF_Utils._Validate(PaperFormat, &quot;PaperFormat&quot;, V_STRING, vPaperFormats) Then GoTo Finally
  1038. End If
  1039. Else
  1040. If Not ScriptForge.SF_Utils._Validate(PaperFormat, &quot;PaperFormat&quot;, V_STRING) Then GoTo Finally
  1041. End If
  1042. Try:
  1043. With _PrintComponent
  1044. Set oPropertyValue = ScriptForge.SF_Utils._MakePropertyValue(&quot;Name&quot;, Iif(Len(Printer) &gt; 0, Printer, vPrinters(0)))
  1045. vPrinterSettings = Array(oPropertyValue)
  1046. If Len(Orientation) &gt; 0 Then
  1047. vPrinterSettings = ScriptForge.SF_Utils._SetPropertyValue(vPrinterSettings, &quot;PaperOrientation&quot; _
  1048. , ScriptForge.SF_Array.IndexOf(vOrientations, Orientation, CaseSensitive := False))
  1049. End If
  1050. If Len(PaperFormat) &gt; 0 Then
  1051. vPrinterSettings = ScriptForge.SF_Utils._SetPropertyValue(vPrinterSettings, &quot;PaperFormat&quot; _
  1052. , ScriptForge.SF_Array.IndexOf(vPaperFormats, PaperFormat, CaseSensitive := False))
  1053. End If
  1054. .setPrinter(vPrinterSettings)
  1055. End With
  1056. bPrinter = True
  1057. Finally:
  1058. SetPrinter = bPrinter
  1059. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  1060. Exit Function
  1061. Catch:
  1062. GoTo Finally
  1063. End Function &apos; SFDocuments.SF_Document.SetPrinter
  1064. REM -----------------------------------------------------------------------------
  1065. Private Function SetProperty(Optional ByVal psProperty As String _
  1066. , Optional ByVal pvValue As Variant _
  1067. ) As Boolean
  1068. &apos;&apos;&apos; Set the new value of the named property
  1069. &apos;&apos;&apos; Args:
  1070. &apos;&apos;&apos; psProperty: the name of the property
  1071. &apos;&apos;&apos; pvValue: the new value of the given property
  1072. &apos;&apos;&apos; Returns:
  1073. &apos;&apos;&apos; True if successful
  1074. Dim bSet As Boolean &apos; Return value
  1075. Static oSession As Object &apos; Alias of SF_Session
  1076. Dim cstThisSub As String
  1077. Const cstSubArgs = &quot;Value&quot;
  1078. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  1079. bSet = False
  1080. cstThisSub = &quot;SFDocuments.Document.set&quot; &amp; psProperty
  1081. If IsMissing(pvValue) Then pvValue = Empty
  1082. &apos;ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) &apos; Validation done in Property Lets
  1083. If IsNull(oSession) Then Set oSession = ScriptForge.SF_Services.CreateScriptService(&quot;Session&quot;)
  1084. bSet = True
  1085. Select Case UCase(psProperty)
  1086. Case UCase(&quot;CustomProperties&quot;)
  1087. CustomProperties = pvValue
  1088. Case UCase(&quot;Description&quot;)
  1089. Description = pvValue
  1090. Case UCase(&quot;Keywords&quot;)
  1091. Keywords = pvValue
  1092. Case UCase(&quot;Subject&quot;)
  1093. Subject = pvValue
  1094. Case UCase(&quot;Title&quot;)
  1095. Title = pvValue
  1096. Case Else
  1097. bSet = False
  1098. End Select
  1099. Finally:
  1100. SetProperty = bSet
  1101. &apos;ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  1102. Exit Function
  1103. Catch:
  1104. GoTo Finally
  1105. End Function &apos; SFDocuments.SF_Document.SetProperty
  1106. REM =========================================================== PRIVATE FUNCTIONS
  1107. REM -----------------------------------------------------------------------------
  1108. Private Function _FileIdent() As String
  1109. &apos;&apos;&apos; Returns a file identification from the information that is currently available
  1110. &apos;&apos;&apos; Useful e.g. for display in error messages
  1111. &apos; OS notation is used to avoid presence of &quot;%nn&quot; in error messages and wrong parameter substitutions
  1112. _FileIdent = Iif(Len(_WindowFileName) &gt; 0, ConvertFromUrl(_WindowFileName), _WindowTitle)
  1113. End Function &apos; SFDocuments.SF_Document._FileIdent
  1114. REM -----------------------------------------------------------------------------
  1115. Private Function _GetFilterNames(ByVal pbExport As Boolean) As Variant
  1116. &apos;&apos;&apos; Returns the list of export (pbExport = True) or import filters
  1117. &apos;&apos;&apos; applicable to the current document
  1118. &apos;&apos;&apos; Args:
  1119. &apos;&apos;&apos; pbExport: True for export, False for import
  1120. &apos;&apos;&apos; Returns:
  1121. &apos;&apos;&apos; A zero-based array of strings
  1122. Dim vFilters As Variant &apos; Return value
  1123. Dim sIdentifier As String &apos; Document service, like com.sun.star.text.TextDocument
  1124. Dim oFilterFactory As Object &apos; com.sun.star.document.FilterFactory
  1125. Dim vAllFilters As Variant &apos; The full list of installed filters
  1126. Dim sFilter As String &apos; A single filter name
  1127. Dim iCount As Integer &apos; Filters counter
  1128. Dim vFilter As Variant &apos; A filter descriptor as an array of Name/Value pairs
  1129. Dim sType As String &apos; The filter type to be compared with the document service
  1130. Dim lFlags As Long &apos; Read https://wiki.documentfoundation.org/Documentation/DevGuide/Office_Development#Properties_of_a_Filter
  1131. Dim bExport As Boolean &apos; Filter valid for export when True
  1132. Dim bImport As Boolean &apos; Filter valid for import when True
  1133. Dim bImportExport As Boolean &apos; Filter valid both for import and export when True
  1134. vFilters = Array()
  1135. On Local Error GoTo Finally &apos; Return empty or partial list if error
  1136. Try:
  1137. sIdentifier = _Component.Identifier
  1138. Set oFilterFactory = ScriptForge.SF_Utils._GetUNOService(&quot;FilterFactory&quot;)
  1139. vAllFilters = oFilterFactory.getElementNames()
  1140. ReDim vFilters(0 To UBound(vAllFilters))
  1141. iCount = -1
  1142. For Each sFilter In vAllFilters
  1143. vFilter = oFilterFactory.getByName(sFilter)
  1144. sType = ScriptForge.SF_Utils._GetPropertyValue(vFilter, &quot;DocumentService&quot;)
  1145. If sType = sIdentifier Then
  1146. lFlags = ScriptForge.SF_Utils._GetPropertyValue(vFilter, &quot;Flags&quot;)
  1147. &apos; export: flag is even
  1148. &apos; import: flag is odd and flag/2 is even
  1149. &apos; import/export: flag is odd and flag/2 is odd
  1150. bExport = ( lFlags Mod 2 = 0 )
  1151. bImport = ( (lFlags Mod 2 = 1) And ((lFlags \ 2) Mod 2 = 0) )
  1152. bImportExport = ( (lFlags Mod 2 = 1) And ((lFlags \ 2) Mod 2 = 1) )
  1153. &apos; Select filter ?
  1154. If bImportExport _
  1155. Or (pbExport And bExport) _
  1156. Or (Not pbExport And bImport) Then
  1157. iCount = iCount + 1
  1158. vFilters(iCount) = sFilter
  1159. End If
  1160. End If
  1161. Next sFilter
  1162. If iCount &gt; -1 Then
  1163. ReDim Preserve vFilters(0 To iCount)
  1164. End If
  1165. Finally:
  1166. _GetFilterNames = vFilters
  1167. Exit Function
  1168. End Function &apos; SFDocuments.SF_Document._GetFilterNames
  1169. REM -----------------------------------------------------------------------------
  1170. Private Function _IsStillAlive(Optional ByVal pbForUpdate As Boolean _
  1171. , Optional ByVal pbError As Boolean _
  1172. ) As Boolean
  1173. &apos;&apos;&apos; Returns True if the document has not been closed manually or incidentally since the last use
  1174. &apos;&apos;&apos; If dead the actual instance is disposed. The execution is cancelled when pbError = True (default)
  1175. &apos;&apos;&apos; Args:
  1176. &apos;&apos;&apos; pbForUpdate: if True (default = False), check additionally if document is open for editing
  1177. &apos;&apos;&apos; pbError: if True (default), raise a fatal error
  1178. Dim bAlive As Boolean &apos; Return value
  1179. Dim sFileName As String &apos; File identification used to display error message
  1180. On Local Error GoTo Catch &apos; Anticipate DisposedException errors or alike
  1181. If IsMissing(pbForUpdate) Then pbForUpdate = False
  1182. If IsMissing(pbError) Then pbError = True
  1183. Try:
  1184. &apos; Check existence of document
  1185. bAlive = Not IsNull(_Frame)
  1186. If bAlive Then bAlive = Not IsNull(_Component)
  1187. If bAlive Then bAlive = Not IsNull(_Component.CurrentController)
  1188. &apos; Check document is not read only
  1189. If bAlive And pbForUpdate Then
  1190. If _Component.isreadonly() Then GoTo CatchReadonly
  1191. End If
  1192. Finally:
  1193. _IsStillAlive = bAlive
  1194. Exit Function
  1195. Catch:
  1196. bAlive = False
  1197. On Error GoTo 0
  1198. sFileName = _FileIdent()
  1199. Dispose()
  1200. If pbError Then ScriptForge.SF_Exception.RaiseFatal(DOCUMENTDEADERROR, sFileName)
  1201. GoTo Finally
  1202. CatchReadonly:
  1203. bAlive = False
  1204. If pbError Then ScriptForge.SF_Exception.RaiseFatal(DOCUMENTREADONLYERROR, &quot;Document&quot;, _FileIdent())
  1205. GoTo Finally
  1206. End Function &apos; SFDocuments.SF_Document._IsStillAlive
  1207. REM -----------------------------------------------------------------------------
  1208. Private Sub _LoadDocumentProperties()
  1209. &apos;&apos;&apos; Create dictionary with document properties as entries/ Custom properties are excluded
  1210. &apos;&apos;&apos; Document is presumed still alive
  1211. &apos;&apos;&apos; Special values:
  1212. &apos;&apos;&apos; Only valid dates are taken
  1213. &apos;&apos;&apos; Statistics are exploded in subitems. Subitems are specific to document type
  1214. &apos;&apos;&apos; Keywords are joined
  1215. &apos;&apos;&apos; Language is aligned on L10N convention la-CO
  1216. Dim oProperties As Object &apos; Document properties
  1217. Dim vNamedValue As Variant &apos; com.sun.star.beans.NamedValue
  1218. If IsNull(_DocumentProperties) Then
  1219. Set oProperties = _Component.getDocumentProperties
  1220. Set _DocumentProperties = CreateScriptService(&quot;Dictionary&quot;)
  1221. With _DocumentProperties
  1222. .Add(&quot;Author&quot;, oProperties.Author)
  1223. .Add(&quot;AutoloadSecs&quot;, oProperties.AutoloadSecs)
  1224. .Add(&quot;AutoloadURL&quot;, oProperties.AutoloadURL)
  1225. If oProperties.CreationDate.Year &gt; 0 Then .Add(&quot;CreationDate&quot;, CDateFromUnoDateTime(oProperties.CreationDate))
  1226. .Add(&quot;DefaultTarget&quot;, oProperties.DefaultTarget)
  1227. .Add(&quot;Description&quot;, oProperties.Description) &apos; The description can be multiline
  1228. &apos; DocumentStatistics : number and names of statistics depend on document type
  1229. For Each vNamedValue In oProperties.DocumentStatistics
  1230. .Add(vNamedValue.Name, vNamedValue.Value)
  1231. Next vNamedValue
  1232. .Add(&quot;EditingDuration&quot;, oProperties.EditingDuration)
  1233. .Add(&quot;Generator&quot;, oProperties.Generator)
  1234. .Add(&quot;Keywords&quot;, Join(oProperties.Keywords, &quot;, &quot;))
  1235. .Add(&quot;Language&quot;, oProperties.Language.Language &amp; Iif(Len(oProperties.Language.Country) &gt; 0, &quot;-&quot; &amp; oProperties.Language.Country, &quot;&quot;))
  1236. If oProperties.ModificationDate.Year &gt; 0 Then .Add(&quot;ModificationDate&quot;, CDateFromUnoDateTime(oProperties.ModificationDate))
  1237. If oProperties.PrintDate.Year &gt; 0 Then .Add(&quot;PrintDate&quot;, CDateFromUnoDateTime(oProperties.PrintDate))
  1238. .Add(&quot;PrintedBy&quot;, oProperties.PrintedBy)
  1239. .Add(&quot;Subject&quot;, oProperties.Subject)
  1240. If oProperties.TemplateDate.Year &gt; 0 Then .Add(&quot;TemplateDate&quot;, CDateFromUnoDateTime(oProperties.TemplateDate))
  1241. .Add(&quot;TemplateName&quot;, oProperties.TemplateName)
  1242. .Add(&quot;TemplateURL&quot;, oProperties.TemplateURL)
  1243. .Add(&quot;Title&quot;, oProperties.Title)
  1244. End With
  1245. End If
  1246. End Sub &apos; SFDocuments.SF_Document._LoadDocumentProperties
  1247. REM -----------------------------------------------------------------------------
  1248. Private Function _PropertyGet(Optional ByVal psProperty As String) As Variant
  1249. &apos;&apos;&apos; Return the value of the named property
  1250. &apos;&apos;&apos; Args:
  1251. &apos;&apos;&apos; psProperty: the name of the property
  1252. Dim oProperties As Object &apos; Document or Custom properties
  1253. Dim cstThisSub As String
  1254. Const cstSubArgs = &quot;&quot;
  1255. _PropertyGet = False
  1256. Select Case _DocumentType
  1257. Case &quot;Calc&quot; : cstThisSub = &quot;SFDocuments.SF_&quot; &amp; _DocumentType &amp; &quot;.get&quot; &amp; psProperty
  1258. Case Else : cstThisSub = &quot;SFDocuments.SF_Document.get&quot; &amp; psProperty
  1259. End Select
  1260. ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
  1261. If Not _IsStillAlive() Then GoTo Finally
  1262. Select Case psProperty
  1263. Case &quot;CustomProperties&quot;
  1264. _CustomProperties = CreateScriptService(&quot;Dictionary&quot;) &apos; Always reload as updates could have been done manually by user
  1265. _CustomProperties.ImportFromPropertyValues(_Component.getDocumentProperties().UserDefinedProperties.getPropertyValues)
  1266. _PropertyGet = _CustomProperties
  1267. Case &quot;Description&quot;
  1268. _PropertyGet = _Component.DocumentProperties.Description
  1269. Case &quot;DocumentProperties&quot;
  1270. _LoadDocumentProperties() &apos; Always reload as updates could have been done manually by user
  1271. Set _PropertyGet = _DocumentProperties
  1272. Case &quot;DocumentType&quot;
  1273. _PropertyGet = _DocumentType
  1274. Case &quot;ExportFilters&quot;
  1275. _PropertyGet = _GetFilterNames(True)
  1276. Case &quot;ImportFilters&quot;
  1277. _PropertyGet = _GetFilterNames(False)
  1278. Case &quot;IsBase&quot;, &quot;IsCalc&quot;, &quot;IsDraw&quot;, &quot;IsImpress&quot;, &quot;IsMath&quot;, &quot;IsWriter&quot;
  1279. _PropertyGet = ( Mid(psProperty, 3) = _DocumentType )
  1280. Case &quot;Keywords&quot;
  1281. _PropertyGet = Join(_Component.DocumentProperties.Keywords, &quot;, &quot;)
  1282. Case &quot;Readonly&quot;
  1283. _PropertyGet = _Component.isReadonly()
  1284. Case &quot;Subject&quot;
  1285. _PropertyGet = _Component.DocumentProperties.Subject
  1286. Case &quot;Title&quot;
  1287. _PropertyGet = _Component.DocumentProperties.Title
  1288. Case &quot;XComponent&quot;
  1289. Set _PropertyGet = _Component
  1290. Case Else
  1291. _PropertyGet = Null
  1292. End Select
  1293. Finally:
  1294. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  1295. Exit Function
  1296. End Function &apos; SFDocuments.SF_Document._PropertyGet
  1297. REM -----------------------------------------------------------------------------
  1298. Private Function _Repr() As String
  1299. &apos;&apos;&apos; Convert the SF_Document instance to a readable string, typically for debugging purposes (DebugPrint ...)
  1300. &apos;&apos;&apos; Args:
  1301. &apos;&apos;&apos; Return:
  1302. &apos;&apos;&apos; &quot;[DOCUMENT]: Type - File&quot;
  1303. _Repr = &quot;[Document]: &quot; &amp; _DocumentType &amp; &quot; - &quot; &amp; _FileIdent()
  1304. End Function &apos; SFDocuments.SF_Document._Repr
  1305. REM ============================================ END OF SFDOCUMENTS.SF_DOCUMENT
  1306. </script:module>