1
0
Fork 0
libreoffice/wizards/source/sfdocuments/SF_Writer.xba
Daniel Baumann 8e63e14cf6
Adding upstream version 4:25.2.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-22 16:20:04 +02:00

1182 lines
No EOL
54 KiB
XML

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE script:module PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "module.dtd">
<script:module xmlns:script="http://openoffice.org/2000/script" script:name="SF_Writer" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
REM === The SFDocuments library is one of the associated libraries. ===
REM === Full documentation is available on https://help.libreoffice.org/ ===
REM =======================================================================================================================
Option Compatible
Option ClassModule
Option Explicit
&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
&apos;&apos;&apos; SF_Writer
&apos;&apos;&apos; =========
&apos;&apos;&apos;
&apos;&apos;&apos; The SFDocuments library gathers a number of methods and properties making easy
&apos;&apos;&apos; managing and manipulating LibreOffice documents
&apos;&apos;&apos;
&apos;&apos;&apos; Some methods are generic for all types of documents: they are combined in the SF_Document module.
&apos;&apos;&apos; Specific properties and methods are implemented in the concerned subclass(es) SF_Calc, SF_Writer, SF_Base, ...
&apos;&apos;&apos;
&apos;&apos;&apos; To workaround the absence of class inheritance in LibreOffice Basic, some redundancy is necessary
&apos;&apos;&apos; Each subclass MUST implement also the generic methods and properties, even if they only call
&apos;&apos;&apos; the parent methods and properties.
&apos;&apos;&apos; They should also duplicate some generic private members as a subset of their own set of members
&apos;&apos;&apos;
&apos;&apos;&apos; The SF_Writer module is focused on selecting, reading, inserting, modifying texts and values
&apos;&apos;&apos; on well-identified and predefined places in the document.
&apos;&apos;&apos; Usually such customization of the document starts from a predefined template.
&apos;&apos;&apos; Multiple customizations are also known as mail merging.
&apos;&apos;&apos;
&apos;&apos;&apos; As a consequence, focus is not on text formatting, except by the application of styles
&apos;&apos;&apos; onto the targeted text fragments.
&apos;&apos;&apos;
&apos;&apos;&apos; The positions in the text where customization can take place easily are:
&apos;&apos;&apos; - the start and end positions of the text body
&apos;&apos;&apos; - the start and end positions of text frames
&apos;&apos;&apos; - bookmarks
&apos;&apos;&apos; - text fields
&apos;&apos;&apos; - the start and end positions of document sections
&apos;&apos;&apos; - writer tables and table cells
&apos;&apos;&apos; - the area currently selected by the user, i.e. the &quot;visible&quot; selection
&apos;&apos;&apos;
&apos;&apos;&apos; The current module is closely related to the &quot;UI&quot; service of the ScriptForge library
&apos;&apos;&apos;
&apos;&apos;&apos; Service invocation examples:
&apos;&apos;&apos; 1) From the UI service
&apos;&apos;&apos; Dim ui As Object, oDoc As Object
&apos;&apos;&apos; Set ui = CreateScriptService(&quot;UI&quot;)
&apos;&apos;&apos; Set oDoc = ui.CreateDocument(&quot;Writer&quot;, ...)
&apos;&apos;&apos; &apos; or Set oDoc = ui.OpenDocument(&quot;C:\Me\MyFile.odt&quot;)
&apos;&apos;&apos; 2) Directly if the document is already opened
&apos;&apos;&apos; Dim oDoc As Object
&apos;&apos;&apos; Set oDoc = CreateScriptService(&quot;SFDocuments.Writer&quot;, ThisComponent) &apos; Default = ActiveWindow
&apos;&apos;&apos; &apos; or Set oDoc = CreateScriptService(&quot;SFDocuments.Writer&quot;, &quot;Untitled 1&quot;) &apos; Untitled 1 is presumed a Writer document
&apos;&apos;&apos; &apos; The substring &quot;SFDocuments.&quot; in the service name is optional
&apos;&apos;&apos;
&apos;&apos;&apos; Definitions:
&apos;&apos;&apos; Many methods require a &quot;TextRange&quot; as argument.
&apos;&apos;&apos; A textrange is a string describing the scope on which to apply the method.
&apos;&apos;&apos; Such a textrange corresponds either with a single insertion point or with a (text) interval between 2 insertion points.
&apos;&apos;&apos; Multiple textranges are not supported in this context.
&apos;&apos;&apos;
&apos;&apos;&apos; TextRange: a string containing one of next variants :
&apos;&apos;&apos; (names may be surrounded with single or double quotes)
&apos;&apos;&apos; &quot;~&quot; or &quot;SELECTION&quot; or &quot;SEL&quot; = current selection (if multiple selections, its 1st component)
&apos;&apos;&apos; &quot;BODY&quot; = the main text of the actual document instance
&apos;&apos;&apos; &quot;FRAME!name&quot; = the text contained in a text frame
&apos;&apos;&apos; &quot;BOOKMARK!name&quot; = the given bookmark, may be zero or more characters long
&apos;&apos;&apos; &quot;FIELD!name&quot; = a user text field
&apos;&apos;&apos; &quot;SECTION!name&quot; = the text contained in a section
&apos;&apos;&apos; &quot;TABLE!name!&quot; = the whole cellrange of a table
&apos;&apos;&apos; &quot;TABLE!name!cellrange&quot; = a cell (cellrange = &quot;B3&quot;) or a range of cells (&quot;A2:B3&quot;)
&apos;&apos;&apos; &quot;WORD+3&quot; = 3 words after the current selection
&apos;&apos;&apos; &quot;SENTENCE-1&quot; = the sentence before the current selection
&apos;&apos;&apos; &quot;PARAGRAPH&quot; or &quot;§&quot; = the paragraph containing the current selection (0 is the default)
&apos;&apos;&apos; optionally combined with next control character:
&apos;&apos;&apos; &quot;|&quot;: start or end of string
&apos;&apos;&apos; &quot;|~&quot; = the point immediately before the current visible selection (starting point)
&apos;&apos;&apos; &quot;~|&quot; = the point immediately after the current visible selection (ending point)
&apos;&apos;&apos; &quot;~&quot;, &quot;|~|&quot; = the full visible selection
&apos;&apos;&apos;
&apos;&apos;&apos;
&apos;&apos;&apos; Detailed user documentation:
&apos;&apos;&apos; https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03/sf_writer.html?DbPAR=BASIC
&apos;&apos;&apos;
&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;
REM ================================================================== EXCEPTIONS
Private Const WRITERFORMNOTFOUNDERROR = &quot;WRITERFORMNOTFOUNDERROR&quot;
Private Const WRITERRANGEERROR = &quot;WRITERRANGEERROR&quot;
REM ============================================================= PRIVATE MEMBERS
Private [Me] As Object
Private [_Parent] As Object
Private [_Super] As Object &apos; Document superclass, which the current instance is a subclass of
Private ObjectType As String &apos; Must be WRITER
Private ServiceName As String
&apos; Window component
Private _Component As Object &apos; com.sun.star.lang.XComponent
&apos; Text Range
Type _TextRange
RangeString As String &apos; The input string
Target As String &apos; Selection or Body or Frame or ...
TargetName As String &apos; Name of Frame or Table or ...
TargetCell As String &apos; Cell
TargetObject As Object &apos; Field, TableCell, Section, ... object
Offset As Long &apos; Number of items to right (+) or to left (-)
StartPoint As Boolean &apos; When True, vertical bar before target
EndPoint As Boolean &apos; When True, vertical bar after target
Anchor As Object &apos; com.sun.star.text.XTextRange
Text As Object &apos; com.sun.star.text.XText
Cursor As Object &apos; com.sun.star.text.XTextCursor
Location As String &apos; BODY or FOOTNOTE or HEADER/FOOTER ...
End Type
REM ============================================================ MODULE CONSTANTS
Const ISDOCFORM = 1 &apos; Form is stored in a Writer document
REM ====================================================== CONSTRUCTOR/DESTRUCTOR
REM -----------------------------------------------------------------------------
Private Sub Class_Initialize()
Set [Me] = Nothing
Set [_Parent] = Nothing
Set [_Super] = Nothing
ObjectType = &quot;WRITER&quot;
ServiceName = &quot;SFDocuments.Writer&quot;
Set _Component = Nothing
End Sub &apos; SFDocuments.SF_Writer Constructor
REM -----------------------------------------------------------------------------
Private Sub Class_Terminate()
Call Class_Initialize()
End Sub &apos; SFDocuments.SF_Writer Destructor
REM -----------------------------------------------------------------------------
Public Function Dispose() As Variant
If Not IsNull([_Super]) Then Set [_Super] = [_Super].Dispose()
Call Class_Terminate()
Set Dispose = Nothing
End Function &apos; SFDocuments.SF_Writer Explicit Destructor
REM ================================================================== PROPERTIES
REM -----------------------------------------------------------------------------
Property Get Bookmarks() As Variant
&apos;&apos;&apos; Return the list of currently available bookmarks as a zero-based array
Bookmarks = _PropertyGet(&quot;Bookmarks&quot;)
End Property &apos; SFDocuments.SF_Writer.Bookmarks (get)
REM -----------------------------------------------------------------------------
Property Get CurrentSelection() As Variant
&apos;&apos;&apos; Return the list of currently available CurrentSelection as a zero-based array
CurrentSelection = _PropertyGet(&quot;CurrentSelection&quot;)
End Property &apos; SFDocuments.SF_Writer.CurrentSelection (get)
REM -----------------------------------------------------------------------------
Property Let CurrentSelection(Optional ByVal pvSelection As Variant)
&apos;&apos;&apos; Set the selection to a single or a multiple range
&apos;&apos;&apos; The argument can be:
&apos;&apos;&apos; - a string (a textrange)
&apos;&apos;&apos; - a com.sun.star.text.XTextRange object
&apos;&apos;&apos; - a collection of com.sun.star.text.XTextRange objects
Dim vSelection As Variant &apos; Alias of pvSelection
Dim oSelection As Object &apos; com.sun.star.text.XTextRange
Dim sType As String &apos; session.UnoObjectType()
Dim oSess As Object : Set oSess = ScriptForge.SF_Session
Dim i As Long
Const cstThisSub = &quot;SFDocuments.Writer.setCurrentSelection&quot;
Const cstSubArgs = &quot;Selection&quot;
If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
Check:
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not _IsStillAlive(True) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(pvSelection, &quot;Selection&quot;, Array(V_STRING, ScriptForge.V_Object)) Then GoTo Finally
End If
Try:
vSelection = pvSelection &apos; Necessary to avoid the &quot;Object variable not set&quot; error
With _Component.CurrentController
If VarType(vSelection) = V_STRING Then
Set oSelection = _ParseRange(vSelection).Cursor
If Not IsNull(oSelection) Then .select(oSelection)
Else
sType = oSess.UnoObjectType(vSelection)
Select Case sType
Case &quot;SwXTextRanges&quot; &apos; Argument is a multiple selection
For i = 0 To vSelection.Count - 1
If oSess.UnoObjectType(vSelection.getByIndex(i)) &lt;&gt; &quot;SwXTextRange&quot; Then GoTo Catch &apos; Do nothing
Next i
.select(vSelection)
Case &quot;SwXTextRange&quot;, &quot;SwXTextCursor&quot;, &quot;SwXTextTableCursor&quot; &apos; Argument is a simple selection (anchor/cursor)
.select(vSelection)
Case Else
End Select
End If
End With
Finally:
ScriptForge.SF_Utils._ExitFunction(cstThisSub)
Exit Property
Catch:
GoTo Finally
End Property &apos; SFDocuments.SF_Writer.CurrentSelection (let)
REM -----------------------------------------------------------------------------
Property Get Fields() As Variant
&apos;&apos;&apos; Return the list of currently available fields as a zero-based array
&apos;&apos;&apos; Are considered only next field-types:
&apos;&apos;&apos; - user fields: com.sun.star.text.textfield.User
&apos;&apos;&apos; - variable fields: com.sun.star.text.textfield.SetExpression
Fields = _PropertyGet(&quot;Fields&quot;)
End Property &apos; SFDocuments.SF_Writer.Fields (get)
REM -----------------------------------------------------------------------------
Property Get Frames() As Variant
&apos;&apos;&apos; Return the list of currently available frames as a zero-based array
Frames = _PropertyGet(&quot;Frames&quot;)
End Property &apos; SFDocuments.SF_Writer.Frames (get)
REM ===================================================================== METHODS
REM -----------------------------------------------------------------------------
Public Function Forms(Optional ByVal Form As Variant) As Variant
&apos;&apos;&apos; Return either
&apos;&apos;&apos; - the list of the Forms contained in the form document
&apos;&apos;&apos; - a SFDocuments.Form object based on its name or its index
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Form: a form stored in the document given by its name or its index
&apos;&apos;&apos; When absent, the list of available forms is returned
&apos;&apos;&apos; To get the first (unique ?) form stored in the form document, set Form = 0
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; WRITERFORMNOTFOUNDERROR Form not found
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; A zero-based array of strings if Form is absent
&apos;&apos;&apos; An instance of the SF_Form class if Form exists
&apos;&apos;&apos; Example:
&apos;&apos;&apos; Dim myForm As Object, myList As Variant
&apos;&apos;&apos; myList = oDoc.Forms()
&apos;&apos;&apos; Set myForm = oDoc.Forms(&quot;myForm&quot;)
Dim oForm As Object &apos; The new Form class instance
Dim oMainForm As Object &apos; com.sun.star.comp.sdb.Content
Dim oXForm As Object &apos; com.sun.star.form.XForm
Dim vFormNames As Variant &apos; Array of form names
Dim oForms As Object &apos; Forms collection
Const cstDrawPage = 0 &apos; Only 1 drawpage in a Writer document
Const cstThisSub = &quot;SFDocuments.Writer.Forms&quot;
Const cstSubArgs = &quot;[Form=&quot;&quot;&quot;&quot;]&quot;
If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
Check:
If IsMissing(Form) Or IsEmpty(Form) Then Form = &quot;&quot;
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not _IsStillAlive() Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(Form, &quot;Form&quot;, Array(V_STRING, ScriptForge.V_NUMERIC)) Then GoTo Finally
End If
Try:
&apos; Start from the document component and go down to forms
Set oForms = _Component.DrawPages(cstDrawPage).Forms
vFormNames = oForms.getElementNames()
If Len(Form) = 0 Then &apos; Return the list of valid form names
Forms = vFormNames
Else
If VarType(Form) = V_STRING Then &apos; Find the form by name
If Not ScriptForge.SF_Array.Contains(vFormNames, Form, CaseSensitive := True) Then GoTo CatchNotFound
Set oXForm = oForms.getByName(Form)
Else &apos; Find the form by index
If Form &lt; 0 Or Form &gt;= oForms.Count Then GoTo CatchNotFound
Set oXForm = oForms.getByIndex(Form)
End If
&apos; Create the new Form class instance
Set oForm = SF_Register._NewForm(oXForm)
With oForm
Set .[_Parent] = [Me]
._FormType = ISDOCFORM
Set ._Component = _Component
._Initialize()
End With
Set Forms = oForm
End If
Finally:
ScriptForge.SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
CatchNotFound:
ScriptForge.SF_Exception.RaiseFatal(WRITERFORMNOTFOUNDERROR, Form, _FileIdent())
End Function &apos; SFDocuments.SF_Writer.Forms
REM -----------------------------------------------------------------------------
Public Function GetProperty(Optional ByVal PropertyName As Variant _
) As Variant
&apos;&apos;&apos; Return the actual value of the given property
&apos;&apos;&apos; Args:
&apos;&apos;&apos; PropertyName: the name of the property as a string
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; The actual value of the property
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; ARGUMENTERROR The property does not exist
Const cstThisSub = &quot;SFDocuments.Writer.GetProperty&quot;
Const cstSubArgs = &quot;&quot;
If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
GetProperty = Null
Check:
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not ScriptForge.SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
End If
Try:
&apos; Superclass or subclass property ?
If ScriptForge.SF_Array.Contains([_Super].Properties(), PropertyName) Then
GetProperty = [_Super].GetProperty(PropertyName)
Else
GetProperty = _PropertyGet(PropertyName)
End If
Finally:
ScriptForge.SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
End Function &apos; SFDocuments.SF_Writer.GetProperty
REM -----------------------------------------------------------------------------
Public Function Methods() As Variant
&apos;&apos;&apos; Return the list of public methods of the Writer service as an array
Methods = Array( _
&quot;Forms&quot; _
, &quot;PrintOut&quot; _
)
End Function &apos; SFDocuments.SF_Writer.Methods
REM -----------------------------------------------------------------------------
Public Function PrintOut(Optional ByVal Pages As Variant _
, Optional ByVal Copies As Variant _
, Optional ByVal PrintBackground As Variant _
, Optional ByVal PrintBlankPages As Variant _
, Optional ByVal PrintEvenPages As Variant _
, Optional ByVal PrintOddPages As Variant _
, Optional ByVal PrintImages As Variant _
) As Boolean
&apos;&apos;&apos; Send the content of the document to the printer.
&apos;&apos;&apos; The printer might be defined previously by default, by the user or by the SetPrinter() method
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Pages: the pages to print as a string, like in the user interface. Example: &quot;1-4;10;15-18&quot;. Default = all pages
&apos;&apos;&apos; Copies: the number of copies
&apos;&apos;&apos; PrintBackground: print the background image when True (default)
&apos;&apos;&apos; PrintBlankPages: when False (default), omit empty pages
&apos;&apos;&apos; PrintEvenPages: print the left pages when True (default)
&apos;&apos;&apos; PrintOddPages: print the right pages when True (default)
&apos;&apos;&apos; PrintImages: print the graphic objects when True (default)
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; True when successful
&apos;&apos;&apos; Examples:
&apos;&apos;&apos; oDoc.PrintOut(&quot;1-4;10;15-18&quot;, Copies := 2, PrintImages := False)
Dim bPrint As Boolean &apos; Return value
Dim vPrintOptions As Variant &apos; com.sun.star.text.DocumentSettings
Const cstThisSub = &quot;SFDocuments.Writer.PrintOut&quot;
Const cstSubArgs = &quot;[Pages=&quot;&quot;&quot;&quot;], [Copies=1], [PrintBackground=True], [PrintBlankPages=False], [PrintEvenPages=True]&quot; _
&amp; &quot;, [PrintOddPages=True], [PrintImages=True]&quot;
If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
bPrint = False
Check:
If IsMissing(Pages) Or IsEmpty(Pages) Then Pages = &quot;&quot;
If IsMissing(Copies) Or IsEmpty(Copies) Then Copies = 1
If IsMissing(PrintBackground) Or IsEmpty(PrintBackground) Then PrintBackground = True
If IsMissing(PrintBlankPages) Or IsEmpty(PrintBlankPages) Then PrintBlankPages = False
If IsMissing(PrintEvenPages) Or IsEmpty(PrintEvenPages) Then PrintEvenPages = True
If IsMissing(PrintOddPages) Or IsEmpty(PrintOddPages) Then PrintOddPages = True
If IsMissing(PrintImages) Or IsEmpty(PrintImages) Then PrintImages = True
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not _IsStillAlive() Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(Pages, &quot;Pages&quot;, V_STRING) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(Copies, &quot;Copies&quot;, ScriptForge.V_NUMERIC) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(PrintBackground, &quot;PrintBackground&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(PrintBlankPages, &quot;PrintBlankPages&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(PrintEvenPages, &quot;PrintEvenPages&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(PrintOddPages, &quot;PrintOddPages&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(PrintImages, &quot;PrintImages&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
End If
Try:
vPrintOptions = _Component.createInstance(&quot;com.sun.star.text.DocumentSettings&quot;)
With vPrintOptions
.PrintPageBackground = PrintBackground
.PrintEmptyPages = PrintBlankPages
.PrintLeftPages = PrintEvenPages
.PrintRightPages = PrintOddPages
.PrintGraphics = PrintImages
.PrintDrawings = PrintImages
End With
bPrint = [_Super].PrintOut(Pages, Copies, _Component)
Finally:
PrintOut = bPrint
ScriptForge.SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
End Function &apos; SFDocuments.SF_Writer.PrintOut
REM -----------------------------------------------------------------------------
Public Function Properties() As Variant
&apos;&apos;&apos; Return the list or properties of the Writer class as an array
Properties = Array( _
&quot;Bookmarks&quot; _
, &quot;CurrentSelection&quot; _
, &quot;CustomProperties&quot; _
, &quot;Description&quot; _
, &quot;DocumentProperties&quot; _
, &quot;DocumentType&quot; _
, &quot;ExportFilters&quot; _
, &quot;Fields&quot; _
, &quot;FileSystem&quot; _
, &quot;Frames&quot; _
, &quot;ImportFilters&quot; _
, &quot;IsAlive&quot; _
, &quot;IsBase&quot; _
, &quot;IsCalc&quot; _
, &quot;IsDraw&quot; _
, &quot;IsFormDocument&quot; _
, &quot;IsImpress&quot; _
, &quot;IsMath&quot; _
, &quot;IsWriter&quot; _
, &quot;Keywords&quot; _
, &quot;Readonly&quot; _
, &quot;StyleFamilies&quot; _
, &quot;Subject&quot; _
, &quot;Title&quot; _
, &quot;XComponent&quot; _
, &quot;XDocumentSettings&quot; _
)
End Function &apos; SFDocuments.SF_Writer.Properties
REM -----------------------------------------------------------------------------
Private Function SetProperty(Optional ByVal psProperty As String _
, Optional ByVal pvValue As Variant _
) As Boolean
&apos;&apos;&apos; Set the new value of the named property
&apos;&apos;&apos; Args:
&apos;&apos;&apos; psProperty: the name of the property
&apos;&apos;&apos; pvValue: the new value of the given property
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; True if successful
Dim bSet As Boolean &apos; Return value
Static oSession As Object &apos; Alias of SF_Session
Dim cstThisSub As String
Const cstSubArgs = &quot;Value&quot;
If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
bSet = False
cstThisSub = &quot;SFDocuments.Writer.set&quot; &amp; psProperty
If IsMissing(pvValue) Then pvValue = Empty
&apos;ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) &apos; Validation done in Property Lets
If IsNull(oSession) Then Set oSession = ScriptForge.SF_Services.CreateScriptService(&quot;Session&quot;)
bSet = True
Select Case UCase(psProperty)
Case UCase(&quot;CustomProperties&quot;)
CustomProperties = pvValue
Case UCase(&quot;Description&quot;)
Description = pvValue
Case UCase(&quot;Keywords&quot;)
Keywords = pvValue
Case UCase(&quot;Subject&quot;)
Subject = pvValue
Case UCase(&quot;Title&quot;)
Title = pvValue
Case Else
bSet = False
End Select
Finally:
SetProperty = bSet
&apos;ScriptForge.SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
End Function &apos; SFDocuments.SF_Writer.SetProperty
REM ======================================================= SUPERCLASS PROPERTIES
REM -----------------------------------------------------------------------------
Property Get CustomProperties() As Variant
CustomProperties = [_Super].GetProperty(&quot;CustomProperties&quot;)
End Property &apos; SFDocuments.SF_Writer.CustomProperties
REM -----------------------------------------------------------------------------
Property Let CustomProperties(Optional ByVal pvCustomProperties As Variant)
[_Super].CustomProperties = pvCustomProperties
End Property &apos; SFDocuments.SF_Writer.CustomProperties
REM -----------------------------------------------------------------------------
Property Get Description() As Variant
Description = [_Super].GetProperty(&quot;Description&quot;)
End Property &apos; SFDocuments.SF_Writer.Description
REM -----------------------------------------------------------------------------
Property Let Description(Optional ByVal pvDescription As Variant)
[_Super].Description = pvDescription
End Property &apos; SFDocuments.SF_Writer.Description
REM -----------------------------------------------------------------------------
Property Get DocumentProperties() As Variant
DocumentProperties = [_Super].GetProperty(&quot;DocumentProperties&quot;)
End Property &apos; SFDocuments.SF_Writer.DocumentProperties
REM -----------------------------------------------------------------------------
Property Get DocumentType() As String
DocumentType = [_Super].GetProperty(&quot;DocumentType&quot;)
End Property &apos; SFDocuments.SF_Writer.DocumentType
REM -----------------------------------------------------------------------------
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;)
End Property &apos; SFDocuments.SF_Writer.ImportFilters
REM -----------------------------------------------------------------------------
Property Get IsAlive() As Boolean
IsAlive = [_Super].GetProperty(&quot;IsAlive&quot;)
End Property &apos; SFDocuments.SF_Writer.IsAlive
REM -----------------------------------------------------------------------------
Property Get IsBase() As Boolean
IsBase = [_Super].GetProperty(&quot;IsBase&quot;)
End Property &apos; SFDocuments.SF_Writer.IsBase
REM -----------------------------------------------------------------------------
Property Get IsCalc() As Boolean
IsCalc = [_Super].GetProperty(&quot;IsCalc&quot;)
End Property &apos; SFDocuments.SF_Writer.IsCalc
REM -----------------------------------------------------------------------------
Property Get IsDraw() As Boolean
IsDraw = [_Super].GetProperty(&quot;IsDraw&quot;)
End Property &apos; SFDocuments.SF_Writer.IsDraw
REM -----------------------------------------------------------------------------
Property Get IsFormDocument() As Boolean
IsFormDocument = [_Super].GetProperty(&quot;IsFormDocument&quot;)
End Property &apos; SFDocuments.SF_Writer.IsFormDocument
REM -----------------------------------------------------------------------------
Property Get IsImpress() As Boolean
IsImpress = [_Super].GetProperty(&quot;IsImpress&quot;)
End Property &apos; SFDocuments.SF_Writer.IsImpress
REM -----------------------------------------------------------------------------
Property Get IsMath() As Boolean
IsMath = [_Super].GetProperty(&quot;IsMath&quot;)
End Property &apos; SFDocuments.SF_Writer.IsMath
REM -----------------------------------------------------------------------------
Property Get IsWriter() As Boolean
IsWriter = [_Super].GetProperty(&quot;IsWriter&quot;)
End Property &apos; SFDocuments.SF_Writer.IsWriter
REM -----------------------------------------------------------------------------
Property Get Keywords() As Variant
Keywords = [_Super].GetProperty(&quot;Keywords&quot;)
End Property &apos; SFDocuments.SF_Writer.Keywords
REM -----------------------------------------------------------------------------
Property Let Keywords(Optional ByVal pvKeywords As Variant)
[_Super].Keywords = pvKeywords
End Property &apos; SFDocuments.SF_Writer.Keywords
REM -----------------------------------------------------------------------------
Property Get Readonly() As Variant
Readonly = [_Super].GetProperty(&quot;Readonly&quot;)
End Property &apos; SFDocuments.SF_Writer.Readonly
REM -----------------------------------------------------------------------------
Property Get StyleFamilies() As Variant
StyleFamilies = [_Super].GetProperty(&quot;StyleFamilies&quot;)
End Property &apos; SFDocuments.SF_Writer.StyleFamilies
REM -----------------------------------------------------------------------------
Property Get Subject() As Variant
Subject = [_Super].GetProperty(&quot;Subject&quot;)
End Property &apos; SFDocuments.SF_Writer.Subject
REM -----------------------------------------------------------------------------
Property Let Subject(Optional ByVal pvSubject As Variant)
[_Super].Subject = pvSubject
End Property &apos; SFDocuments.SF_Writer.Subject
REM -----------------------------------------------------------------------------
Property Get Title() As Variant
Title = [_Super].GetProperty(&quot;Title&quot;)
End Property &apos; SFDocuments.SF_Writer.Title
REM -----------------------------------------------------------------------------
Property Let Title(Optional ByVal pvTitle As Variant)
[_Super].Title = pvTitle
End Property &apos; SFDocuments.SF_Writer.Title
REM -----------------------------------------------------------------------------
Property Get XComponent() As Variant
XComponent = [_Super].GetProperty(&quot;XComponent&quot;)
End Property &apos; SFDocuments.SF_Writer.XComponent
REM -----------------------------------------------------------------------------
Property Get XDocumentSettings() As Variant
XDocumentSettings = [_Super].GetProperty(&quot;XDocumentSettings&quot;)
End Property &apos; SFDocuments.SF_Writer.XDocumentSettings
REM ========================================================== SUPERCLASS METHODS
REM -----------------------------------------------------------------------------
Public Function Activate() As Boolean
Activate = [_Super].Activate()
End Function &apos; SFDocuments.SF_Writer.Activate
REM -----------------------------------------------------------------------------
Public Function CloseDocument(Optional ByVal SaveAsk As Variant) As Boolean
CloseDocument = [_Super].CloseDocument(SaveAsk)
End Function &apos; SFDocuments.SF_Writer.CloseDocument
REM -----------------------------------------------------------------------------
Public Function ContextMenus(Optional ByVal ContextMenuName As Variant _
, Optional ByVal SubmenuChar As Variant _
) As Variant
ContextMenus = [_Super].ContextMenus(ContextMenuName, SubmenuChar)
End Function &apos; SFDocuments.SF_Writer.ContextMenus
REM -----------------------------------------------------------------------------
Public Function CreateMenu(Optional ByVal MenuHeader As Variant _
, Optional ByVal Before As Variant _
, Optional ByVal SubmenuChar As Variant _
) As Object
Set CreateMenu = [_Super].CreateMenu(MenuHeader, Before, SubmenuChar)
End Function &apos; SFDocuments.SF_Writer.CreateMenu
REM -----------------------------------------------------------------------------
Public Sub DeleteStyles(Optional ByVal Family As Variant _
, Optional ByRef StylesList As Variant _
)
[_Super].DeleteStyles(Family, StylesList)
End Sub &apos; SFDocuments.SF_Writer.DeleteStyles
REM -----------------------------------------------------------------------------
Public Sub Echo(Optional ByVal EchoOn As Variant _
, Optional ByVal Hourglass As Variant _
)
[_Super].Echo(EchoOn, Hourglass)
End Sub &apos; SFDocuments.SF_Writer.Echo
REM -----------------------------------------------------------------------------
Public Function ExportAsPDF(Optional ByVal FileName As Variant _
, Optional ByVal Overwrite As Variant _
, Optional ByVal Pages As Variant _
, Optional ByVal Password As Variant _
, Optional ByVal Watermark As Variant _
) As Boolean
ExportAsPDF = [_Super].ExportAsPDF(FileName, Overwrite, Pages, Password, Watermark)
End Function &apos; SFDocuments.SF_Writer.ExportAsPDF
REM -----------------------------------------------------------------------------
Public Sub ImportStylesFromFile(Optional FileName As Variant _
, Optional ByRef Families As Variant _
, Optional ByVal Overwrite As variant _
) As Variant
[_Super]._ImportStylesFromFile(FileName, Families, Overwrite)
End Sub &apos; SFDocuments.SF_Writer.ImportStylesFromFile
REM -----------------------------------------------------------------------------
Public Function RemoveMenu(Optional ByVal MenuHeader As Variant) As Boolean
RemoveMenu = [_Super].RemoveMenu(MenuHeader)
End Function &apos; SFDocuments.SF_Writer.RemoveMenu
REM -----------------------------------------------------------------------------
Public Sub RunCommand(Optional ByVal Command As Variant _
, ParamArray Args As Variant _
)
[_Super].RunCommand(Command, Args)
End Sub &apos; SFDocuments.SF_Writer.RunCommand
REM -----------------------------------------------------------------------------
Public Function Save() As Boolean
Save = [_Super].Save()
End Function &apos; SFDocuments.SF_Writer.Save
REM -----------------------------------------------------------------------------
Public Function SaveAs(Optional ByVal FileName As Variant _
, Optional ByVal Overwrite As Variant _
, Optional ByVal Password As Variant _
, Optional ByVal FilterName As Variant _
, Optional ByVal FilterOptions As Variant _
) As Boolean
SaveAs = [_Super].SaveAs(FileName, Overwrite, Password, FilterName, FilterOptions)
End Function &apos; SFDocuments.SF_Writer.SaveAs
REM -----------------------------------------------------------------------------
Public Function SaveCopyAs(Optional ByVal FileName As Variant _
, Optional ByVal Overwrite As Variant _
, Optional ByVal Password As Variant _
, Optional ByVal FilterName As Variant _
, Optional ByVal FilterOptions As Variant _
) As Boolean
SaveCopyAs = [_Super].SaveCopyAs(FileName, Overwrite, Password, FilterName, FilterOptions)
End Function &apos; SFDocuments.SF_Writer.SaveCopyAs
REM -----------------------------------------------------------------------------
Public Function SetPrinter(Optional ByVal Printer As Variant _
, Optional ByVal Orientation As Variant _
, Optional ByVal PaperFormat As Variant _
) As Boolean
SetPrinter = [_Super].SetPrinter(Printer, Orientation, PaperFormat)
End Function &apos; SFDocuments.SF_Writer.SetPrinter
REM -----------------------------------------------------------------------------
Public Function Styles(Optional ByVal Family As Variant _
, Optional ByVal NamePattern As variant _
, Optional ByVal Used As variant _
, Optional ByVal UserDefined As Variant _
, Optional ByVal ParentStyle As Variant _
, Optional ByVal Category As Variant _
) As Variant
Styles = [_Super].Styles(Family, NamePattern, Used, UserDefined, ParentStyle, Category)
End Function &apos; SFDocuments.SF_Writer.Styles
REM -----------------------------------------------------------------------------
Public Function Toolbars(Optional ByVal ToolbarName As Variant) As Variant
Toolbars = [_Super].Toolbars(ToolbarName)
End Function &apos; SFDocuments.SF_Writer.Toolbars
REM -----------------------------------------------------------------------------
Public Function XStyle(Optional ByVal Family As Variant _
, Optional ByVal StyleName As variant _
) As Object
Set XStyle = [_Super].XStyle(Family, StyleName)
End Function &apos; SFDocuments.SF_Writer.XStyle
REM =========================================================== PRIVATE FUNCTIONS
REM -----------------------------------------------------------------------------
Private Function _FileIdent() As String
&apos;&apos;&apos; Returns a file identification from the information that is currently available
&apos;&apos;&apos; Useful e.g. for display in error messages
_FileIdent = [_Super]._FileIdent()
End Function &apos; SFDocuments.SF_Writer._FileIdent
REM -----------------------------------------------------------------------------
Private Function _IsStillAlive(Optional ByVal pbForUpdate As Boolean _
, Optional ByVal pbError As Boolean _
) As Boolean
&apos;&apos;&apos; Returns True if the document has not been closed manually or incidentally since the last use
&apos;&apos;&apos; If dead the actual instance is disposed. The execution is cancelled when pbError = True (default)
&apos;&apos;&apos; Args:
&apos;&apos;&apos; pbForUpdate: if True (default = False), check additionally if document is open for editing
&apos;&apos;&apos; pbError: if True (default), raise a fatal error
Dim bAlive As Boolean &apos; Return value
If IsMissing(pbForUpdate) Then pbForUpdate = False
If IsMissing(pbError) Then pbError = True
Try:
bAlive = [_Super]._IsStillAlive(pbForUpdate, pbError)
Finally:
_IsStillAlive = bAlive
Exit Function
End Function &apos; SFDocuments.SF_Writer._IsStillAlive
REM -----------------------------------------------------------------------------
Private Function _ParseRange(psTextRange As String) As Object
&apos;&apos;&apos; Parse and validate a text range passed as a string
&apos;&apos;&apos; Syntax to parse:
&apos;&apos;&apos; [|]~ or &quot;SELECTION&quot; or &quot;SEL&quot;[|]
&apos;&apos;&apos; [|]BODY[|]
&apos;&apos;&apos; [|]FRAME!name[|]
&apos;&apos;&apos; BOOKMARK!name
&apos;&apos;&apos; FIELD!name
&apos;&apos;&apos; [|]SECTION!name[|]
&apos;&apos;&apos; TABLE!name!cell
&apos;&apos;&apos; [|]WORD±n[|]
&apos;&apos;&apos; [|]SENTENCE±n[|]
&apos;&apos;&apos; [|]PARAGRAPH±n or §±n[|]
&apos;&apos;&apos; A name must be surrounded with single or double quotes when it contains a space or a not alphanumeric character
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; An object of type _TextRange
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; WRITERRANGEERROR &apos; Text range could not be parsed to a valid location
Dim oTextRange As Object &apos; Return value
Dim bParsing As Boolean &apos; When True, parsing could identify the target
Dim lSelects As Long &apos; Number of items in the current selection
Dim sTarget As String &apos; Alias of _TextRange.Target
Dim sString As String &apos; Work variable
Dim sLeft1 As String &apos; The 1st character of sString
Dim sSign As String &apos; + or -
Dim oColl As Object &apos; Collection of TargetObjects (bookmarks or frames or ...)
Dim oItem As Object &apos; An item in the oColl collection
Dim vNames As Variant &apos; Array of the available object names within a collection
Dim oStr As Object : Set oStr = ScriptForge.SF_String
Dim bMove As Boolean &apos; Return value of a cursor move
Dim i As Long
&apos; Reinitialize a new _TextRange object
Set oTextRange = New _TextRange
With oTextRange
Set .TargetObject = Nothing
.RangeString = &quot;&quot; : .Target = &quot;&quot; : .TargetName = &quot;&quot; : .TargetCell = &quot;&quot;
.Offset = 0 : .StartPoint = False : .EndPoint = False
Set .Anchor = Nothing : Set .Text = Nothing : Set .Cursor = Nothing
.Location = &quot;&quot;
End With
&apos; Identify the type of range with adequate regular expressions
With oTextRange
.RangeString = psTextRange
.StartPoint = ( Left(psTextRange, 1) = &quot;|&quot; )
.EndPoint = ( Right(psTextRange, 1) = &quot;|&quot; )
Select Case True
&apos; Parsing is done with regular expressions because names may really contain any character, including &quot;ç&quot;
&apos; Selection
Case oStr.IsRegex(psTextRange, &quot;\|?\s*(~|SEL|SELECTION)\s*\|?&quot;)
.Target = &quot;Selection&quot;
If _Component.CurrentSelection.ImplementationName = &quot;SwXTextRanges&quot; Then
lSelects = _Component.CurrentSelection.Count
If lSelects &gt; 0 Then
Set .Anchor = _Component.CurrentSelection.getByIndex(lSelects - 1)
If .StartPoint And Not .EndPoint Then
Set .Anchor = .Anchor.Start
ElseIf Not .StartPoint And .EndPoint Then
Set .Anchor = .Anchor.End
End If
Set .Text = .Anchor.Text
Set .Cursor = .Text.createTextCursorByRange(.Anchor)
End If
End If
If IsNull(.Cursor) Then .Location = _Component.CurrentSelection.ImplementationName
&apos; WORD, SENTENCE, PARAGRAPH
Case oStr.IsRegex(psTextRange, &quot;\|?\s*(PARAGRAPH|§|SENTENCE|WORD)\s*([+-][0-9]+)?\s*\|?&quot;)
If InStr(psTextRange, &quot;+&quot;) &gt; 0 Then
sSign = &quot;+&quot;
ElseIf InStr(psTextRange, &quot;-&quot;) &gt; 0 Then
sSign= &quot;-&quot;
End If
If Len(sSign) &gt; 0 Then sTarget = Split(psTextRange, sSign)(0) Else sTarget = psTextRange
If InStr(Iif(.StartPoint, 2, 1), sTarget, &quot;PARAGRAPH&quot;, 1) &gt; 0 Or InStr(Iif(.StartPoint, 2, 1), sTarget, &quot;§&quot;, 1) &gt; 0 Then
.Target = &quot;Paragraph&quot;
ElseIf InStr(Iif(.StartPoint, 2, 1), sTarget, &quot;SENTENCE&quot;, 1) &gt; 0 Then
.Target = &quot;Sentence&quot;
ElseIf InStr(Iif(.StartPoint, 2, 1), sTarget, &quot;WORD&quot;, 1) &gt; 0 Then
.Target = &quot;Word&quot;
End If
&apos; Identify the offset
If Len(sSign) = 0 Then
.Offset = 0
Else
sString = Split(psTextRange, sSign)(1)
If .EndPoint Then sString = Left(sString, Len(sString) - 1)
.Offset = CLng(sString) * Iif(sSign = &quot;+&quot;, 1, -1)
End If
&apos; Build the cursor pointing at the current selection
If _Component.CurrentSelection.ImplementationName = &quot;SwXTextRanges&quot; Then
lSelects = _Component.CurrentSelection.Count
If lSelects &gt; 0 Then
Set .Anchor = _Component.CurrentSelection.getByIndex(lSelects - 1)
Set .Text = .Anchor.Text
Set .Cursor = .Text.createTextCursorByRange(.Anchor)
End If
End If
If IsNull(.Cursor) Then
.Location = _Component.CurrentSelection.ImplementationName
Else
&apos; Move the cursor to the requested area
With .Cursor
Select Case oTextRange.Target
Case &quot;Word&quot;
bMove = .gotoStartOfWord(False)
If bMove Then
For i = 1 To Abs(oTextRange.Offset)
If sSign = &quot;+&quot; Then bMove = .gotoNextWord(False) Else bMove = .gotoPreviousWord(False)
If sSign = &quot;+&quot; Then
If Not bMove Then Exit For
If .isEndOfSentence() Then i = i - 1 &apos; Loop to do once more
Else
bMove = .goLeft(1, False) &apos; Additional trial to bypass some locks (tabs, list items, ... ?)
If Not bMove Then Exit For
End If
Next i
End If
&apos; Cursor is always at the start of a word, move it when necessary
If Not oTextRange.StartPoint And oTextRange.EndPoint Then
.gotoEndOfWord(False)
ElseIf oTextRange.StartPoint = oTextRange.EndPoint Then
.gotoEndOfWord(True)
End If
Case &quot;Sentence&quot;
bMove = .gotoStartOfSentence(False)
If bMove Then
For i = 1 To Abs(oTextRange.Offset)
If sSign = &quot;+&quot; Then bMove = .gotoNextSentence(False) Else bMove = .gotoPreviousSentence(False)
If sSign = &quot;+&quot; Then
If .isEndOfParagraph() Then bMove = .goRight(1, False)
Else
bMove = .goLeft(1, False) &apos; Additional trial to bypass some locks (tabs, list items, ... ?)
If .isStartOfParagraph() Then bMove = .goLeft(1, False)
End If
If Not bMove Then Exit For
Next i
End If
&apos; Cursor is always at the start of a sentence, move it when necessary
If Not oTextRange.StartPoint And oTextRange.EndPoint Then
.gotoEndOfSentence(False)
ElseIf oTextRange.StartPoint = oTextRange.EndPoint Then
.gotoEndOfSentence(True)
End If
Case &quot;Paragraph&quot;
bMove = .gotoStartOfParagraph(False)
If bMove Then
For i = 1 To Abs(oTextRange.Offset)
If sSign = &quot;+&quot; Then bMove = .gotoNextParagraph(False) Else bMove = .gotoPreviousParagraph(False)
If sSign = &quot;+&quot; Then
If .isEndOfParagraph() Then bMove = .goRight(1, False)
Else
bMove = .goLeft(1, False) &apos; Additional trial to bypass some locks (tabs, list items, ... ?)
If .isStartOfParagraph() Then bMove = .goLeft(1, False)
End If
If Not bMove Then Exit For
Next i
End If
&apos; Cursor is always at the start of a Paragraph, move it when necessary
If Not oTextRange.StartPoint And oTextRange.EndPoint Then
.gotoEndOfParagraph(False)
ElseIf oTextRange.StartPoint = oTextRange.EndPoint Then
.gotoEndOfParagraph(True)
End If
End Select
End With
End If
&apos; Bookmarks, Fields, Frames, Sections
Case oStr.IsRegex(psTextRange, &quot;\|?\s*(BOOKMARK|FIELD|FRAME|SECTION)!([\w\s]+|&apos;[^&apos;]+&apos;|&quot;&quot;[^&quot;&quot;]+&quot;&quot;)\|?&quot;)
sTarget = Split(psTextRange, &quot;!&quot;)(0)
If InStr(Iif(.StartPoint, 2, 1), sTarget, &quot;BOOKMARK&quot;, 1) &gt; 0 Then
.Target = &quot;Bookmark&quot;
ElseIf InStr(Iif(.StartPoint, 2, 1), sTarget, &quot;FIELD&quot;, 1) &gt; 0 Then
.Target = &quot;Field&quot;
ElseIf InStr(Iif(.StartPoint, 2, 1), sTarget, &quot;FRAME&quot;, 1) &gt; 0 Then
.Target = &quot;Frame&quot;
ElseIf InStr(Iif(.StartPoint, 2, 1), sTarget, &quot;SECTION&quot;, 1) &gt; 0 Then
.Target = &quot;Section&quot;
End If
&apos; Identify section or frame or bookmark or field by its name
sString = Split(psTextRange, &quot;!&quot;)(1)
If .EndPoint Then sString = Left(sString, Len(sString) - 1)
sLeft1 = Left(sString, 1)
If (sLeft1 = &quot;&quot;&quot;&quot; Or sLeft1 = &quot;&apos;&quot;) And Len(sString) &gt; 2 Then .TargetName = Trim(Mid(sString, 2, Len(sString) - 2)) Else .TargetName = Trim(sString)
Select Case .Target
Case &quot;Bookmark&quot; : Set oColl = _Component.getBookmarks()
Case &quot;Field&quot; : Set oColl = _Component.getTextFieldMasters()
.TargetName = &quot;com.sun.star.text.fieldmaster.User.&quot; &amp; .TargetName
If Not oColl.hasByName(.TargetName) Then .TargetName = Replace(.TargetName, &quot;.User.&quot;, &quot;.SetExpression.&quot;)
Case &quot;Frame&quot; : Set oColl = _Component.getTextFrames()
Case &quot;Section&quot; : Set oColl = _Component.getTextSections()
End Select
If .Target = &quot;Field&quot; Then vNames = Fields() Else vNames = oColl.getElementNames()
If Not ScriptForge.SF_Utils._Validate(.TargetName, .Target, V_STRING, vNames, True) Then GoTo Finally
Set .TargetObject = oColl.getByName(.TargetName)
&apos; Set text, anchor and cursor: order varies depending on target
Select Case .Target
Case &quot;Bookmark&quot;, &quot;Field&quot;, &quot;Section&quot;
If .Target = &quot;Field&quot; Then Set .Anchor = .TargetObject.DependentTextFields(0).Anchor Else Set .Anchor = .TargetObject.Anchor
If .StartPoint And Not .EndPoint Then
Set .Anchor = .Anchor.Start
ElseIf Not .StartPoint And .EndPoint Then
Set .Anchor = .Anchor.End
End If
Set .Text = .Anchor.Text
Set .Cursor = .Text.createTextCursorByRange(.Anchor)
Case &quot;Frame&quot;
Set .Text = .TargetObject.Start.Text
Set .Anchor = .Text.Anchor
Set .Cursor = .Text.createTextCursor()
If .StartPoint And Not .EndPoint Then
.Cursor.gotoStart(False)
ElseIf Not .StartPoint And .EndPoint Then
.Cursor.gotoEnd(False)
Else
.Cursor.gotoStart(False)
.Cursor.gotoEnd(True)
End If
Case Else
End Select
&apos; Body
Case oStr.IsRegex(psTextRange, &quot;\|0\s*?BODY\s*\|?&quot;)
Set .Text = _Component.Text
Set .Anchor = .Text.Start
Set .Cursor = .Text.createTextCursor()
If .StartPoint And Not .EndPoint Then
.Cursor.gotoStart(False)
ElseIf Not .StartPoint And .EndPoint Then
Set .Anchor = .Text.End
.Cursor.gotoEnd(False)
Else
.Cursor.gotoStart(False)
.Cursor.gotoEnd(True)
End If
&apos; Table cell
Case oStr.IsRegex(psTextRange, &quot;\|?\s*TABLE!([\w\s]+|&apos;[^&apos;]+&apos;|&quot;&quot;[^&quot;&quot;]+&quot;&quot;)![\s]*[A-Za-z]+[1-9][0-9]*\s*\|?&quot;)
.Target = &quot;TableCell&quot;
&apos; Identify table by its name
sString = Split(psTextRange, &quot;!&quot;)(1)
sLeft1 = Left(sString, 1)
If (sLeft1 = &quot;&quot;&quot;&quot; Or sLeft1 = &quot;&apos;&quot;) And Len(sString) &gt; 2 Then .TargetName = Trim(Mid(sString, 2, Len(sString) - 2)) Else .TargetName = Trim(sString)
Set oColl = _Component.getTextTables()
vNames = oColl.getElementNames()
If Not ScriptForge.SF_Utils._Validate(.TargetName, .Target, V_STRING, vNames, True) Then GoTo Finally
Set oItem = oColl.getByName(.TargetName)
.TargetCell = Split(psTextRange, &quot;!&quot;)(2)
&apos; Set text, anchor and cursor
Set .TargetObject = oItem.getCellByName(.TargetCell)
If IsNull(.TargetObject) Then GoTo CatchRange &apos; The given range is out of the scope of the table
Set .Text = .TargetObject.Text
Set .Anchor = .Text.Start
Set .Cursor = .Text.createTextCursor()
If .StartPoint And Not .EndPoint Then
.Cursor.gotoStart(False)
ElseIf Not .StartPoint And .EndPoint Then
Set .Anchor = .Text.End
.Cursor.gotoEnd(False)
Else
.Cursor.gotoStart(False)
.Cursor.gotoEnd(True)
End If
Case Else
GoTo CatchRange
End Select
&apos; Determine Location if not yet done
If .Location = &quot;&quot; And Not IsNull(.Text) Then
Select Case .Text.ImplementationName
Case &quot;SwXBodyText&quot; : .Location = &quot;Body&quot;
Case &quot;SwXTextFrame&quot; : .Location = &quot;Frame&quot;
Case &quot;SwXCell&quot; : .Location = &quot;Cell&quot;
Case &quot;SwXHeadFootText&quot; : .Location = &quot;Header/Footer&quot;
Case &quot;SwXFootnote&quot; : .Location = &quot;Footnote/Endnote&quot;
Case &quot;SwXShape&quot; : .Location = &quot;Shape&quot;
Case Else : .Location = .Text.ImplementationName
End Select
End If
End With
Finally:
Set _ParseRange = oTextRange
Exit Function
CatchError:
ScriptForge.SF_Exception.Clear()
CatchRange:
ScriptForge.SF_Exception.RaiseFatal(WRITERRANGEERROR, &quot;TextRange&quot;, psTextRange _
, &quot;Document&quot;, [_Super]._FileIdent())
GoTo Finally
End Function &apos; SFDocuments.SF_Writer._ParseRange
REM -----------------------------------------------------------------------------
Private Function _PropertyGet(Optional ByVal psProperty As String _
, Optional ByVal pvArg As Variant _
) As Variant
&apos;&apos;&apos; Return the value of the named property
&apos;&apos;&apos; Args:
&apos;&apos;&apos; psProperty: the name of the property
Dim oFieldMasters As Object &apos; SwXTextFieldMasters
Dim vMasters As Variant &apos; Array of SwXTextFieldMasters
Dim oMaster As Object &apos; A single SwXTextFieldMasters
Dim sField As String &apos; A text field full name
Dim vFieldNames As Variant &apos; Array of field names as strings
Dim cstThisSub As String
Const cstSubArgs = &quot;&quot;
_PropertyGet = False
cstThisSub = &quot;SFDocuments.Writer.get&quot; &amp; psProperty
ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
If Not _IsStillAlive() Then GoTo Finally
Select Case UCase(psProperty)
Case UCase(&quot;Bookmarks&quot;)
_PropertyGet = _Component.getBookmarks().getElementNames()
Case UCase(&quot;CurrentSelection&quot;)
_PropertyGet = _Component.CurrentSelection
Case UCase(&quot;Fields&quot;)
vFieldNames = Array()
Set oFieldMasters = _Component.getTextFieldMasters()
vMasters = oFieldMasters.getElementNames()
For Each sField In vMasters
If ScriptForge.SF_String.StartsWith(sField, &quot;com.sun.star.text.fieldmaster.User&quot;) Then
Set oMaster = oFieldMasters.getByName(sField)
vFieldNames = ScriptForge.SF_Array.InsertSorted(vFieldNames, oMaster.Name, CaseSensitive := True)
ElseIf ScriptForge.SF_String.StartsWith(sField, &quot;com.sun.star.text.fieldmaster.SetExpression&quot;) Then
Set oMaster = oFieldMasters.getByName(sField)
If oMaster.SubType = com.sun.star.text.SetVariableType.VAR Then
vFieldNames = ScriptForge.SF_Array.InsertSorted(vFieldNames, oMaster.Name, CaseSensitive := True)
End If
End If
Next sField
_PropertyGet = vFieldNames
Case UCase(&quot;Frames&quot;)
_PropertyGet = _Component.getTextFrames().getElementNames()
Case Else
_PropertyGet = Null
End Select
Finally:
ScriptForge.SF_Utils._ExitFunction(cstThisSub)
Exit Function
End Function &apos; SFDocuments.SF_Writer._PropertyGet
REM -----------------------------------------------------------------------------
Private Function _Repr() As String
&apos;&apos;&apos; Convert the SF_Writer instance to a readable string, typically for debugging purposes (DebugPrint ...)
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Return:
&apos;&apos;&apos; &quot;[DOCUMENT]: Type/File&quot;
_Repr = &quot;[Writer]: &quot; &amp; [_Super]._FileIdent()
End Function &apos; SFDocuments.SF_Writer._Repr
REM ============================================ END OF SFDOCUMENTS.SF_WRITER
</script:module>