SF_Document.xba 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010
  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; the management and several manipulations of 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_Writer, ...
  23. &apos;&apos;&apos;
  24. &apos;&apos;&apos; To workaround the absence of class inheritance in LibreOffice Basic, some redundancy is necessary
  25. &apos;&apos;&apos; Each subclass MUST implement also the generic methods and properties, even if they only call
  26. &apos;&apos;&apos; the parent methods and properties implemented below
  27. &apos;&apos;&apos; They should also duplicate some generic private members as a subset of their own set of members
  28. &apos;&apos;&apos;
  29. &apos;&apos;&apos; The current module is closely related to the &quot;UI&quot; and &quot;FileSystem&quot; services
  30. &apos;&apos;&apos; of the ScriptForge library
  31. &apos;&apos;&apos;
  32. &apos;&apos;&apos; Service invocation examples:
  33. &apos;&apos;&apos; 1) From the UI service
  34. &apos;&apos;&apos; Dim ui As Object, oDoc As Object
  35. &apos;&apos;&apos; Set ui = CreateScriptService(&quot;UI&quot;)
  36. &apos;&apos;&apos; Set oDoc = ui.GetDocument(&quot;Untitled 1&quot;)
  37. &apos;&apos;&apos; &apos; or Set oDoc = ui.CreateDocument(&quot;Calc&quot;, ...)
  38. &apos;&apos;&apos; &apos; or Set oDoc = ui.OpenDocument(&quot;C:\Me\MyFile.odt&quot;)
  39. &apos;&apos;&apos; 2) Directly if the document is already opened
  40. &apos;&apos;&apos; Dim oDoc As Object
  41. &apos;&apos;&apos; Set oDoc = CreateScriptService(&quot;SFDocuments.Document&quot;, &quot;Untitled 1&quot;) &apos; Default = ActiveWindow
  42. &apos;&apos;&apos; &apos; The substring &quot;SFDocuments.&quot; in the service name is optional
  43. &apos;&apos;&apos;
  44. &apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
  45. REM ================================================================== EXCEPTIONS
  46. Private Const DOCUMENTDEADERROR = &quot;DOCUMENTDEADERROR&quot;
  47. Private Const DOCUMENTSAVEERROR = &quot;DOCUMENTSAVEERROR&quot;
  48. Private Const DOCUMENTSAVEASERROR = &quot;DOCUMENTSAVEASERROR&quot;
  49. Private Const DOCUMENTREADONLYERROR = &quot;DOCUMENTREADONLYERROR&quot;
  50. REM ============================================================= PRIVATE MEMBERS
  51. Private [Me] As Object
  52. Private [_Parent] As Object
  53. Private ObjectType As String &apos; Must be DOCUMENT
  54. Private ServiceName As String
  55. &apos; Window description
  56. Private _Component As Object &apos; com.sun.star.lang.XComponent
  57. Private _Frame As Object &apos; com.sun.star.comp.framework.Frame
  58. Private _WindowName As String &apos; Object Name
  59. Private _WindowTitle As String &apos; Only mean to identify new documents
  60. Private _WindowFileName As String &apos; URL of file name
  61. Private _DocumentType As String &apos; Writer, Calc, ...
  62. &apos; Properties (work variables - real properties could have been set manually by user)
  63. Private _DocumentProperties As Object &apos; Dictionary of document properties
  64. Private _CustomProperties As Object &apos; Dictionary of custom properties
  65. REM ============================================================ MODULE CONSTANTS
  66. REM ===================================================== CONSTRUCTOR/DESTRUCTOR
  67. REM -----------------------------------------------------------------------------
  68. Private Sub Class_Initialize()
  69. Set [Me] = Nothing
  70. Set [_Parent] = Nothing
  71. ObjectType = &quot;DOCUMENT&quot;
  72. ServiceName = &quot;SFDocuments.Document&quot;
  73. Set _Component = Nothing
  74. Set _Frame = Nothing
  75. _WindowName = &quot;&quot;
  76. _WindowTitle = &quot;&quot;
  77. _WindowFileName = &quot;&quot;
  78. _DocumentType = &quot;&quot;
  79. Set _DocumentProperties = Nothing
  80. Set _CustomProperties = Nothing
  81. End Sub &apos; SFDocuments.SF_Document Constructor
  82. REM -----------------------------------------------------------------------------
  83. Private Sub Class_Terminate()
  84. Call Class_Initialize()
  85. End Sub &apos; SFDocuments.SF_Document Destructor
  86. REM -----------------------------------------------------------------------------
  87. Public Function Dispose() As Variant
  88. Call Class_Terminate()
  89. Set Dispose = Nothing
  90. End Function &apos; SFDocuments.SF_Document Explicit Destructor
  91. REM ================================================================== PROPERTIES
  92. REM -----------------------------------------------------------------------------
  93. Property Get CustomProperties() As Variant
  94. &apos;&apos;&apos; Returns a dictionary of all custom properties of the document
  95. CustomProperties = _PropertyGet(&quot;CustomProperties&quot;)
  96. End Property &apos; SFDocuments.SF_Document.CustomProperties
  97. REM -----------------------------------------------------------------------------
  98. Property Let CustomProperties(Optional ByVal pvCustomProperties As Variant)
  99. &apos;&apos;&apos; Sets the updatable custom properties
  100. &apos;&apos;&apos; The argument is a dictionary
  101. Dim vPropertyValues As Variant &apos; Array of com.sun.star.beans.PropertyValue
  102. Dim vCustomProperties As Variant &apos; Alias of argument
  103. Dim oUserdefinedProperties As Object &apos; Custom properties object
  104. Dim vOldPropertyValues As Variant &apos; Array of (to remove) existing user defined properties
  105. Dim oProperty As Object &apos; Single com.sun.star.beans.PropertyValues
  106. Dim sProperty As String &apos; Property name
  107. Dim vKeys As Variant &apos; Array of dictionary keys
  108. Dim vItems As Variant &apos; Array of dictionary items
  109. Dim vValue As Variant &apos; Value to store in property
  110. Dim iAttribute As Integer &apos; com.sun.star.beans.PropertyAttribute.REMOVEABLE
  111. Dim i As Long
  112. Const cstThisSub = &quot;SFDocuments.Document.setCustomProperties&quot;
  113. Const cstSubArgs = &quot;CustomProperties&quot;
  114. On Local Error GoTo Catch
  115. Check:
  116. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  117. If Not _IsStillAlive(True) Then GoTo Finally
  118. If Not ScriptForge.SF_Utils._Validate(pvCustomProperties, &quot;CustomProperties&quot;, ScriptForge.V_OBJECT, , , &quot;DICTIONARY&quot;) Then GoTo Finally
  119. End If
  120. Try:
  121. Set oUserDefinedProperties = _Component.getDocumentProperties().UserDefinedProperties
  122. Set vCustomProperties = pvCustomProperties &apos; To avoid &quot;Object variable not set&quot; error
  123. With vCustomProperties
  124. &apos; All existing custom properties must first be removed to avoid type conflicts
  125. vOldPropertyValues = oUserDefinedProperties.getPropertyValues
  126. For Each oProperty In vOldPropertyValues
  127. sProperty = oProperty.Name
  128. oUserDefinedProperties.removeProperty(sProperty)
  129. Next oProperty
  130. &apos; Insert new properties one by one after type adjustment (dates, arrays, numbers)
  131. vKeys = .Keys
  132. vItems = .Items
  133. iAttribute = com.sun.star.beans.PropertyAttribute.REMOVEABLE
  134. For i = 0 To UBound(vKeys)
  135. If VarType(vItems(i)) = V_DATE Then
  136. vValue = ScriptForge.SF_Utils._CDateToUnoDate(vItems(i))
  137. ElseIf IsArray(vItems(i)) Then
  138. vValue = Null
  139. ElseIf ScriptForge.SF_Utils._VarTypeExt(vItems(i)) = ScriptForge.V_NUMERIC Then
  140. vValue = CreateUnoValue(&quot;double&quot;, vItems(i))
  141. Else
  142. vValue = vItems(i)
  143. End If
  144. oUserDefinedProperties.addProperty(vKeys(i), iAttribute, vValue)
  145. Next i
  146. &apos; Declare the document as changed
  147. _Component.setModified(True)
  148. End With
  149. &apos; Reload custom properties in current object instance
  150. _PropertyGet(&quot;CustomProperties&quot;)
  151. Finally:
  152. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  153. Exit Property
  154. Catch:
  155. GoTo Finally
  156. End Property &apos; SFDocuments.SF_Document.CustomProperties
  157. REM -----------------------------------------------------------------------------
  158. Property Get Description() As Variant
  159. &apos;&apos;&apos; Returns the updatable document property Description
  160. Description = _PropertyGet(&quot;Description&quot;)
  161. End Property &apos; SFDocuments.SF_Document.Description
  162. REM -----------------------------------------------------------------------------
  163. Property Let Description(Optional ByVal pvDescription As Variant)
  164. &apos;&apos;&apos; Sets the updatable document property Description
  165. &apos;&apos;&apos; If multilined, separate lines by &quot;\n&quot; escape sequence or by hard breaks
  166. Dim sDescription As String &apos; Alias of pvDescription
  167. Const cstThisSub = &quot;SFDocuments.Document.setDescription&quot;
  168. Const cstSubArgs = &quot;Description&quot;
  169. Check:
  170. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  171. If Not _IsStillAlive(True) Then GoTo Finally
  172. If Not ScriptForge.SF_Utils._Validate(pvDescription, &quot;Description&quot;, V_STRING) Then GoTo Finally
  173. End If
  174. Try:
  175. &apos; Update in UNO component object and in current instance
  176. sDescription = Replace(pvDescription, &quot;\n&quot;, ScriptForge.SF_String.sfNEWLINE)
  177. _Component.DocumentProperties.Description = sDescription
  178. If Not IsNull(_DocumentProperties) Then _DocumentProperties.ReplaceItem(&quot;Description&quot;, sdescription)
  179. Finally:
  180. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  181. Exit Property
  182. End Property &apos; SFDocuments.SF_Document.Description
  183. REM -----------------------------------------------------------------------------
  184. Property Get DocumentProperties() As Variant
  185. &apos;&apos;&apos; Returns a dictionary of all standard document properties, custom properties are excluded
  186. DocumentProperties = _PropertyGet(&quot;DocumentProperties&quot;)
  187. End Property &apos; SFDocuments.SF_Document.DocumentProperties
  188. REM -----------------------------------------------------------------------------
  189. Property Get DocumentType() As String
  190. &apos;&apos;&apos; Returns &quot;Base&quot;, &quot;Calc&quot;, &quot;Draw&quot;, ... or &quot;Writer&quot;
  191. DocumentType = _PropertyGet(&quot;DocumentType&quot;)
  192. End Property &apos; SFDocuments.SF_Document.DocumentType
  193. REM -----------------------------------------------------------------------------
  194. Property Get IsBase() As Boolean
  195. IsBase = _PropertyGet(&quot;IsBase&quot;)
  196. End Property &apos; SFDocuments.SF_Document.IsBase
  197. REM -----------------------------------------------------------------------------
  198. Property Get IsCalc() As Boolean
  199. IsCalc = _PropertyGet(&quot;IsCalc&quot;)
  200. End Property &apos; SFDocuments.SF_Document.IsCalc
  201. REM -----------------------------------------------------------------------------
  202. Property Get IsDraw() As Boolean
  203. IsDraw = _PropertyGet(&quot;IsDraw&quot;)
  204. End Property &apos; SFDocuments.SF_Document.IsDraw
  205. REM -----------------------------------------------------------------------------
  206. Property Get IsImpress() As Boolean
  207. IsImpress = _PropertyGet(&quot;IsImpress&quot;)
  208. End Property &apos; SFDocuments.SF_Document.IsImpress
  209. REM -----------------------------------------------------------------------------
  210. Property Get IsMath() As Boolean
  211. IsMath = _PropertyGet(&quot;IsMath&quot;)
  212. End Property &apos; SFDocuments.SF_Document.IsMath
  213. REM -----------------------------------------------------------------------------
  214. Property Get IsWriter() As Boolean
  215. IsWriter = _PropertyGet(&quot;IsWriter&quot;)
  216. End Property &apos; SFDocuments.SF_Document.IsWriter
  217. REM -----------------------------------------------------------------------------
  218. Property Get Keywords() As Variant
  219. &apos;&apos;&apos; Returns the updatable document property Keywords
  220. Keywords = _PropertyGet(&quot;Keywords&quot;)
  221. End Property &apos; SFDocuments.SF_Document.Keywords
  222. REM -----------------------------------------------------------------------------
  223. Property Let Keywords(Optional ByVal pvKeywords As Variant)
  224. &apos;&apos;&apos; Sets the updatable document property Keywords
  225. Dim vKeywords As Variant &apos; Alias of pvKeywords
  226. Const cstThisSub = &quot;SFDocuments.Document.setKeywords&quot;
  227. Const cstSubArgs = &quot;Keywords&quot;
  228. Check:
  229. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  230. If Not _IsStillAlive(True) Then GoTo Finally
  231. If Not ScriptForge.SF_Utils._Validate(pvKeywords, &quot;Keywords&quot;, V_STRING) Then GoTo Finally
  232. End If
  233. Try:
  234. &apos; Update in UNO component object and in current instance
  235. vKeywords = ScriptForge.SF_Array.TrimArray(Split(pvKeywords, &quot;,&quot;))
  236. _Component.DocumentProperties.Keywords = vKeywords
  237. If Not IsNull(_DocumentProperties) Then _DocumentProperties.ReplaceItem(&quot;Keywords&quot;, Join(vKeywords, &quot;, &quot;))
  238. Finally:
  239. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  240. Exit Property
  241. End Property &apos; SFDocuments.SF_Document.Keywords
  242. REM -----------------------------------------------------------------------------
  243. Property Get Readonly() As Boolean
  244. &apos;&apos;&apos; Returns True if the document must not be modified
  245. Readonly = _PropertyGet(&quot;Readonly&quot;)
  246. End Property &apos; SFDocuments.SF_Document.Readonly
  247. REM -----------------------------------------------------------------------------
  248. Property Get Subject() As Variant
  249. &apos;&apos;&apos; Returns the updatable document property Subject
  250. Subject = _PropertyGet(&quot;Subject&quot;)
  251. End Property &apos; SFDocuments.SF_Document.Subject
  252. REM -----------------------------------------------------------------------------
  253. Property Let Subject(Optional ByVal pvSubject As Variant)
  254. &apos;&apos;&apos; Sets the updatable document property Subject
  255. Const cstThisSub = &quot;SFDocuments.Document.setSubject&quot;
  256. Const cstSubArgs = &quot;Subject&quot;
  257. Check:
  258. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  259. If Not _IsStillAlive(True) Then GoTo Finally
  260. If Not ScriptForge.SF_Utils._Validate(pvSubject, &quot;Subject&quot;, V_STRING) Then GoTo Finally
  261. End If
  262. Try:
  263. &apos; Update in UNO component object and in current instance
  264. _Component.DocumentProperties.Subject = pvSubject
  265. If Not IsNull(_DocumentProperties) Then _DocumentProperties.ReplaceItem(&quot;Subject&quot;, pvSubject)
  266. Finally:
  267. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  268. Exit Property
  269. End Property &apos; SFDocuments.SF_Document.Subject
  270. REM -----------------------------------------------------------------------------
  271. Property Get Title() As Variant
  272. &apos;&apos;&apos; Returns the updatable document property Title
  273. Title = _PropertyGet(&quot;Title&quot;)
  274. End Property &apos; SFDocuments.SF_Document.Title
  275. REM -----------------------------------------------------------------------------
  276. Property Let Title(Optional ByVal pvTitle As Variant)
  277. &apos;&apos;&apos; Sets the updatable document property Title
  278. Const cstThisSub = &quot;SFDocuments.Document.setTitle&quot;
  279. Const cstSubArgs = &quot;Title&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(pvTitle, &quot;Title&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.Title = pvTitle
  288. If Not IsNull(_DocumentProperties) Then _DocumentProperties.ReplaceItem(&quot;Title&quot;, pvTitle)
  289. Finally:
  290. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  291. Exit Property
  292. End Property &apos; SFDocuments.SF_Document.Title
  293. REM -----------------------------------------------------------------------------
  294. Property Get XComponent() As Variant
  295. &apos;&apos;&apos; Returns the com.sun.star.lang.XComponent UNO object representing the document
  296. XComponent = _PropertyGet(&quot;XComponent&quot;)
  297. End Property &apos; SFDocuments.SF_Document.XComponent
  298. REM ===================================================================== METHODS
  299. REM -----------------------------------------------------------------------------
  300. Public Function Activate() As Boolean
  301. &apos;&apos;&apos; Make the current document active
  302. &apos;&apos;&apos; Args:
  303. &apos;&apos;&apos; Returns:
  304. &apos;&apos;&apos; True if the document could be activated
  305. &apos;&apos;&apos; Otherwise, there is no change in the actual user interface
  306. &apos;&apos;&apos; Examples:
  307. &apos;&apos;&apos; oDoc.Activate()
  308. Dim bActivate As Boolean &apos; Return value
  309. Dim oContainer As Object &apos; com.sun.star.awt.XWindow
  310. Const cstThisSub = &quot;SFDocuments.Document.Activate&quot;
  311. Const cstSubArgs = &quot;&quot;
  312. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  313. bActivate = False
  314. Check:
  315. ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
  316. If Not _IsStillAlive() Then GoTo Finally
  317. Try:
  318. Set oContainer = _Frame.ContainerWindow
  319. With oContainer
  320. If .isVisible() = False Then .setVisible(True)
  321. .IsMinimized = False
  322. .setFocus()
  323. .toFront() &apos; Force window change in Linux
  324. Wait 1 &apos; Bypass desynchro issue in Linux
  325. End With
  326. bActivate = True
  327. Finally:
  328. Activate = bActivate
  329. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  330. Exit Function
  331. Catch:
  332. GoTo Finally
  333. End Function &apos; SFDocuments.SF_Document.Activate
  334. REM -----------------------------------------------------------------------------
  335. Public Function CloseDocument(Optional ByVal SaveAsk As Variant) As Boolean
  336. &apos;&apos;&apos; Close the document. Does nothing if the document is already closed
  337. &apos;&apos;&apos; regardless of how the document was closed, manually or by program
  338. &apos;&apos;&apos; Args:
  339. &apos;&apos;&apos; SaveAsk: If True (default), the user is invited to confirm or not the writing of the changes on disk
  340. &apos;&apos;&apos; No effect if the document was not modified
  341. &apos;&apos;&apos; Returns:
  342. &apos;&apos;&apos; False if the user declined to close
  343. &apos;&apos;&apos; Examples:
  344. &apos;&apos;&apos; If oDoc.CloseDocument() Then
  345. &apos;&apos;&apos; &apos; ...
  346. Dim bClosed As Boolean &apos; return value
  347. Dim oDispatch &apos; com.sun.star.frame.DispatchHelper
  348. Const cstThisSub = &quot;SFDocuments.Document.CloseDocument&quot;
  349. Const cstSubArgs = &quot;[SaveAsk=True]&quot;
  350. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  351. bClosed = False
  352. Check:
  353. If IsMissing(SaveAsk) Or IsEmpty(SaveAsk) Then SaveAsk = True
  354. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  355. If Not _IsStillAlive() Then GoTo Finally
  356. If Not ScriptForge.SF_Utils._Validate(SaveAsk, &quot;SaveAsk&quot;, V_BOOLEAN) Then GoTo Finally
  357. End If
  358. Try:
  359. If SaveAsk And _Component.IsModified Then &apos; Execute closure with the File/Close menu command
  360. Activate()
  361. RunCommand(&quot;CloseDoc&quot;)
  362. bClosed = _IsStillAlive(, False) &apos; Do not raise error
  363. Else
  364. _Frame.close(True)
  365. _Frame.dispose()
  366. bClosed = True
  367. End If
  368. Finally:
  369. If bClosed Then Dispose()
  370. CloseDocument = bClosed
  371. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  372. Exit Function
  373. Catch:
  374. GoTo Finally
  375. End Function &apos; SFDocuments.SF_Document.CloseDocument
  376. REM -----------------------------------------------------------------------------
  377. Public Function GetProperty(Optional ByVal PropertyName As Variant) As Variant
  378. &apos;&apos;&apos; Return the actual value of the given property
  379. &apos;&apos;&apos; Args:
  380. &apos;&apos;&apos; PropertyName: the name of the property as a string
  381. &apos;&apos;&apos; Returns:
  382. &apos;&apos;&apos; The actual value of the property
  383. &apos;&apos;&apos; If the property does not exist, returns Null
  384. &apos;&apos;&apos; Exceptions:
  385. &apos;&apos;&apos; see the exceptions of the individual properties
  386. &apos;&apos;&apos; Examples:
  387. &apos;&apos;&apos; myModel.GetProperty(&quot;MyProperty&quot;)
  388. Const cstThisSub = &quot;SFDocuments.Document.GetProperty&quot;
  389. Const cstSubArgs = &quot;&quot;
  390. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  391. GetProperty = Null
  392. Check:
  393. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  394. If Not ScriptForge.SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
  395. End If
  396. Try:
  397. GetProperty = _PropertyGet(PropertyName)
  398. Finally:
  399. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  400. Exit Function
  401. Catch:
  402. GoTo Finally
  403. End Function &apos; SFDocuments.SF_Document.GetProperty
  404. REM -----------------------------------------------------------------------------
  405. Public Function Methods() As Variant
  406. &apos;&apos;&apos; Return the list of public methods of the Model service as an array
  407. Methods = Array( _
  408. &quot;Activate&quot; _
  409. , &quot;CloseDocument&quot; _
  410. , &quot;RunCommand&quot; _
  411. , &quot;Save&quot; _
  412. , &quot;SaveAs&quot; _
  413. , &quot;SaveCopyAs&quot; _
  414. )
  415. End Function &apos; SFDocuments.SF_Document.Methods
  416. REM -----------------------------------------------------------------------------
  417. Public Function Properties() As Variant
  418. &apos;&apos;&apos; Return the list or properties of the Timer class as an array
  419. Properties = Array( _
  420. &quot;CustomProperties&quot; _
  421. , &quot;Description&quot; _
  422. , &quot;DocumentProperties&quot; _
  423. , &quot;DocumentType&quot; _
  424. , &quot;IsBase&quot; _
  425. , &quot;IsCalc&quot; _
  426. , &quot;IsDraw &quot; _
  427. , &quot;IsImpress&quot; _
  428. , &quot;IsMath&quot; _
  429. , &quot;IsWriter&quot; _
  430. , &quot;Keywords&quot; _
  431. , &quot;Readonly&quot; _
  432. , &quot;Subject&quot; _
  433. , &quot;Title&quot; _
  434. , &quot;XComponent&quot; _
  435. )
  436. End Function &apos; SFDocuments.SF_Document.Properties
  437. REM -----------------------------------------------------------------------------
  438. Public Sub RunCommand(Optional ByVal Command As Variant)
  439. &apos;&apos;&apos; Run on the document the given menu command. The command is executed without arguments
  440. &apos;&apos;&apos; A few typical commands:
  441. &apos;&apos;&apos; Save, SaveAs, ExportToPDF, SetDocumentProperties, Undo, Copy, Paste, ...
  442. &apos;&apos;&apos; Dozens can be found in the directory $install/share/config/soffice.cfg/modules
  443. &apos;&apos;&apos; Args:
  444. &apos;&apos;&apos; Command: Case-sensitive. The command itself is not checked.
  445. &apos;&apos;&apos; If nothing happens, then the command is probably wrong
  446. &apos;&apos;&apos; Returns:
  447. &apos;&apos;&apos; Examples:
  448. &apos;&apos;&apos; oDoc.RunCommand(&quot;About&quot;)
  449. Dim oDispatch &apos; com.sun.star.frame.DispatchHelper
  450. Const cstThisSub = &quot;SFDocuments.Document.RunCommand&quot;
  451. Const cstSubArgs = &quot;Command&quot;
  452. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  453. Check:
  454. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  455. If Not _IsStillAlive() Then GoTo Finally
  456. If Not ScriptForge.SF_Utils._Validate(Command, &quot;Command&quot;, V_STRING) Then GoTo Finally
  457. End If
  458. Try:
  459. Set oDispatch = ScriptForge.SF_Utils._GetUNOService(&quot;DispatchHelper&quot;)
  460. oDispatch.executeDispatch(_Frame, &quot;.uno:&quot; &amp; Command, &quot;&quot;, 0, Array())
  461. Finally:
  462. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  463. Exit Sub
  464. Catch:
  465. GoTo Finally
  466. End Sub &apos; SFDocuments.SF_Document.RunCommand
  467. REM -----------------------------------------------------------------------------
  468. Public Function Save() As Boolean
  469. &apos;&apos;&apos; Store the document to the file location from which it was loaded
  470. &apos;&apos;&apos; Ignored if the document was not modified
  471. &apos;&apos;&apos; Args:
  472. &apos;&apos;&apos; Returns:
  473. &apos;&apos;&apos; False if the document could not be saved
  474. &apos;&apos;&apos; Exceptions:
  475. &apos;&apos;&apos; DOCUMENTSAVEERROR The file has been opened readonly or was opened as new and was not yet saved
  476. &apos;&apos;&apos; Examples:
  477. &apos;&apos;&apos; If Not oDoc.Save() Then
  478. &apos;&apos;&apos; &apos; ...
  479. Dim bSaved As Boolean &apos; return value
  480. Const cstThisSub = &quot;SFDocuments.Document.Save&quot;
  481. Const cstSubArgs = &quot;&quot;
  482. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  483. bSaved = False
  484. Check:
  485. ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
  486. If Not _IsStillAlive() Then GoTo Finally
  487. bSaved = False
  488. Try:
  489. With _Component
  490. If .isReadonly() Or Not .hasLocation() Then GoTo CatchReadonly
  491. If .IsModified() Then
  492. .store()
  493. bSaved = True
  494. End If
  495. End With
  496. Finally:
  497. Save = bSaved
  498. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  499. Exit Function
  500. Catch:
  501. GoTo Finally
  502. CatchReadonly:
  503. ScriptForge.SF_Exception.RaiseFatal(DOCUMENTSAVEERROR, &quot;FileName&quot;, _FileIdent())
  504. GoTo Finally
  505. End Function &apos; SFDocuments.SF_Document.Save
  506. REM -----------------------------------------------------------------------------
  507. Public Function SaveAs(Optional ByVal FileName As Variant _
  508. , Optional ByVal Overwrite As Variant _
  509. , Optional ByVal Password As Variant _
  510. , Optional ByVal FilterName As Variant _
  511. , Optional ByVal FilterOptions As Variant _
  512. ) As Boolean
  513. &apos;&apos;&apos; Store the document to the given file location
  514. &apos;&apos;&apos; The new location becomes the new file name on which simple Save method calls will be applied
  515. &apos;&apos;&apos; Args:
  516. &apos;&apos;&apos; FileName: Identifies the file where to save. It must follow the SF_FileSystem.FileNaming notation
  517. &apos;&apos;&apos; Overwrite: True if the destination file may be overwritten (default = False)
  518. &apos;&apos;&apos; Password: Use to protect the document
  519. &apos;&apos;&apos; FilterName: the name of a filter that should be used for saving the document
  520. &apos;&apos;&apos; If present, the filter must exist
  521. &apos;&apos;&apos; FilterOptions: an optional string of options associated with the filter
  522. &apos;&apos;&apos; Returns:
  523. &apos;&apos;&apos; False if the document could not be saved
  524. &apos;&apos;&apos; Exceptions:
  525. &apos;&apos;&apos; DOCUMENTSAVEASERROR The destination has its readonly attribute set or overwriting rejected
  526. &apos;&apos;&apos; Examples:
  527. &apos;&apos;&apos; oDoc.SaveAs(&quot;C:\Me\Copy2.odt&quot;, Overwrite := True)
  528. Dim bSaved As Boolean &apos; return value
  529. Dim oFilterFactory As Object &apos; com.sun.star.document.FilterFactory
  530. Dim oSfa As Object &apos; com.sun.star.ucb.SimpleFileAccess
  531. Dim sFile As String &apos; Alias of FileName
  532. Dim vProperties As Variant &apos; Array of com.sun.star.beans.PropertyValue
  533. Dim FSO As Object &apos; SF_FileSystem
  534. Const cstThisSub = &quot;SFDocuments.Document.SaveAs&quot;
  535. Const cstSubArgs = &quot;FileName, [Overwrite=False], [Password=&quot;&quot;&quot;&quot;], [FilterName=&quot;&quot;&quot;&quot;], [FilterOptions=&quot;&quot;&quot;&quot;]&quot;
  536. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo CatchError
  537. bSaved = False
  538. Check:
  539. If IsMissing(Overwrite) Or IsEmpty(Overwrite) Then Overwrite = False
  540. If IsMissing(Password) Or IsEmpty(Password) Then Password = &quot;&quot;
  541. If IsMissing(FilterName) Or IsEmpty(FilterName) Then FilterName = &quot;&quot;
  542. If IsMissing(FilterOptions) Or IsEmpty(FilterOptions) Then FilterOptions = &quot;&quot;
  543. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  544. If Not _IsStillAlive() Then GoTo Finally
  545. If Not SF_Utils._ValidateFile(FileName, &quot;FileName&quot;) Then GoTo Finally
  546. If Not SF_Utils._Validate(Overwrite, &quot;Overwrite&quot;, V_BOOLEAN) Then GoTo Finally
  547. If Not SF_Utils._Validate(Password, &quot;Password&quot;, V_STRING) Then GoTo Finally
  548. If Not SF_Utils._Validate(FilterName, &quot;FilterName&quot;, V_STRING) Then GoTo Finally
  549. If Not SF_Utils._Validate(FilterOptions, &quot;FilterOptions&quot;, V_STRING) Then GoTo Finally
  550. End If
  551. &apos; Check that the filter exists
  552. If Len(FilterName) &gt; 0 Then
  553. Set oFilterFactory = ScriptForge.SF_Utils._GetUNOService(&quot;FilterFactory&quot;)
  554. If Not oFilterFactory.hasByName(FilterName) Then GoTo CatchError
  555. End If
  556. &apos; Check destination file overwriting
  557. Set FSO = CreateScriptService(&quot;FileSystem&quot;)
  558. sFile = FSO._ConvertToUrl(FileName)
  559. If FSO.FileExists(FileName) Then
  560. If Overwrite = False Then GoTo CatchError
  561. Set oSfa = ScriptForge.SF_Utils._GetUNOService(&quot;FileAccess&quot;)
  562. If oSfa.isReadonly(sFile) Then GoTo CatchError
  563. End If
  564. Try:
  565. &apos; Setup arguments
  566. If Len(Password) + Len(FilterName) = 0 Then
  567. vProperties = Array()
  568. Else
  569. vProperties = Array( _
  570. ScriptForge.SF_Utils._MakePropertyValue(&quot;FilterName&quot;, FilterName) _
  571. , ScriptForge.SF_Utils._MakePropertyValue(&quot;FilterOptions&quot;, FilterOptions) _
  572. )
  573. If Len(Password) &gt; 0 Then &apos; Password is to add only if &lt;&gt; &quot;&quot; !?
  574. vProperties = ScriptForge.SF_Array.Append(vproperties _
  575. , ScriptForge.SF_Utils._MakePropertyValue(&quot;Password&quot;, Password))
  576. End If
  577. End If
  578. _Component.StoreAsURL(sFile, vProperties)
  579. &apos; Remind the new file name
  580. _WindowFileName = sFile
  581. _WindowName = FSO.GetName(FileName)
  582. bSaved = True
  583. Finally:
  584. SaveAs = bSaved
  585. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  586. Exit Function
  587. Catch:
  588. GoTo Finally
  589. CatchError:
  590. ScriptForge.SF_Exception.RaiseFatal(DOCUMENTSAVEASERROR, &quot;FileName&quot;, FileName, &quot;Overwrite&quot;, Overwrite _
  591. , &quot;FilterName&quot;, FilterName)
  592. GoTo Finally
  593. End Function &apos; SFDocuments.SF_Document.SaveAs
  594. REM -----------------------------------------------------------------------------
  595. Public Function SaveCopyAs(Optional ByVal FileName As Variant _
  596. , Optional ByVal Overwrite As Variant _
  597. , Optional ByVal Password As Variant _
  598. , Optional ByVal FilterName As Variant _
  599. , Optional ByVal FilterOptions As Variant _
  600. ) As Boolean
  601. &apos;&apos;&apos; Store a copy or export the document to the given file location
  602. &apos;&apos;&apos; The actual location is unchanged
  603. &apos;&apos;&apos; Args:
  604. &apos;&apos;&apos; FileName: Identifies the file where to save. It must follow the SF_FileSystem.FileNaming notation
  605. &apos;&apos;&apos; Overwrite: True if the destination file may be overwritten (default = False)
  606. &apos;&apos;&apos; Password: Use to protect the document
  607. &apos;&apos;&apos; FilterName: the name of a filter that should be used for saving the document
  608. &apos;&apos;&apos; If present, the filter must exist
  609. &apos;&apos;&apos; FilterOptions: an optional string of options associated with the filter
  610. &apos;&apos;&apos; Returns:
  611. &apos;&apos;&apos; False if the document could not be saved
  612. &apos;&apos;&apos; Exceptions:
  613. &apos;&apos;&apos; DOCUMENTSAVEASERROR The destination has its readonly attribute set or overwriting rejected
  614. &apos;&apos;&apos; Examples:
  615. &apos;&apos;&apos; oDoc.SaveCopyAs(&quot;C:\Me\Copy2.odt&quot;, Overwrite := True)
  616. Dim bSaved As Boolean &apos; return value
  617. Dim oFilterFactory As Object &apos; com.sun.star.document.FilterFactory
  618. Dim oSfa As Object &apos; com.sun.star.ucb.SimpleFileAccess
  619. Dim sFile As String &apos; Alias of FileName
  620. Dim vProperties As Variant &apos; Array of com.sun.star.beans.PropertyValue
  621. Dim FSO As Object &apos; SF_FileSystem
  622. Const cstThisSub = &quot;SFDocuments.Document.SaveCopyAs&quot;
  623. Const cstSubArgs = &quot;FileName, [Overwrite=False], [Password=&quot;&quot;&quot;&quot;], [FilterName=&quot;&quot;&quot;&quot;], [FilterOptions=&quot;&quot;&quot;&quot;]&quot;
  624. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo CatchError
  625. bSaved = False
  626. Check:
  627. If IsMissing(Overwrite) Or IsEmpty(Overwrite) Then Overwrite = False
  628. If IsMissing(Password) Or IsEmpty(Password) Then Password = &quot;&quot;
  629. If IsMissing(FilterName) Or IsEmpty(FilterName) Then FilterName = &quot;&quot;
  630. If IsMissing(FilterOptions) Or IsEmpty(FilterOptions) Then FilterOptions = &quot;&quot;
  631. If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
  632. If Not _IsStillAlive() Then GoTo Finally
  633. If Not SF_Utils._ValidateFile(FileName, &quot;FileName&quot;) Then GoTo Finally
  634. If Not SF_Utils._Validate(Overwrite, &quot;Overwrite&quot;, V_BOOLEAN) Then GoTo Finally
  635. If Not SF_Utils._Validate(Password, &quot;Password&quot;, V_STRING) Then GoTo Finally
  636. If Not SF_Utils._Validate(FilterName, &quot;FilterName&quot;, V_STRING) Then GoTo Finally
  637. If Not SF_Utils._Validate(FilterOptions, &quot;FilterOptions&quot;, V_STRING) Then GoTo Finally
  638. End If
  639. &apos; Check that the filter exists
  640. If Len(FilterName) &gt; 0 Then
  641. Set oFilterFactory = ScriptForge.SF_Utils._GetUNOService(&quot;FilterFactory&quot;)
  642. If Not oFilterFactory.hasByName(FilterName) Then GoTo CatchError
  643. End If
  644. &apos; Check destination file overwriting
  645. Set FSO = CreateScriptService(&quot;FileSystem&quot;)
  646. sFile = FSO._ConvertToUrl(FileName)
  647. If FSO.FileExists(FileName) Then
  648. If Overwrite = False Then GoTo CatchError
  649. Set oSfa = ScriptForge.SF_Utils._GetUNOService(&quot;FileAccess&quot;)
  650. If oSfa.isReadonly(sFile) Then GoTo CatchError
  651. End If
  652. Try:
  653. &apos; Setup arguments
  654. If Len(Password) + Len(FilterName) = 0 Then
  655. vProperties = Array()
  656. Else
  657. vProperties = Array( _
  658. ScriptForge.SF_Utils._MakePropertyValue(&quot;FilterName&quot;, FilterName) _
  659. , ScriptForge.SF_Utils._MakePropertyValue(&quot;FilterOptions&quot;, FilterOptions) _
  660. )
  661. If Len(Password) &gt; 0 Then &apos; Password is to add only if &lt;&gt; &quot;&quot; !?
  662. vProperties = ScriptForge.SF_Array.Append(vproperties _
  663. , ScriptForge.SF_Utils._MakePropertyValue(&quot;Password&quot;, Password))
  664. End If
  665. End If
  666. _Component.StoreToURL(sFile, vProperties)
  667. bSaved = True
  668. Finally:
  669. SaveCopyAs = bSaved
  670. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  671. Exit Function
  672. Catch:
  673. GoTo Finally
  674. CatchError:
  675. ScriptForge.SF_Exception.RaiseFatal(DOCUMENTSAVEASERROR, &quot;FileName&quot;, FileName, &quot;Overwrite&quot;, Overwrite _
  676. , &quot;FilterName&quot;, FilterName)
  677. GoTo Finally
  678. End Function &apos; SFDocuments.SF_Document.SaveCopyAs
  679. REM -----------------------------------------------------------------------------
  680. Private Function SetProperty(Optional ByVal psProperty As String _
  681. , Optional ByVal pvValue As Variant _
  682. ) As Boolean
  683. &apos;&apos;&apos; Set the new value of the named property
  684. &apos;&apos;&apos; Args:
  685. &apos;&apos;&apos; psProperty: the name of the property
  686. &apos;&apos;&apos; pvValue: the new value of the given property
  687. &apos;&apos;&apos; Returns:
  688. &apos;&apos;&apos; True if successful
  689. Dim bSet As Boolean &apos; Return value
  690. Static oSession As Object &apos; Alias of SF_Session
  691. Dim cstThisSub As String
  692. Const cstSubArgs = &quot;Value&quot;
  693. If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
  694. bSet = False
  695. cstThisSub = &quot;SFDocuments.Document.set&quot; &amp; psProperty
  696. If IsMissing(pvValue) Then pvValue = Empty
  697. &apos;ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) &apos; Validation done in Property Lets
  698. If IsNull(oSession) Then Set oSession = ScriptForge.SF_Services.CreateScriptService(&quot;Session&quot;)
  699. bSet = True
  700. Select Case UCase(psProperty)
  701. Case UCase(&quot;CustomProperties&quot;)
  702. CustomProperties = pvValue
  703. Case UCase(&quot;Description&quot;)
  704. Description = pvValue
  705. Case UCase(&quot;Keywords&quot;)
  706. Keywords = pvValue
  707. Case UCase(&quot;Subject&quot;)
  708. Subject = pvValue
  709. Case UCase(&quot;Title&quot;)
  710. Title = pvValue
  711. Case Else
  712. bSet = False
  713. End Select
  714. Finally:
  715. SetProperty = bSet
  716. &apos;ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  717. Exit Function
  718. Catch:
  719. GoTo Finally
  720. End Function &apos; SFDocuments.SF_Document.SetProperty
  721. REM =========================================================== PRIVATE FUNCTIONS
  722. REM -----------------------------------------------------------------------------
  723. Private Function _FileIdent() As String
  724. &apos;&apos;&apos; Returns a file identification from the information that is currently available
  725. &apos;&apos;&apos; Useful e.g. for display in error messages
  726. _FileIdent = Iif(Len(_WindowFileName) &gt; 0, SF_FileSystem._ConvertFromUrl(_WindowFileName), _WindowTitle)
  727. End Function &apos; SFDocuments.SF_Document._FileIdent
  728. REM -----------------------------------------------------------------------------
  729. Private Function _IsStillAlive(Optional ByVal pbForUpdate As Boolean _
  730. , Optional ByVal pbError As Boolean _
  731. ) As Boolean
  732. &apos;&apos;&apos; Returns True if the document has not been closed manually or incidentally since the last use
  733. &apos;&apos;&apos; If dead the actual instance is disposed. The execution is cancelled when pbError = True (default)
  734. &apos;&apos;&apos; Args:
  735. &apos;&apos;&apos; pbForUpdate: if True (default = False), check additionally if document is open for editing
  736. &apos;&apos;&apos; pbError: if True (default), raise a fatal error
  737. Dim bAlive As Boolean &apos; Return value
  738. Dim sFileName As String &apos; File identification used to display error message
  739. On Local Error GoTo Catch &apos; Anticipate DisposedException errors or alike
  740. If IsMissing(pbForUpdate) Then pbForUpdate = False
  741. If IsMissing(pbError) Then pbError = True
  742. Try:
  743. &apos; Check existence of document
  744. bAlive = Not IsNull(_Frame)
  745. If bAlive Then bAlive = Not IsNull(_Component)
  746. If bAlive Then bAlive = Not IsNull(_Component.CurrentController)
  747. &apos; Check document is not read only
  748. If bAlive And pbForUpdate Then
  749. If _Component.isreadonly() Then GoTo CatchReadonly
  750. End If
  751. Finally:
  752. _IsStillAlive = bAlive
  753. Exit Function
  754. Catch:
  755. bAlive = False
  756. On Error GoTo 0
  757. sFileName = _FileIdent()
  758. Dispose()
  759. If pbError Then ScriptForge.SF_Exception.RaiseFatal(DOCUMENTDEADERROR, sFileName)
  760. GoTo Finally
  761. CatchReadonly:
  762. bAlive = False
  763. If pbError Then ScriptForge.SF_Exception.RaiseFatal(DOCUMENTREADONLYERROR, &quot;Document&quot;, _FileIdent())
  764. GoTo Finally
  765. End Function &apos; SFDocuments.SF_Document._IsStillAlive
  766. REM -----------------------------------------------------------------------------
  767. Private Sub _LoadDocumentProperties()
  768. &apos;&apos;&apos; Create dictionary with document properties as entries/ Custom properties are excluded
  769. &apos;&apos;&apos; Document is presumed still alive
  770. &apos;&apos;&apos; Special values:
  771. &apos;&apos;&apos; Only valid dates are taken
  772. &apos;&apos;&apos; Statistics are exploded in subitems. Subitems are specific to document type
  773. &apos;&apos;&apos; Keywords are joined
  774. &apos;&apos;&apos; Language is aligned on L10N convention la-CO
  775. Dim oProperties As Object &apos; Document properties
  776. Dim vNamedValue As Variant &apos; com.sun.star.beans.NamedValue
  777. If IsNull(_DocumentProperties) Then
  778. Set oProperties = _Component.getDocumentProperties
  779. Set _DocumentProperties = CreateScriptService(&quot;Dictionary&quot;)
  780. With _DocumentProperties
  781. .Add(&quot;Author&quot;, oProperties.Author)
  782. .Add(&quot;AutoloadSecs&quot;, oProperties.AutoloadSecs)
  783. .Add(&quot;AutoloadURL&quot;, oProperties.AutoloadURL)
  784. If oProperties.CreationDate.Year &gt; 0 Then .Add(&quot;CreationDate&quot;, CDateFromUnoDateTime(oProperties.CreationDate))
  785. .Add(&quot;DefaultTarget&quot;, oProperties.DefaultTarget)
  786. .Add(&quot;Description&quot;, oProperties.Description) &apos; The description can be multiline
  787. &apos; DocumentStatistics : number and names of statistics depend on document type
  788. For Each vNamedValue In oProperties.DocumentStatistics
  789. .Add(vNamedValue.Name, vNamedValue.Value)
  790. Next vNamedValue
  791. .Add(&quot;EditingDuration&quot;, oProperties.EditingDuration)
  792. .Add(&quot;Generator&quot;, oProperties.Generator)
  793. .Add(&quot;Keywords&quot;, Join(oProperties.Keywords, &quot;, &quot;))
  794. .Add(&quot;Language&quot;, oProperties.Language.Language &amp; Iif(Len(oProperties.Language.Country) &gt; 0, &quot;-&quot; &amp; oProperties.Language.Country, &quot;&quot;))
  795. If oProperties.ModificationDate.Year &gt; 0 Then .Add(&quot;ModificationDate&quot;, CDateFromUnoDateTime(oProperties.ModificationDate))
  796. If oProperties.PrintDate.Year &gt; 0 Then .Add(&quot;PrintDate&quot;, CDateFromUnoDateTime(oProperties.PrintDate))
  797. .Add(&quot;PrintedBy&quot;, oProperties.PrintedBy)
  798. .Add(&quot;Subject&quot;, oProperties.Subject)
  799. If oProperties.TemplateDate.Year &gt; 0 Then .Add(&quot;TemplateDate&quot;, CDateFromUnoDateTime(oProperties.TemplateDate))
  800. .Add(&quot;TemplateName&quot;, oProperties.TemplateName)
  801. .Add(&quot;TemplateURL&quot;, oProperties.TemplateURL)
  802. .Add(&quot;Title&quot;, oProperties.Title)
  803. End With
  804. End If
  805. End Sub &apos; SFDocuments.SF_Document._LoadDocumentProperties
  806. REM -----------------------------------------------------------------------------
  807. Private Function _PropertyGet(Optional ByVal psProperty As String) As Variant
  808. &apos;&apos;&apos; Return the value of the named property
  809. &apos;&apos;&apos; Args:
  810. &apos;&apos;&apos; psProperty: the name of the property
  811. Dim oProperties As Object &apos; Document or Custom properties
  812. Dim cstThisSub As String
  813. Const cstSubArgs = &quot;&quot;
  814. _PropertyGet = False
  815. Select Case _DocumentType
  816. Case &quot;Calc&quot; : cstThisSub = &quot;SFDocuments.SF_&quot; &amp; _DocumentType &amp; &quot;.get&quot; &amp; psProperty
  817. Case Else : cstThisSub = &quot;SFDocuments.SF_Document.get&quot; &amp; psProperty
  818. End Select
  819. ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
  820. If Not _IsStillAlive() Then GoTo Finally
  821. Select Case psProperty
  822. Case &quot;CustomProperties&quot;
  823. _CustomProperties = CreateScriptService(&quot;Dictionary&quot;) &apos; Always reload as updates could have been done manually by user
  824. _CustomProperties.ImportFromPropertyValues(_Component.getDocumentProperties().UserDefinedProperties.getPropertyValues)
  825. _PropertyGet = _CustomProperties
  826. Case &quot;Description&quot;
  827. _PropertyGet = _Component.DocumentProperties.Description
  828. Case &quot;DocumentProperties&quot;
  829. _LoadDocumentProperties() &apos; Always reload as updates could have been done manually by user
  830. Set _PropertyGet = _DocumentProperties
  831. Case &quot;DocumentType&quot;
  832. _PropertyGet = _DocumentType
  833. Case &quot;IsBase&quot;, &quot;IsCalc&quot;, &quot;IsDraw&quot;, &quot;IsImpress&quot;, &quot;IsMath&quot;, &quot;IsWriter&quot;
  834. _PropertyGet = ( Mid(psProperty, 3) = _DocumentType )
  835. Case &quot;Keywords&quot;
  836. _PropertyGet = Join(_Component.DocumentProperties.Keywords, &quot;, &quot;)
  837. Case &quot;Readonly&quot;
  838. _PropertyGet = _Component.isReadonly()
  839. Case &quot;Subject&quot;
  840. _PropertyGet = _Component.DocumentProperties.Subject
  841. Case &quot;Title&quot;
  842. _PropertyGet = _Component.DocumentProperties.Title
  843. Case &quot;XComponent&quot;
  844. Set _PropertyGet = _Component
  845. Case Else
  846. _PropertyGet = Null
  847. End Select
  848. Finally:
  849. ScriptForge.SF_Utils._ExitFunction(cstThisSub)
  850. Exit Function
  851. End Function &apos; SFDocuments.SF_Document._PropertyGet
  852. REM -----------------------------------------------------------------------------
  853. Private Function _Repr() As String
  854. &apos;&apos;&apos; Convert the SF_Document instance to a readable string, typically for debugging purposes (DebugPrint ...)
  855. &apos;&apos;&apos; Args:
  856. &apos;&apos;&apos; Return:
  857. &apos;&apos;&apos; &quot;[DOCUMENT]: Type - File&quot;
  858. _Repr = &quot;[Document]: &quot; &amp; _DocumentType &amp; &quot; - &quot; &amp; _FileIdent()
  859. End Function &apos; SFDocuments.SF_Document._Repr
  860. REM ============================================ END OF SFDOCUMENTS.SF_DOCUMENT
  861. </script:module>