wizards/source/scriptforge/SF_Exception.xba      |    5 
 wizards/source/scriptforge/SF_FileSystem.xba     |  177 ++++++++++++++++++-----
 wizards/source/scriptforge/SF_Region.xba         |    2 
 wizards/source/scriptforge/SF_Root.xba           |   15 +
 wizards/source/scriptforge/SF_TextStream.xba     |   27 +++
 wizards/source/scriptforge/SF_Utils.xba          |    7 
 wizards/source/scriptforge/po/ScriptForge.pot    |   15 +
 wizards/source/scriptforge/po/en.po              |   15 +
 wizards/source/scriptforge/python/scriptforge.py |   42 ++---
 wizards/source/sfdocuments/SF_Base.xba           |    6 
 wizards/source/sfdocuments/SF_Calc.xba           |    6 
 wizards/source/sfdocuments/SF_Document.xba       |   23 ++
 wizards/source/sfdocuments/SF_FormDocument.xba   |    6 
 wizards/source/sfdocuments/SF_Writer.xba         |    6 
 14 files changed, 290 insertions(+), 62 deletions(-)

New commits:
commit 44334328f75dd0023122a4cb446ccba0d507720c
Author:     Jean-Pierre Ledure <j...@ledure.be>
AuthorDate: Fri Jul 14 17:11:14 2023 +0200
Commit:     Jean-Pierre Ledure <j...@ledure.be>
CommitDate: Sat Jul 15 09:54:01 2023 +0200

    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 <j...@ledure.be>
    Tested-by: Jenkins

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
@@ -2130,6 +2231,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; _
@@ -821,6 +822,11 @@ Property Get DocumentType() As String
        DocumentType = [_Super].GetProperty(&quot;DocumentType&quot;)
 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;)
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; _
@@ -3618,6 +3619,11 @@ Property Get ExportFilters() As Variant
        ExportFilters = [_Super].GetProperty(&quot;ExportFilters&quot;)
 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;)
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
@@ -249,6 +249,19 @@ Property Get ExportFilters() As Variant
        ExportFilters = _PropertyGet(&quot;ExportFilters&quot;)
 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
@@ -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; _
@@ -433,6 +434,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;)
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; _
@@ -412,6 +413,11 @@ Property Get ExportFilters() As Variant
        ExportFilters = [_Super].GetProperty(&quot;ExportFilters&quot;)
 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;)

Reply via email to