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