summaryrefslogtreecommitdiff
path: root/wizards
diff options
context:
space:
mode:
authorJean-Pierre Ledure <jp@ledure.be>2023-07-14 17:11:14 +0200
committerJean-Pierre Ledure <jp@ledure.be>2023-07-15 09:54:01 +0200
commit44334328f75dd0023122a4cb446ccba0d507720c (patch)
tree0b814e6a7d4480d45d16646121610ca47e6fe363 /wizards
parentddb483509113e469b771320fea52f1b089574021 (diff)
ScriptForge (SF_FileSystem) support document(s internal file structure
1. The SF_Document services (document, base, calc, formdocument, writer) receive a new FileSystem property that returns the "root" of the component's file structure under the format: "vnd.sun.star.tdoc:/XXX" XXX being the document's identifier. The implementation does not use the RuntimeUID (UNO property of the OfficeDocument service) which is optional and, f.i. not present for Base documents. Instead the css.frame.TransientDocumentsDocumentContentFactory service is used. 2. The SF_FileSystem and SF_TextStream modules have been reviewed to support the new context. Next restrictions have been met: - The FileNaming property is always cnsidered as 'URL' - CompareFiles() is not applicable - GetFileLen() always returns zero - HashFile() is not applicable - Normalize() always returns the input string unchanged - PickFile() is not applicable - PickFolder() is not applicable Additionally, - CreatetextFile() - OpenTextFile() in write or append modes copy or initialize the file in a temporary storage and write it back in the document when it is being closed. The process is transparent for the user. 3. The GetTempName() method accepts an option Extension argument, for better convenience. The new functionalities are available in Basic and Python. Changes require an update of the help documentation. Change-Id: Ibf8dd9983656923cf6ab43d9f48398dc4d1e6307 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154443 Reviewed-by: Jean-Pierre Ledure <jp@ledure.be> Tested-by: Jenkins
Diffstat (limited to 'wizards')
-rw-r--r--wizards/source/scriptforge/SF_Exception.xba5
-rw-r--r--wizards/source/scriptforge/SF_FileSystem.xba177
-rw-r--r--wizards/source/scriptforge/SF_Region.xba2
-rw-r--r--wizards/source/scriptforge/SF_Root.xba15
-rw-r--r--wizards/source/scriptforge/SF_TextStream.xba27
-rw-r--r--wizards/source/scriptforge/SF_Utils.xba7
-rw-r--r--wizards/source/scriptforge/po/ScriptForge.pot15
-rw-r--r--wizards/source/scriptforge/po/en.po15
-rw-r--r--wizards/source/scriptforge/python/scriptforge.py42
-rw-r--r--wizards/source/sfdocuments/SF_Base.xba6
-rw-r--r--wizards/source/sfdocuments/SF_Calc.xba6
-rw-r--r--wizards/source/sfdocuments/SF_Document.xba23
-rw-r--r--wizards/source/sfdocuments/SF_FormDocument.xba6
-rw-r--r--wizards/source/sfdocuments/SF_Writer.xba6
14 files changed, 290 insertions, 62 deletions
diff --git a/wizards/source/scriptforge/SF_Exception.xba b/wizards/source/scriptforge/SF_Exception.xba
index 6add0b158990..38e5b2ef24e0 100644
--- a/wizards/source/scriptforge/SF_Exception.xba
+++ b/wizards/source/scriptforge/SF_Exception.xba
@@ -72,6 +72,7 @@ Const OVERWRITEERROR = &quot;OVERWRITEERROR&quot;
Const READONLYERROR = &quot;READONLYERROR&quot;
Const NOFILEMATCHERROR = &quot;NOFILEMATCHFOUND&quot;
Const FOLDERCREATIONERROR = &quot;FOLDERCREATIONERROR&quot;
+Const FILESYSTEMERROR = &quot;FILESYSTEMERROR&quot;
&apos; SF_Services
Const UNKNOWNSERVICEERROR = &quot;UNKNOWNSERVICEERROR&quot;
@@ -884,6 +885,10 @@ Try:
sMessage = sLocation _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;VALIDATEERROR&quot;, pvArgs(0)) _
&amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;FOLDERCREATION&quot;, pvArgs(0), pvArgs(1))
+ Case FILESYSTEMERROR &apos; SF_FileSystem.---(ArgName, MethodName, ArgValue)
+ pvArgs(0) = _RightCase(pvArgs(0))
+ sMessage = sLocation _
+ &amp; &quot;\n&quot; &amp; &quot;\n&quot; &amp; .GetText(&quot;FILESYSTEM&quot;, pvArgs(0), pvArgs(1), pvArgs(2))
Case UNKNOWNSERVICEERROR &apos; SF_Services.CreateScriptService(ArgName, Value, Library, Service)
pvArgs(0) = _RightCase(pvArgs(0))
sMessage = sLocation _
diff --git a/wizards/source/scriptforge/SF_FileSystem.xba b/wizards/source/scriptforge/SF_FileSystem.xba
index b09f980429f4..aeeafc4dc73d 100644
--- a/wizards/source/scriptforge/SF_FileSystem.xba
+++ b/wizards/source/scriptforge/SF_FileSystem.xba
@@ -27,7 +27,7 @@ Option Explicit
&apos;&apos;&apos; File and folder names may be expressed either in the (preferable because portable) URL form
&apos;&apos;&apos; or in the more usual operating system notation (e.g. C:\... for Windows)
&apos;&apos;&apos; The notation, both for arguments and for returned values
-&apos;&apos;&apos; is determined by the FileNaming property: either &quot;URL&quot; (default) or &quot;SYS&quot;
+&apos;&apos;&apos; is determined by the FileNaming property: either &quot;ANY&quot; (default), &quot;URL&quot; or &quot;SYS&quot;
&apos;&apos;&apos;
&apos;&apos;&apos; FileName: the full name of the file including the path without any ending path separator
&apos;&apos;&apos; FolderName: the full name of the folder including the path and the ending path separator
@@ -37,6 +37,23 @@ Option Explicit
&apos;&apos;&apos; Admitted wildcards are: the &quot;?&quot; represents any single character
&apos;&apos;&apos; the &quot;*&quot; represents zero, one, or multiple characters
&apos;&apos;&apos;
+&apos;&apos;&apos; Disk file sstems and document&apos;s internal file systems
+&apos;&apos;&apos; All the implemented properties and methods are applicable on usual disk file systems.
+&apos;&apos;&apos; Root is usually something like &quot;C:\&quot; or &quot;/&quot; or their URL equivalents
+&apos;&apos;&apos; Now, Libreoffice documents have an internal file system as well. Many of the proposed methods
+&apos;&apos;&apos; support document&apos;s file systems too, however, for some of them, with restrictions.
+&apos;&apos;&apos; Read the comments in the individual methods below.
+&apos;&apos;&apos; It makes browing folders and files, adding, replacing files possible. Updates will be
+&apos;&apos;&apos; saved with the document.
+&apos;&apos;&apos; VERY POWERFUL but KNOW WHAT YOU&apos;RE DOING !!
+&apos;&apos;&apos; The root of a document&apos;s file system is obtained from the &quot;FileSystem&quot; property of a document instance, like in:
+&apos;&apos;&apos; Dim root As String, doc As Object, ui As Object
+&apos;&apos;&apos; Set ui = CreateScriptService(&quot;ui&quot;)
+&apos;&apos;&apos; Set doc = ui.GetDocument(ThisComponent)
+&apos;&apos;&apos; root = doc.FileSystem
+&apos;&apos;&apos; The file manifest.xml is managed automatically.
+&apos;&apos;&apos; The FileNaming setting is ignored.
+&apos;&apos;&apos;
&apos;&apos;&apos; Service invocation example:
&apos;&apos;&apos; Dim FSO As Variant
&apos;&apos;&apos; Set FSO = CreateScriptService(&quot;FileSystem&quot;)
@@ -55,6 +72,7 @@ Const OVERWRITEERROR = &quot;OVERWRITEERROR&quot; &apos; Destination can not
Const READONLYERROR = &quot;READONLYERROR&quot; &apos; Destination has its read-only attribute set
Const NOFILEMATCHERROR = &quot;NOFILEMATCHFOUND&quot; &apos; No file matches Source containing wildcards
Const FOLDERCREATIONERROR = &quot;FOLDERCREATIONERROR&quot; &apos; FolderName is an existing folder or file
+Const FILESYSTEMERROR = &quot;FILESYSTEMERROR&quot; &apos; The method is not applicable on document&apos;s file systems
REM ============================================================ MODULE CONSTANTS
@@ -63,6 +81,9 @@ Const cstForReading = 1
Const cstForWriting = 2
Const cstForAppending = 8
+&apos;&apos;&apos; Document file system
+Const DOCFILESYSTEM = &quot;vnd.sun.star.tdoc:/&quot;
+
REM ===================================================== CONSTRUCTOR/DESTRUCTOR
REM -----------------------------------------------------------------------------
@@ -286,6 +307,7 @@ Public Function CompareFiles(Optional ByVal FileName1 As Variant _
&apos;&apos;&apos; Compare 2 files and return True if they seem identical
&apos;&apos;&apos; The comparison may be based on the file attributes, like modification time,
&apos;&apos;&apos; or on their contents.
+&apos;&apos;&apos; The method is not supporte for document&apos;s internal file systems.
&apos;&apos;&apos; Args:
&apos;&apos;&apos; FileName1: The 1st file to compare
&apos;&apos;&apos; FileName2: The 2nd file to compare
@@ -294,6 +316,7 @@ Public Function CompareFiles(Optional ByVal FileName1 As Variant _
&apos;&apos;&apos; True when the files seem identical
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; UNKNOWNFILEERROR One of the files does not exist
+&apos;&apos;&apos; FILESYSTEMERROR The method is not applicable on document&apos;s file systems
&apos;&apos;&apos; Example:
&apos;&apos;&apos; FSO.FileNaming = &quot;SYS&quot;
&apos;&apos;&apos; MsgBox FSO.CompareFiles(&quot;C:\myFile1.txt&quot;, &quot;C:\myFile2.txt&quot;, CompareContents := True)
@@ -322,6 +345,11 @@ Check:
sFile = FileName2 : iFile = 2
If Not SF_FileSystem.FileExists(sFile) Then GoTo CatchNotExists
+ sFile = FileName1 : iFile = 1
+ If SF_FileSystem._IsDocFileSystem(sFile) Then GoTo CatchNotSupported
+ sFile = FileName2 : iFile = 2
+ If SF_FileSystem._IsDocFileSystem(sFile) Then GoTo CatchNotSupported
+
Try:
With ScriptForge.SF_Session
bCompare = .ExecutePythonScript(.SCRIPTISSHARED, _SF_.PythonHelper &amp; cstPyHelper _
@@ -339,6 +367,9 @@ Catch:
CatchNotExists:
SF_Exception.RaiseFatal(UNKNOWNFILEERROR, &quot;FileName&quot; &amp; iFile, sFile)
GoTo Finally
+CatchNotSupported:
+ SF_Exception.RaiseFatal(FILESYSTEMERROR, &quot;FileName&quot; &amp; iFile, Split(cstThisSub, &quot;.&quot;)(1), sFile)
+ GoTo Finally
End Function &apos; ScriptForge.SF_FileSystem.CompareFiles
REM -----------------------------------------------------------------------------
@@ -750,6 +781,7 @@ Dim vFiles As Variant &apos; Return value
Dim oSfa As Object &apos; com.sun.star.ucb.SimpleFileAccess
Dim sFolderName As String &apos; URL lias for FolderName
Dim sFile As String &apos; Single file
+Dim bDocFileSystem As Boolean &apos; When True, a document file system is being explored
Dim i As Long
Const cstThisSub = &quot;FileSystem.Files&quot;
@@ -768,20 +800,30 @@ Check:
If SF_FileSystem.FileExists(FolderName) Then GoTo CatchFile &apos; Must not be a file
If Not SF_FileSystem.FolderExists(FolderName) Then GoTo CatchFolder &apos; Folder must exist
+ bDocFileSystem = SF_String.StartsWith(sFolderName, DOCFILESYSTEM)
+
Try:
&apos; Get files
Set oSfa = SF_Utils._GetUnoService(&quot;FileAccess&quot;)
- vFiles = oSfa.getFolderContents(sFolderName, False)
+ vFiles = oSfa.getFolderContents(sFolderName, False) &apos; NB: The False argumentis ignored in document file systems
&apos; Adjust notations
For i = 0 To UBound(vFiles)
sFile = SF_FileSystem._ConvertFromUrl(vFiles(i))
vFiles(i) = sFile
Next i
- &apos; Reduce list to those passing the filter
- If Len(Filter) &gt; 0 Then
+
+ &apos; Reduce list to valid items:
+ &apos; - those passing the filter
+ &apos; - files only, not folders: in documents file systems, the False argument of getFolderContents() is ignored.
+ If Len(Filter) &gt; 0 Or bDocFileSystem Then
For i = 0 To UBound(vFiles)
sFile = SF_FileSystem.GetName(vFiles(i))
- If Not SF_String.IsLike(sFile, Filter) Then vFiles(i) = &quot;&quot;
+ If Len(Filter) &gt; 0 Then
+ If Not SF_String.IsLike(sFile, Filter) Then vFiles(i) = &quot;&quot;
+ End If
+ If bDocFileSystem Then
+ If oSfa.isFolder(ConvertToUrl(vFiles(i))) Then vFiles(i) = &quot;&quot;
+ End If
Next i
vFiles = Sf_Array.TrimArray(vFiles)
End If
@@ -936,6 +978,7 @@ Public Function GetFileLen(Optional ByVal FileName As Variant) As Currency
&apos;&apos;&apos; FileName: a string representing a file
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; File size if FileName exists
+&apos;&apos;&apos; 0 when FileName belongs to a document&apos;s internal file systems.
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; UNKNOWNFILEERROR The file does not exist of is a folder
&apos;&apos;&apos; Example:
@@ -956,10 +999,14 @@ Check:
Try:
If SF_FileSystem.FileExists(FileName) Then
- With ScriptForge.SF_Session
- curSize = .ExecutePythonScript(.SCRIPTISSHARED, _SF_.PythonHelper &amp; cstPyHelper _
- , _ConvertFromUrl(FileName))
- End With
+ If SF_FileSystem._IsDocFileSystem(FileName) Then
+ curSize = 0
+ Else
+ With ScriptForge.SF_Session
+ curSize = .ExecutePythonScript(.SCRIPTISSHARED, _SF_.PythonHelper &amp; cstPyHelper _
+ , _ConvertFromUrl(FileName))
+ End With
+ End If
Else
GoTo CatchNotExists
End If
@@ -978,12 +1025,14 @@ End Function &apos; ScriptForge.SF_FileSystem.GetFileLen
REM -----------------------------------------------------------------------------
Public Function GetFileModified(Optional ByVal FileName As Variant) As Variant
&apos;&apos;&apos; Returns the last modified date for the given file
+&apos;&apos;&apos; The method is not supporte for document&apos;s internal file systems.
&apos;&apos;&apos; Args:
&apos;&apos;&apos; FileName: a string representing an existing file
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; The modification date and time as a Basic Date
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; UNKNOWNFILEERROR The file does not exist of is a folder
+&apos;&apos;&apos; FILESYSTEMERROR The method is not applicable on document&apos;s file systems
&apos;&apos;&apos; Example:
&apos;&apos;&apos; Dim a As Date
&apos;&apos;&apos; FSO.FileNaming = &quot;SYS&quot;
@@ -1003,6 +1052,7 @@ Check:
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not SF_Utils._ValidateFile(FileName, &quot;FileName&quot;) Then GoTo Finally
End If
+ If SF_FileSystem._IsDocFileSystem(FileName) Then GoTo CatchNotSupported
Try:
Set oSfa = SF_Utils._GetUnoService(&quot;FileAccess&quot;)
@@ -1023,6 +1073,9 @@ Catch:
CatchNotExists:
SF_Exception.RaiseFatal(UNKNOWNFILEERROR, &quot;FileName&quot;, FileName)
GoTo Finally
+CatchNotSupported:
+ SF_Exception.RaiseFatal(FILESYSTEMERROR, &quot;FileName&quot;, Split(cstThisSub, &quot;.&quot;)(1), FileName)
+ GoTo Finally
End Function &apos; ScriptForge.SF_FileSystem.GetFileModified
REM -----------------------------------------------------------------------------
@@ -1152,20 +1205,21 @@ Catch:
End Function &apos; ScriptForge.SF_FileSystem.GetProperty
REM -----------------------------------------------------------------------------
-Public Function GetTempName() As String
+Public Function GetTempName(Optional ByVal Extension As Variant) As String
&apos;&apos;&apos; Returns a randomly generated temporary file name that is useful for performing
&apos;&apos;&apos; operations that require a temporary file : the method does not create any file
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; A FileName as a String that can be used f.i. with CreateTextFile()
-&apos;&apos;&apos; The FileName does not have any suffix
+&apos;&apos;&apos; The FileName has as suffix the given extension.
&apos;&apos;&apos; Example:
&apos;&apos;&apos; Dim a As String
&apos;&apos;&apos; FSO.FileNaming = &quot;SYS&quot;
-&apos;&apos;&apos; a = FSO.GetTempName() &amp; &quot;.txt&quot;
+&apos;&apos;&apos; a = FSO.GetTempName(&quot;txt&quot;) &apos; /tmp/SF_123456.txt
+&apos;&apos;&apos; a = FSO.GetTempName() &apos; /tmp/SF_234567
Dim sFile As String &apos; Return value
-Dim sTempDir As String &apos; The path to a temporary folder
+Dim sExtension As String &apos; The given extension preceded by a dot
Dim lRandom As Long &apos; Random integer
Const cstThisSub = &quot;FileSystem.GetTempName&quot;
@@ -1175,11 +1229,15 @@ Const cstSubArgs = &quot;&quot;
sFile = &quot;&quot;
Check:
- SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
+ If IsMissing(Extension) Or IsEmpty(Extension) Then Extension = &quot;&quot;
+ If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
+ If Not SF_Utils._Validate(Extension, &quot;Extension&quot;, V_STRING) Then GoTo Catch
+ End If
Try:
lRandom = SF_Session.ExecuteCalcFunction(&quot;RANDBETWEEN.NV&quot;, 1, 999999)
- sFile = SF_FileSystem.TemporaryFolder &amp; &quot;SF_&quot; &amp; Right(&quot;000000&quot; &amp; lRandom, 6)
+ If Len(Extension) &gt; 0 Then sExtension = &quot;.&quot; &amp; Extension Else sExtension = &quot;&quot;
+ sFile = SF_FileSystem.TemporaryFolder &amp; &quot;SF_&quot; &amp; Right(&quot;000000&quot; &amp; lRandom, 6) &amp; sExtension
Finally:
GetTempName = SF_FileSystem._ConvertFromUrl(sFile)
@@ -1195,6 +1253,7 @@ Public Function HashFile(Optional ByVal FileName As Variant _
) As String
&apos;&apos;&apos; Return an hexadecimal string representing a checksum of the given file
&apos;&apos;&apos; Next algorithms are supported: MD5, SHA1, SHA224, SHA256, SHA384 and SHA512
+&apos;&apos;&apos; The method is not supporte for document&apos;s internal file systems.
&apos;&apos;&apos; Args:
&apos;&apos;&apos; FileName: a string representing a file
&apos;&apos;&apos; Algorithm: The hashing algorithm to use
@@ -1203,6 +1262,7 @@ Public Function HashFile(Optional ByVal FileName As Variant _
&apos;&apos;&apos; A zero-length string when an error occurred
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; UNKNOWNFILEERROR The file does not exist of is a folder
+&apos;&apos;&apos; FILESYSTEMERROR The method is not applicable on document&apos;s file systems
&apos;&apos;&apos; Example:
&apos;&apos;&apos; Print SF_FileSystem.HashFile(&quot;C:\pagefile.sys&quot;, &quot;MD5&quot;)
@@ -1220,6 +1280,7 @@ Check:
If Not SF_Utils._Validate(Algorithm, &quot;Algorithm&quot;, V_STRING _
, Array(&quot;MD5&quot;, &quot;SHA1&quot;, &quot;SHA224&quot;, &quot;SHA256&quot;, &quot;SHA384&quot;, &quot;SHA512&quot;)) Then GoTo Finally
End If
+ If SF_FileSystem._IsDocFileSystem(FileName) Then GoTo CatchNotSupported
Try:
If SF_FileSystem.FileExists(FileName) Then
@@ -1240,6 +1301,9 @@ Catch:
CatchNotExists:
SF_Exception.RaiseFatal(UNKNOWNFILEERROR, &quot;FileName&quot;, FileName)
GoTo Finally
+CatchNotSupported:
+ SF_Exception.RaiseFatal(FILESYSTEMERROR, &quot;FileName&quot;, Split(cstThisSub, &quot;.&quot;)(1), FileName)
+ GoTo Finally
End Function &apos; ScriptForge.SF_FileSystem.HashFile
REM -----------------------------------------------------------------------------
@@ -1389,6 +1453,7 @@ Public Function Normalize(Optional ByVal FileName As Variant) As String
&apos;&apos;&apos; Normalize a pathname by collapsing redundant separators and up-level references
&apos;&apos;&apos; so that A//B, A/B/, A/./B and A/foo/../B all become A/B.
&apos;&apos;&apos; On Windows, it converts forward slashes to backward slashes.
+&apos;&apos;&apos; The method returns the input string when the file is from a document&apos;s internal file systems.
&apos;&apos;&apos; Args:
&apos;&apos;&apos; FileName: a string representing a file. The file may not exist.
&apos;&apos;&apos; Returns:
@@ -1410,12 +1475,16 @@ Check:
End If
Try:
- With ScriptForge.SF_Session
- sNorm = .ExecutePythonScript(.SCRIPTISSHARED, _SF_.PythonHelper &amp; cstPyHelper _
- , _ConvertFromUrl(FileName))
- &apos; The Python os.path expects and returns a file name in os notation
- If SF_FileSystem.FileNaming &lt;&gt; &quot;SYS&quot; Then sNorm = ConvertToUrl(sNorm)
- End With
+ If SF_FileSystem._IsDocFileSystem(FileName) Then
+ sNorm = FileName
+ Else
+ With ScriptForge.SF_Session
+ sNorm = .ExecutePythonScript(.SCRIPTISSHARED, _SF_.PythonHelper &amp; cstPyHelper _
+ , _ConvertFromUrl(FileName))
+ &apos; The Python os.path expects and returns a file name in os notation
+ If SF_FileSystem.FileNaming &lt;&gt; &quot;SYS&quot; Then sNorm = ConvertToUrl(sNorm)
+ End With
+ End If
Finally:
Normalize = sNorm
@@ -1454,22 +1523,24 @@ Public Function OpenTextFile(Optional ByVal FileName As Variant _
&apos;&apos;&apos; If Not IsNull(myFile) Then &apos; ... Go ahead with reading text lines
Dim oTextStream As Object &apos; Return value
-Dim bExists As Boolean &apos; File to open does exist
+Dim bExists As Boolean &apos; When True, file to open does exist
+Dim bEmbeddedFile As Boolean &apos; When True, file to open is embedded in a document&apos;s internal file system
+Dim oSfa As Object &apos; com.sun.star.ucb.SimpleFileAccess
Const cstThisSub = &quot;FileSystem.OpenTextFile&quot;
-Const cstSubArgs = &quot;FileName, [IOMode=1], [Create=False], [Encoding=&quot;&quot;UTF-8&quot;&quot;]&quot;
+Const cstSubArgs = &quot;FileName, [IOMode=1|2|8], [Create=False], [Encoding=&quot;&quot;UTF-8&quot;&quot;]&quot;
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
Set oTextStream = Nothing
Check:
With SF_FileSystem
- If IsMissing(IOMode) Or IsEmpty(IOMode) Then IOMode = ForReading
+ If IsMissing(IOMode) Or IsEmpty(IOMode) Then IOMode = cstForReading
If IsMissing(Create) Or IsEmpty(Create) Then Create = False
If IsMissing(Encoding) Or IsEmpty(Encoding) Then Encoding = &quot;UTF-8&quot;
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not SF_Utils._ValidateFile(FileName, &quot;FileName&quot;) Then GoTo Finally
If Not SF_Utils._Validate(IOMode, &quot;IOMode&quot;, V_NUMERIC _
- , Array(ForReading, ForWriting, ForAppending)) _
+ , Array(cstForReading, cstForWriting, cstForAppending)) _
Then GoTo Finally
If Not SF_Utils._Validate(Create, &quot;Create&quot;, V_BOOLEAN) Then GoTo Finally
If Not SF_Utils._Validate(Encoding, &quot;Encoding&quot;, V_STRING) Then GoTo Finally
@@ -1482,6 +1553,8 @@ Check:
End Select
If IOMode = ForAppending And Not bExists Then IOMode = ForWriting
+
+ bEmbeddedFile = SF_FileSystem._IsDocFileSystem(FileName)
End With
Try:
@@ -1490,7 +1563,19 @@ Try:
With oTextStream
.[Me] = oTextStream
.[_Parent] = SF_FileSystem
- ._FileName = SF_FileSystem._ConvertToUrl(FileName)
+ ._IsEmbeddedFile = bEmbeddedFile
+ If bEmbeddedFile And (IOMode = cstForWriting Or IOMode = cstForAppending) Then
+ &apos; Updates of an embedded file are done on a copy
+ ._EmbeddedFileName = SF_FileSystem._ConvertToUrl(FileName)
+ ._FileName = SF_FileSystem._ConvertToUrl(SF_FileSystem.GetTempName(SF_FileSystem.GetExtension(FileName)))
+ &apos; Create the copy if relevant
+ If bExists Then
+ Set oSfa = SF_Utils._GetUnoService(&quot;FileAccess&quot;)
+ oSfa.copy(._EmbeddedFileName, ._FileName)
+ End If
+ Else
+ ._FileName = SF_FileSystem._ConvertToUrl(FileName)
+ End If
._IOMode = IOMode
._Encoding = Encoding
._FileExists = bExists
@@ -1517,14 +1602,17 @@ Public Function PickFile(Optional ByVal DefaultFile As Variant _
&apos;&apos;&apos; The mode, OPEN or SAVE, and the filter may be preset
&apos;&apos;&apos; If mode = SAVE and the picked file exists, a warning message will be displayed
&apos;&apos;&apos; Modified from Andrew Pitonyak&apos;s Base Macro Programming §10.4
+&apos;&apos;&apos; The method is not supporte for document&apos;s internal file systems.
&apos;&apos;&apos; Args:
&apos;&apos;&apos; DefaultFile: Folder part: the FolderName from which to start. Default = the last selected folder
&apos;&apos;&apos; File part: the default file to open or save
&apos;&apos;&apos; Mode: &quot;OPEN&quot; (input file) or &quot;SAVE&quot; (output file)
&apos;&apos;&apos; Filter: by default only files having the given suffix will be displayed. Default = all suffixes
-&apos;&apos;&apos; The filter combo box will contain the given SuffixFilter (if not &quot;*&quot;) and &quot;*.*&quot;
+&apos;&apos;&apos; The filter combo box will contain the given suffix filter (if not &quot;*&quot;) and &quot;*.*&quot;
&apos;&apos;&apos; Returns:
-&apos;&apos;&apos; The selected FileName in URL format or &quot;&quot; if the dialog was cancelled
+&apos;&apos;&apos; The selected FileName in FileNaming format or &quot;&quot; if the dialog was cancelled
+&apos;&apos;&apos; Exceptions:
+&apos;&apos;&apos; FILESYSTEMERROR The method is not applicable on document&apos;s file systems
&apos;&apos;&apos; Example:
&apos;&apos;&apos; FSO.FileNaming = &quot;SYS&quot;
&apos;&apos;&apos; FSO.PickFile(&quot;C:\&quot;, &quot;OPEN&quot;, &quot;txt&quot;) &apos; Only *.txt files are displayed
@@ -1553,6 +1641,7 @@ Check:
If Not SF_Utils._Validate(Mode, &quot;Mode&quot;, V_STRING, Array(&quot;OPEN&quot;, &quot;SAVE&quot;)) Then GoTo Finally
If Not SF_Utils._Validate(Filter, &quot;Filter&quot;, V_STRING) Then GoTo Finally
End If
+ If SF_FileSystem._IsDocFileSystem(DefaultFile) Then GoTo CatchNotSupported
DefaultFile = SF_FileSystem._ConvertToUrl(DefaultFile)
Try:
@@ -1600,6 +1689,9 @@ Finally:
Exit Function
Catch:
GoTo Finally
+CatchNotSupported:
+ SF_Exception.RaiseFatal(FILESYSTEMERROR, &quot;DefaultFile&quot;, Split(cstThisSub, &quot;.&quot;)(1), DefaultFile)
+ GoTo Finally
End Function &apos; ScriptForge.SF_FileSystem.PickFile
REM -----------------------------------------------------------------------------
@@ -1607,12 +1699,15 @@ Public Function PickFolder(Optional ByVal DefaultFolder As Variant _
, Optional ByVal FreeText As Variant _
) As String
&apos;&apos;&apos; Display a FolderPicker dialog box
+&apos;&apos;&apos; The method is not supporte for document&apos;s internal file systems.
&apos;&apos;&apos; Args:
&apos;&apos;&apos; DefaultFolder: the FolderName from which to start. Default = the last selected folder
&apos;&apos;&apos; FreeText: text to display in the dialog. Default = &quot;&quot;
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; The selected FolderName in URL or operating system format
&apos;&apos;&apos; The zero-length string if the dialog was cancelled
+&apos;&apos;&apos; Exceptions:
+&apos;&apos;&apos; FILESYSTEMERROR The method is not applicable on document&apos;s file systems
&apos;&apos;&apos; Example:
&apos;&apos;&apos; FSO.FileNaming = &quot;SYS&quot;
&apos;&apos;&apos; FSO.PickFolder(&quot;C:\&quot;, &quot;Choose a folder or press Cancel&quot;)
@@ -1634,6 +1729,7 @@ Check:
If Not SF_Utils._ValidateFile(DefaultFolder, &quot;DefaultFolder&quot;, , True) Then GoTo Finally
If Not SF_Utils._Validate(FreeText, &quot;FreeText&quot;, V_STRING) Then GoTo Finally
End If
+ If SF_FileSystem._IsDocFileSystem(DefaultFolder) Then GoTo CatchNotSupported
DefaultFolder = SF_FileSystem._ConvertToUrl(DefaultFolder)
Try:
@@ -1657,6 +1753,9 @@ Finally:
Exit Function
Catch:
GoTo Finally
+CatchNotSupported:
+ SF_Exception.RaiseFatal(FILESYSTEMERROR, &quot;DefaultFolder&quot;, Split(cstThisSub, &quot;.&quot;)(1), DefaultFolder)
+ GoTo Finally
End Function &apos; ScriptForge.SF_FileSystem.PickFolder
REM -----------------------------------------------------------------------------
@@ -1788,11 +1887,12 @@ Private Function _ConvertFromUrl(psFile) As String
&apos;&apos;&apos; Execute the builtin ConvertFromUrl function only when relevant
&apos;&apos;&apos; i.e. when FileNaming (how arguments and return values are provided) = &quot;SYS&quot;
&apos;&apos;&apos; Called at the bottom of methods returning file names
-&apos;&apos;&apos; Remark: psFile might contain wildcards
+&apos;&apos;&apos; Remarks: psFile might contain wildcards
+&apos;&apos;&apos; Files from document&apos;s file systems are never converted
Const cstQuestion = &quot;$QUESTION$&quot;, cstStar = &quot;$STAR$&quot; &apos; Special tokens to replace wildcards
- If SF_FileSystem.FileNaming = &quot;SYS&quot; Then
+ If SF_FileSystem.FileNaming = &quot;SYS&quot; And Not SF_FileSystem._IsDocFileSystem(psFile) Then
_ConvertFromUrl = Replace(Replace( _
ConvertFromUrl(Replace(Replace(psFile, &quot;?&quot;, cstQuestion), &quot;*&quot;, cstStar)) _
, cstQuestion, &quot;?&quot;), cstStar, &quot;*&quot;)
@@ -1807,12 +1907,13 @@ Private Function _ConvertToUrl(psFile) As String
&apos;&apos;&apos; Execute the builtin ConvertToUrl function only when relevant
&apos;&apos;&apos; i.e. when FileNaming (how arguments and return values are provided) &lt;&gt; &quot;URL&quot;
&apos;&apos;&apos; Called at the top of methods receiving file names as arguments
-&apos;&apos;&apos; Remark: psFile might contain wildcards
+&apos;&apos;&apos; Remarks: psFile might contain wildcards
+&apos;&apos;&apos; Files from document&apos;s file systems are never converted
- If SF_FileSystem.FileNaming = &quot;URL&quot; Then
+ If SF_FileSystem.FileNaming = &quot;URL&quot; Or SF_FileSystem._IsDocFileSystem(psFile) Then
_ConvertToUrl = psFile
Else
- &apos; ConvertToUrl encodes &quot;?&quot;
+ &apos; ConvertToUrl() encodes &quot;?&quot;
_ConvertToUrl = Replace(ConvertToUrl(psFile), &quot;%3F&quot;, &quot;?&quot;)
End If
@@ -1886,7 +1987,7 @@ Check:
Select Case bFile
Case True &apos; File
If Not .FileExists(psSource) Then GoTo CatchFileNotExists
- If Not .FolderExists(.GetParentFolderName(psDestination)) Then GoTo CatchSourceFolderNotExists
+ If Not .FolderExists(.GetParentFolderName(psDestination)) Then GoTo CatchDestFolderNotExists
If .FolderExists(psDestination) Then GoTo CatchFolderNotFile
bDestExists = .FileExists(psDestination)
If pbOverWrite = False And bDestExists = True Then GoTo CatchDestinationExists
@@ -2131,6 +2232,14 @@ Dim sConfig As String &apos; Return value
End Function &apos; ScriptForge.FileSystem._GetConfigFolder
REM -----------------------------------------------------------------------------
+Public Function _IsDocFileSystem(psFile As String) As Boolean
+&apos;&apos;&apos; ReturnsTrue when the argument designates a document&apos;s internal file system
+
+ _IsDocFileSystem = SF_String.StartsWith(psFile, DOCFILESYSTEM, CaseSensitive := True)
+
+End Function &apos; ScriptForge.SF_FileSystem._IsDocFileSystem
+
+REM -----------------------------------------------------------------------------
Public Function _ParseUrl(psUrl As String) As Object
&apos;&apos;&apos; Returns a com.sun.star.util.URL structure based on the argument
diff --git a/wizards/source/scriptforge/SF_Region.xba b/wizards/source/scriptforge/SF_Region.xba
index 9ceccbbc94a6..4c13da75afac 100644
--- a/wizards/source/scriptforge/SF_Region.xba
+++ b/wizards/source/scriptforge/SF_Region.xba
@@ -858,4 +858,4 @@ Finally:
End Function &apos; ScriptForge.SF_Region._PropertyGet
REM ================================================ END OF SCRIPTFORGE.SF_REGION
-</script:module>
+</script:module> \ No newline at end of file
diff --git a/wizards/source/scriptforge/SF_Root.xba b/wizards/source/scriptforge/SF_Root.xba
index e2649d0ce1d1..488e8bfc2e8f 100644
--- a/wizards/source/scriptforge/SF_Root.xba
+++ b/wizards/source/scriptforge/SF_Root.xba
@@ -74,14 +74,15 @@ Private URLTransformer As Object &apos; com.sun.star.util.URLTransformer
Private Introspection As Object &apos; com.sun.star.beans.Introspection
Private BrowseNodeFactory As Object &apos; com.sun.star.script.browse.BrowseNodeFactory
Private DatabaseContext As Object &apos; com.sun.star.sdb.DatabaseContext
-Private ConfigurationProvider _
- As Object &apos; com.sun.star.configuration.ConfigurationProvider
+Private ConfigurationProvider As Object
+ &apos; com.sun.star.configuration.ConfigurationProvider
Private PackageProvider As Object &apos; com.sun.star.comp.deployment.PackageInformationProvider
Private MailService As Object &apos; com.sun.star.system.SimpleCommandMail or com.sun.star.system.SimpleSystemMail
Private GraphicExportFilter As Object &apos; com.sun.star.drawing.GraphicExportFilter
Private Toolkit As Object &apos; com.sun.star.awt.Toolkit
Private ModuleUIConfigurationManagerSupplier As Object
&apos; com.sun.star.ui.ModuleUIConfigurationManagerSupplier
+Private TransientDocument As Object &apos; com.sun.star.frame.TransientDocumentsDocumentContentFactory
&apos; Specific persistent services objects or properties
Private FileSystemNaming As String &apos; If &quot;SYS&quot;, file and folder naming is based on operating system notation
@@ -152,6 +153,7 @@ Private Sub Class_Initialize()
Set GraphicExportFilter = Nothing
Set Toolkit = Nothing
Set ModuleUIConfigurationManagerSupplier = Nothing
+ Set TransientDocument = Nothing
OSName = &quot;&quot;
SFDialogs = Empty
SFForms = Empty
@@ -610,6 +612,15 @@ Try:
&amp; &quot;%1: An identifier\n&quot; _
&amp; &quot;%2: A file or folder name&quot; _
)
+ &apos; SF_FileSystem.Any
+ .AddText( Context := &quot;FILESYSTEM&quot; _
+ , MsgId := &quot;The method « %2 » is not applicable on a document&apos;s internal file system.\n\n&quot; _
+ &amp; &quot;« %1 » = &apos;%3&apos;&quot; _
+ , Comment := &quot;SF_FileSystem not supported method error message\n&quot; _
+ &amp; &quot;%1: A method name\n&quot; _
+ &amp; &quot;%2: An identifier\n&quot; _
+ &amp; &quot;%3: A file or folder name&quot; _
+ )
&apos; SF_Services.CreateScriptService
.AddText( Context := &quot;UNKNOWNSERVICE&quot; _
, MsgId := &quot;No service named &apos;%4&apos; has been registered for the library &apos;%3&apos;.\n\n&quot; _
diff --git a/wizards/source/scriptforge/SF_TextStream.xba b/wizards/source/scriptforge/SF_TextStream.xba
index 35f1b6fb2b49..3da9a773f08e 100644
--- a/wizards/source/scriptforge/SF_TextStream.xba
+++ b/wizards/source/scriptforge/SF_TextStream.xba
@@ -31,6 +31,12 @@ Option Explicit
&apos;&apos;&apos; https://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1io_1_1XTextInputStream.html
&apos;&apos;&apos; https://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1io_1_1XTextOutputStream.html
&apos;&apos;&apos;
+&apos;&apos;&apos; Disk file sstems and document&apos;s internal file systems
+&apos;&apos;&apos; All methods and properties are applicable without restrictions on both file systems.
+&apos;&apos;&apos; However, when updates are operated on text files embedded in a document, (with the WriteXXX() methods),
+&apos;&apos;&apos; the updates are first done on a copy of the original file. When the file is closed, the copy
+&apos;&apos;&apos; will overwrite the original file. The whole process is transparent for the user script.
+&apos;&apos;&apos;
&apos;&apos;&apos; Instantiation example:
&apos;&apos;&apos; Dim FSO As Object, myFile As Object
&apos;&apos;&apos; Set FSO = CreateScriptService(&quot;FileSystem&quot;)
@@ -52,7 +58,7 @@ Private [Me] As Object
Private [_Parent] As Object
Private ObjectType As String &apos; Must be TEXTSTREAM
Private ServiceName As String
-Private _FileName As String &apos; File where it is about
+Private _FileName As String &apos; File where it is about in URL format
Private _IOMode As Integer &apos; ForReading, ForWriting or ForAppending
Private _Encoding As String &apos; https://www.iana.org/assignments/character-sets/character-sets.xhtml
Private _NewLine As String &apos; Line break in write mode
@@ -65,6 +71,12 @@ Private _InputStream As Object &apos; com.sun.star.io.TextInputStream
Private _OutputStream As Object &apos; com.sun.star.io.TextOutputStream
Private _ForceBlankLine As Boolean &apos; Workaround: XTextInputStream misses last line if file ends with newline
+&apos; Document&apos;s file system only
+Private _IsEmbeddedFile As Boolean &apos; True when concerned file is embedded in a document
+Private _EmbeddedFileName As String &apos; When not blank and in update mode, the full embedded file name
+ &apos; This file is initially copied in a temporary storage, modified by the actual class,
+ &apos; and rewritten in the document when the textstream.CloseFile() method is run
+
REM ============================================================ MODULE CONSTANTS
REM ===================================================== CONSTRUCTOR/DESTRUCTOR
@@ -85,6 +97,8 @@ Private Sub Class_Initialize()
Set _InputStream = Nothing
Set _OutputStream = Nothing
_ForceBlankLine = False
+ _IsEmbeddedFile = False
+ _EmbeddedFileName = &quot;&quot;
End Sub &apos; ScriptForge.SF_TextStream Constructor
REM -----------------------------------------------------------------------------
@@ -208,6 +222,7 @@ Public Function CloseFile() As Boolean
&apos;&apos;&apos; myFile.CloseFile()
Dim bClose As Boolean &apos; Return value
+Dim oSfa As Object &apos; com.sun.star.ucb.SimpleFileAccess
Const cstThisSub = &quot;TextStream.CloseFile&quot;
Const cstSubArgs = &quot;&quot;
@@ -227,6 +242,13 @@ Try:
Set _InputStream = Nothing
Set _OutputStream = Nothing
Set _FileHandler = Nothing
+
+ &apos; Manage embedded file closure: copy temporary file to document internal storage
+ If _IsEmbeddedFile Then
+ Set oSfa = SF_Utils._GetUnoService(&quot;FileAccess&quot;)
+ oSfa.copy(_FileName, _EmbeddedFileName)
+ End If
+
bClose = True
Finally:
@@ -664,7 +686,8 @@ Dim cstSubArgs As String
Case UCase(&quot;Encoding&quot;)
_PropertyGet = _Encoding
Case UCase(&quot;FileName&quot;)
- _PropertyGet = SF_FileSystem._ConvertFromUrl(_FileName) &apos; Depends on FileNaming
+ &apos; Requested is the user visible file name in FileNaming notation
+ _PropertyGet = SF_FileSystem._ConvertFromUrl(Iif(_IsEmbeddedFile, _EmbeddedFileName, _FileName))
Case UCase(&quot;IOMode&quot;)
With SF_FileSystem
Select Case _IOMode
diff --git a/wizards/source/scriptforge/SF_Utils.xba b/wizards/source/scriptforge/SF_Utils.xba
index 11753704c461..608a2e8422ca 100644
--- a/wizards/source/scriptforge/SF_Utils.xba
+++ b/wizards/source/scriptforge/SF_Utils.xba
@@ -508,6 +508,11 @@ Dim oDefaultContext As Object
Set .Toolkit = CreateUnoService(&quot;com.sun.star.awt.Toolkit&quot;)
End If
Set _GetUNOService = .Toolkit
+ Case &quot;TransientDocumentFactory&quot;
+ If IsEmpty(.TransientDocument) Or IsNull(.TransientDocument) Then
+ Set .TransientDocument = CreateUnoService(&quot;com.sun.star.frame.TransientDocumentsDocumentContentFactory&quot;)
+ End If
+ Set _GetUNOService = .TransientDocument
Case &quot;URLTransformer&quot;
If IsEmpty(.URLTransformer) Or IsNull(.URLTransformer) Then
Set .URLTransformer = CreateUnoService(&quot;com.sun.star.util.URLTransformer&quot;)
@@ -951,6 +956,7 @@ Dim bValid As Boolean &apos; Returned value
Dim sFileNaming As String &apos; Alias of SF_FileSystem.FileNaming
Dim oArgument As Variant &apos; Workaround &quot;Object variable not set&quot; error on 1st executable statement
Const cstMaxLength = 256 &apos; Maximum length of readable value
+Const DOCFILESYSTEM = &quot;vnd.sun.star.tdoc:/&quot;
&apos; To avoid useless recursions, keep main function, only increase stack depth
@@ -984,6 +990,7 @@ Try:
If bValid Then
With SF_FileSystem
sFileNaming = .FileNaming
+ If SF_String.StartsWith(sFile, DOCFILESYSTEM) Then sFileNaming = &quot;URL&quot;
Select Case sFileNaming
Case &quot;ANY&quot; : bValid = SF_String.IsUrl(ConvertToUrl(sFile))
Case &quot;URL&quot; : bValid = SF_String.IsUrl(sFile)
diff --git a/wizards/source/scriptforge/po/ScriptForge.pot b/wizards/source/scriptforge/po/ScriptForge.pot
index 58d9a4afeaab..1f18806679ac 100644
--- a/wizards/source/scriptforge/po/ScriptForge.pot
+++ b/wizards/source/scriptforge/po/ScriptForge.pot
@@ -14,7 +14,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: https://bugs.libreoffice.org/enter_bug.cgi?product=LibreOffice&bug_status=UNCONFIRMED&component=UI\n"
-"POT-Creation-Date: 2023-05-15 16:22:55\n"
+"POT-Creation-Date: 2023-07-14 16:26:26\n"
"PO-Revision-Date: YYYY-MM-DD HH:MM:SS\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n"
@@ -412,6 +412,19 @@ msgid ""
"« %1 » = %2"
msgstr ""
+#. SF_FileSystem not supported method error message
+#. %1: A method name
+#. %2: An identifier
+#. %3: A file or folder name
+#, kde-format
+msgctxt "FILESYSTEM"
+msgid ""
+"The method « %2 » is not applicable on a document's internal file "
+"system.\n"
+"\n"
+"« %1 » = '%3'"
+msgstr ""
+
#. SF_Services.CreateScriptService error message
#. %1: An identifier
#. %2: A string
diff --git a/wizards/source/scriptforge/po/en.po b/wizards/source/scriptforge/po/en.po
index 58d9a4afeaab..1f18806679ac 100644
--- a/wizards/source/scriptforge/po/en.po
+++ b/wizards/source/scriptforge/po/en.po
@@ -14,7 +14,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: https://bugs.libreoffice.org/enter_bug.cgi?product=LibreOffice&bug_status=UNCONFIRMED&component=UI\n"
-"POT-Creation-Date: 2023-05-15 16:22:55\n"
+"POT-Creation-Date: 2023-07-14 16:26:26\n"
"PO-Revision-Date: YYYY-MM-DD HH:MM:SS\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n"
@@ -412,6 +412,19 @@ msgid ""
"« %1 » = %2"
msgstr ""
+#. SF_FileSystem not supported method error message
+#. %1: A method name
+#. %2: An identifier
+#. %3: A file or folder name
+#, kde-format
+msgctxt "FILESYSTEM"
+msgid ""
+"The method « %2 » is not applicable on a document's internal file "
+"system.\n"
+"\n"
+"« %1 » = '%3'"
+msgstr ""
+
#. SF_Services.CreateScriptService error message
#. %1: An identifier
#. %2: A string
diff --git a/wizards/source/scriptforge/python/scriptforge.py b/wizards/source/scriptforge/python/scriptforge.py
index 96474e4eb4de..631ac00eb0df 100644
--- a/wizards/source/scriptforge/python/scriptforge.py
+++ b/wizards/source/scriptforge/python/scriptforge.py
@@ -694,7 +694,7 @@ class SFScriptForge:
"""
unodate = uno.createUnoStruct('com.sun.star.util.DateTime')
unodate.Year, unodate.Month, unodate.Day, unodate.Hours, unodate.Minutes, unodate.Seconds, \
- unodate.NanoSeconds, unodate.IsUTC = \
+ unodate.NanoSeconds, unodate.IsUTC = \
1899, 12, 30, 0, 0, 0, 0, False # Identical to Basic TimeSerial() function
if isinstance(date, float):
@@ -1156,8 +1156,8 @@ class SFScriptForge:
def GetParentFolderName(self, filename):
return self.ExecMethod(self.vbMethod, 'GetParentFolderName', filename)
- def GetTempName(self):
- return self.ExecMethod(self.vbMethod, 'GetTempName')
+ def GetTempName(self, extension = ''):
+ return self.ExecMethod(self.vbMethod, 'GetTempName', extension)
def HashFile(self, filename, algorithm):
py = ScriptForge.pythonhelpermodule + '$' + '_SF_FileSystem__HashFile'
@@ -2107,10 +2107,10 @@ class SFDocuments:
serviceimplementation = 'basic'
servicename = 'SFDocuments.Document'
servicesynonyms = ('document', 'sfdocuments.document')
- serviceproperties = dict(Description = True, DocumentType = False, ExportFilters = False, ImportFilters = False,
- IsBase = False, IsCalc = False, IsDraw = False, IsFormDocument = False,
- IsImpress = False, IsMath = False, IsWriter = False, Keywords = True, Readonly = False,
- Subject = True, Title = True, XComponent = False)
+ serviceproperties = dict(Description = True, DocumentType = False, ExportFilters = False, FileSystem = False,
+ ImportFilters = False, IsBase = False, IsCalc = False, IsDraw = False,
+ IsFormDocument = False, IsImpress = False, IsMath = False, IsWriter = False,
+ Keywords = True, Readonly = False, Subject = True, Title = True, XComponent = False)
# Force for each property to get its value from Basic - due to intense interactivity with user
forceGetProperty = True
@@ -2175,9 +2175,9 @@ class SFDocuments:
serviceimplementation = 'basic'
servicename = 'SFDocuments.Base'
servicesynonyms = ('base', 'scriptforge.base')
- serviceproperties = dict(DocumentType = False, IsBase = False, IsCalc = False, IsDraw = False,
- IsFormDocument = False, IsImpress = False, IsMath = False, IsWriter = False,
- XComponent = False)
+ serviceproperties = dict(DocumentType = False, FileSystem = False, IsBase = False, IsCalc = False,
+ IsDraw = False, IsFormDocument = False, IsImpress = False, IsMath = False,
+ IsWriter = False, XComponent = False)
@classmethod
def ReviewServiceArgs(cls, windowname = ''):
@@ -2233,10 +2233,10 @@ class SFDocuments:
servicename = 'SFDocuments.Calc'
servicesynonyms = ('calc', 'sfdocuments.calc')
serviceproperties = dict(CurrentSelection = True, Sheets = False,
- Description = True, DocumentType = False, ExportFilters = False, ImportFilters = False,
- IsBase = False, IsCalc = False, IsDraw = False, IsFormDocument = False,
- IsImpress = False, IsMath = False, IsWriter = False, Keywords = True, Readonly = False,
- Subject = True, Title = True, XComponent = False)
+ Description = True, DocumentType = False, ExportFilters = False, FileSystem = False,
+ ImportFilters = False, IsBase = False, IsCalc = False, IsDraw = False,
+ IsFormDocument = False, IsImpress = False, IsMath = False, IsWriter = False,
+ Keywords = True, Readonly = False, Subject = True, Title = True, XComponent = False)
# Force for each property to get its value from Basic - due to intense interactivity with user
forceGetProperty = True
@@ -2590,9 +2590,9 @@ class SFDocuments:
serviceimplementation = 'basic'
servicename = 'SFDocuments.FormDocument'
servicesynonyms = ('formdocument', 'sfdocuments.formdocument')
- serviceproperties = dict(DocumentType = False, IsBase = False, IsCalc = False, IsDraw = False,
- IsFormDocument = False, IsImpress = False, IsMath = False, IsWriter = False,
- Readonly = False, XComponent = False)
+ serviceproperties = dict(DocumentType = False, FileSystem = False, IsBase = False, IsCalc = False,
+ IsDraw = False, IsFormDocument = False, IsImpress = False, IsMath = False,
+ IsWriter = False, Readonly = False, XComponent = False)
@classmethod
def ReviewServiceArgs(cls, windowname = ''):
@@ -2627,10 +2627,10 @@ class SFDocuments:
serviceimplementation = 'basic'
servicename = 'SFDocuments.Writer'
servicesynonyms = ('writer', 'sfdocuments.writer')
- serviceproperties = dict(Description = True, DocumentType = False, ExportFilters = False, ImportFilters = False,
- IsBase = False, IsCalc = False, IsDraw = False, IsFormDocument = False,
- IsImpress = False, IsMath = False, IsWriter = False, Keywords = True, Readonly = False,
- Subject = True, Title = True, XComponent = False)
+ serviceproperties = dict(Description = True, DocumentType = False, ExportFilters = False, FileSystem = False,
+ ImportFilters = False, IsBase = False, IsCalc = False, IsDraw = False,
+ IsFormDocument = False, IsImpress = False, IsMath = False, IsWriter = False,
+ Keywords = True, Readonly = False, Subject = True, Title = True, XComponent = False)
# Force for each property to get its value from Basic - due to intense interactivity with user
forceGetProperty = True
diff --git a/wizards/source/sfdocuments/SF_Base.xba b/wizards/source/sfdocuments/SF_Base.xba
index cc5ab488365e..efc8bfeb148c 100644
--- a/wizards/source/sfdocuments/SF_Base.xba
+++ b/wizards/source/sfdocuments/SF_Base.xba
@@ -683,6 +683,7 @@ Public Function Properties() As Variant
Properties = Array( _
&quot;DocumentType&quot; _
+ , &quot;FileSystem&quot; _
, &quot;IsBase&quot; _
, &quot;IsCalc&quot; _
, &quot;IsDraw &quot; _
@@ -822,6 +823,11 @@ Property Get DocumentType() As String
End Property &apos; SFDocuments.SF_Base.DocumentType
REM -----------------------------------------------------------------------------
+Property Get FileSystem() As String
+ FileSystem = [_Super].GetProperty(&quot;FileSystem&quot;)
+End Property &apos; SFDocuments.SF_Base.FileSystem
+
+REM -----------------------------------------------------------------------------
Property Get IsBase() As Boolean
IsBase = [_Super].GetProperty(&quot;IsBase&quot;)
End Property &apos; SFDocuments.SF_Base.IsBase
diff --git a/wizards/source/sfdocuments/SF_Calc.xba b/wizards/source/sfdocuments/SF_Calc.xba
index 0138730c11f3..a78762056fb0 100644
--- a/wizards/source/sfdocuments/SF_Calc.xba
+++ b/wizards/source/sfdocuments/SF_Calc.xba
@@ -2551,6 +2551,7 @@ Public Function Properties() As Variant
, &quot;DocumentProperties&quot; _
, &quot;DocumentType&quot; _
, &quot;ExportFilters&quot; _
+ , &quot;FileSystem&quot; _
, &quot;FirstCell&quot; _
, &quot;FirstColumn&quot; _
, &quot;FirstRow&quot; _
@@ -3619,6 +3620,11 @@ Property Get ExportFilters() As Variant
End Property &apos; SFDocuments.SF_Calc.ExportFilters
REM -----------------------------------------------------------------------------
+Property Get FileSystem() As String
+ FileSystem = [_Super].GetProperty(&quot;FileSystem&quot;)
+End Property &apos; SFDocuments.SF_Calc.FileSystem
+
+REM -----------------------------------------------------------------------------
Property Get ImportFilters() As Variant
ImportFilters = [_Super].GetProperty(&quot;ImportFilters&quot;)
End Property &apos; SFDocuments.SF_Calc.ImportFilters
diff --git a/wizards/source/sfdocuments/SF_Document.xba b/wizards/source/sfdocuments/SF_Document.xba
index 2233aeb5c650..37cb39fa2010 100644
--- a/wizards/source/sfdocuments/SF_Document.xba
+++ b/wizards/source/sfdocuments/SF_Document.xba
@@ -250,6 +250,19 @@ Property Get ExportFilters() As Variant
End Property &apos; SFDocuments.SF_Document.ExportFilters
REM -----------------------------------------------------------------------------
+Property Get FileSystem() As String
+&apos;&apos;&apos; Returns the root of the document&apos;s virtual file system
+&apos;&apos;&apos; The &quot;FileSystem&quot; service may be used to explore it, as long as the document remains open
+&apos;&apos;&apos; The property is not applicable to Base documents
+&apos;&apos;&apos; Example:
+&apos;&apos;&apos; Dim sRoot As String, FSO
+&apos;&apos;&apos; sRoot = oDoc.FileSystem
+&apos;&apos;&apos; Set FSO = CreateScriptService(&quot;FileSystem&quot;)
+&apos;&apos;&apos; MsgBox FSO.FolderExists(FSO.BuildPath(sRoot, &quot;Pictures&quot;))
+ FileSystem = _PropertyGet(&quot;FileSystem&quot;)
+End Property &apos; SFDocuments.SF_Document.FileSystem
+
+REM -----------------------------------------------------------------------------
Property Get ImportFilters() As Variant
&apos;&apos;&apos; Returns the list of the import filter names applicable to the current document
&apos;&apos;&apos; as a zero-based array of strings
@@ -833,6 +846,7 @@ Public Function Properties() As Variant
, &quot;DocumentProperties&quot; _
, &quot;DocumentType&quot; _
, &quot;ExportFilters&quot; _
+ , &quot;FileSystem&quot; _
, &quot;ImportFilters&quot; _
, &quot;IsBase&quot; _
, &quot;IsCalc&quot; _
@@ -1573,6 +1587,8 @@ Private Function _PropertyGet(Optional ByVal psProperty As String) As Variant
&apos;&apos;&apos; psProperty: the name of the property
Dim oProperties As Object &apos; Document or Custom properties
+Dim oTransient As Object &apos; com.sun.star.frame.TransientDocumentsDocumentContentFactory
+Dim oContent As Object &apos; com.sun.star.comp.ucb.TransientDocumentsContent
Dim cstThisSub As String
Const cstSubArgs = &quot;&quot;
@@ -1599,6 +1615,13 @@ Const cstSubArgs = &quot;&quot;
_PropertyGet = _DocumentType
Case &quot;ExportFilters&quot;
_PropertyGet = _GetFilterNames(True)
+ Case &quot;FileSystem&quot;
+ &apos; Natural choice would have been to use the component.RunTimeUID property
+ &apos; However it is optional in the OfficeDocument service and not available for Base documents
+ &apos; Below a more generic alternative derived from the get_document_uri() method found in apso.py
+ Set oTransient = ScriptForge.SF_Utils._GetUnoService(&quot;TransientDocumentFactory&quot;)
+ Set oContent = oTransient.createDocumentContent(_Component)
+ _PropertyGet = oContent.getIdentifier().ContentIdentifier &amp; &quot;/&quot;
Case &quot;ImportFilters&quot;
_PropertyGet = _GetFilterNames(False)
Case &quot;IsBase&quot;, &quot;IsCalc&quot;, &quot;IsDraw&quot;, &quot;IsFormDocument&quot;, &quot;IsImpress&quot;, &quot;IsMath&quot;, &quot;IsWriter&quot;
diff --git a/wizards/source/sfdocuments/SF_FormDocument.xba b/wizards/source/sfdocuments/SF_FormDocument.xba
index a619ac113aa4..ddddca2f8e70 100644
--- a/wizards/source/sfdocuments/SF_FormDocument.xba
+++ b/wizards/source/sfdocuments/SF_FormDocument.xba
@@ -419,6 +419,7 @@ Public Function Properties() As Variant
Properties = Array( _
&quot;DocumentType&quot; _
+ , &quot;FileSystem&quot; _
, &quot;IsBase&quot; _
, &quot;IsCalc&quot; _
, &quot;IsDraw&quot; _
@@ -434,6 +435,11 @@ End Function &apos; SFDocuments.SF_FormDocument.Properties
REM ======================================================= SUPERCLASS PROPERTIES
REM -----------------------------------------------------------------------------
+Property Get FileSystem() As String
+ FileSystem = [_Super].GetProperty(&quot;FileSystem&quot;)
+End Property &apos; SFDocuments.SF_FormDocument.FileSystem
+
+REM -----------------------------------------------------------------------------
Property Get IsBase() As Boolean
IsBase = [_Super].GetProperty(&quot;IsBase&quot;)
End Property &apos; SFDocuments.SF_FormDocument.IsBase
diff --git a/wizards/source/sfdocuments/SF_Writer.xba b/wizards/source/sfdocuments/SF_Writer.xba
index 685fd2023a20..bc41e0fef7bc 100644
--- a/wizards/source/sfdocuments/SF_Writer.xba
+++ b/wizards/source/sfdocuments/SF_Writer.xba
@@ -310,6 +310,7 @@ Public Function Properties() As Variant
, &quot;DocumentProperties&quot; _
, &quot;DocumentType&quot; _
, &quot;ExportFilters&quot; _
+ , &quot;FileSystem&quot; _
, &quot;ImportFilters&quot; _
, &quot;IsBase&quot; _
, &quot;IsCalc&quot; _
@@ -413,6 +414,11 @@ Property Get ExportFilters() As Variant
End Property &apos; SFDocuments.SF_Writer.ExportFilters
REM -----------------------------------------------------------------------------
+Property Get FileSystem() As String
+ FileSystem = [_Super].GetProperty(&quot;FileSystem&quot;)
+End Property &apos; SFDocuments.SF_Writer.FileSystem
+
+REM -----------------------------------------------------------------------------
Property Get ImportFilters() As Variant
ImportFilters = [_Super].GetProperty(&quot;ImportFilters&quot;)
End Property &apos; SFDocuments.SF_Writer.ImportFilters