This commit is contained in:
Jane
2024-07-16 15:55:31 +08:00
parent 8f4ec86367
commit 29bc31ade5
12411 changed files with 8139339 additions and 0 deletions

View File

@@ -0,0 +1,814 @@
<?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_Chart" 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_Chart
&apos;&apos;&apos; ========
&apos;&apos;&apos;
&apos;&apos;&apos; The SF_Chart module is focused on the description of chart documents
&apos;&apos;&apos; stored in Calc sheets.
&apos;&apos;&apos; With this service, many chart types and chart characteristics available
&apos;&apos;&apos; in the user interface can be read or modified.
&apos;&apos;&apos;
&apos;&apos;&apos; Definitions
&apos;&apos;&apos; Charts have 2 distinct names:
&apos;&apos;&apos; - an internal name, given by the LibreOffice application
&apos;&apos;&apos; - an optional user-defined name
&apos;&apos;&apos; In the scope of the ScriptForge libraries, the chart name is the name given by the user.
&apos;&apos;&apos; Only when there is no user name, the internal name may be used instead.
&apos;&apos;&apos;
&apos;&apos;&apos; Service invocation from the &quot;Calc&quot; service
&apos;&apos;&apos; Either make a new chart
&apos;&apos;&apos; calc.CreateChart(ChartName, SheetName, &quot;SheetX.A1:C8&quot;)
&apos;&apos;&apos; or select an existing one
&apos;&apos;&apos; calc.Charts(SheetName, ChartName)
&apos;&apos;&apos;
&apos;&apos;&apos; Detailed user documentation:
&apos;&apos;&apos; https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03/sf_chart.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 CHARTEXPORTERROR = &quot;CHARTEXPORTERROR&quot;
REM ============================================================= PRIVATE MEMBERS
Private [Me] As Object
Private [_Parent] As Object &apos; Parent Calc document
Private ObjectType As String &apos; Must be CHART
Private ServiceName As String
&apos; Chart description
Private _SheetName As String &apos; Name of the Calc sheet containing the chart
Private _DrawIndex As Long &apos; Index of the chart in the sheet&apos;s draw page
Private _ChartName As String &apos; User name
Private _PersistentName As String &apos; Internal name
Private _Shape As Object &apos; com.sun.star.drawing.XShape
Private _Chart As Object &apos; com.sun.star.table.XTableChart
Private _ChartObject As Object &apos; com.sun.star.lang.XComponent - ScChartObj
Private _Diagram As Object &apos; com.sun.star.chart.XDiagram
REM ============================================================ MODULE CONSTANTS
REM ====================================================== CONSTRUCTOR/DESTRUCTOR
REM -----------------------------------------------------------------------------
Private Sub Class_Initialize()
Set [Me] = Nothing
Set [_Parent] = Nothing
ObjectType = &quot;CHART&quot;
ServiceName = &quot;SFDocuments.Chart&quot;
_SheetName = &quot;&quot;
_DrawIndex = -1
_ChartName = &quot;&quot;
_PersistentName = &quot;&quot;
Set _Shape = Nothing
Set _Chart = Nothing
Set _ChartObject = Nothing
Set _Diagram = Nothing
End Sub &apos; SFDocuments.SF_Chart Constructor
REM -----------------------------------------------------------------------------
Private Sub Class_Terminate()
Call Class_Initialize()
End Sub &apos; SFDocuments.SF_Chart Destructor
REM -----------------------------------------------------------------------------
Public Function Dispose() As Variant
Call Class_Terminate()
Set Dispose = Nothing
End Function &apos; SFDocuments.SF_Chart Explicit Destructor
REM ================================================================== PROPERTIES
REM -----------------------------------------------------------------------------
Property Get ChartType() As Variant
&apos;&apos;&apos; The ChartType property specifies the type of chart as a string among next values:
&apos;&apos;&apos; Pie, Bar, Donut, Column, Area, Line, XY, Bubble, Net
ChartType = _PropertyGet(&quot;ChartType&quot;)
End Property &apos; SFDocuments.SF_Chart.ChartType (get)
REM -----------------------------------------------------------------------------
Property Let ChartType(Optional ByVal pvChartType As Variant)
&apos;&apos;&apos; Set the updatable property ChartType
_PropertySet(&quot;ChartType&quot;, pvChartType)
End Property &apos; SFDocuments.SF_Chart.ChartType (let)
REM -----------------------------------------------------------------------------
Property Get Deep() As Variant
&apos;&apos;&apos; If True, determines that in a three-dimensional bar chart the bars of each series are arranged behind each other in the z-direction.
&apos;&apos;&apos; If False the arrangement of bars is like in two-dimensional bar charts.
&apos;&apos;&apos; Bar and Column chart types only
Deep = _PropertyGet(&quot;Deep&quot;)
End Property &apos; SFDocuments.SF_Chart.Deep (get)
REM -----------------------------------------------------------------------------
Property Let Deep(Optional ByVal pvDeep As Variant)
&apos;&apos;&apos; Set the updatable property Deep
_PropertySet(&quot;Deep&quot;, pvDeep)
End Property &apos; SFDocuments.SF_Chart.Deep (let)
REM -----------------------------------------------------------------------------
Property Get Dim3D() As Variant
&apos;&apos;&apos; The Dim3D property specifies if the chart is displayed with 3D elements
&apos;&apos;&apos; String or Boolean
&apos;&apos;&apos; When String, must be 1 of next values: Bar, Cylinder, Cone or Pyramid
&apos;&apos;&apos; When Boolean True, Bar is assumed; when False, no 3D to be applied
Dim3D = _PropertyGet(&quot;Dim3D&quot;)
End Property &apos; SFDocuments.SF_Chart.Dim3D (get)
REM -----------------------------------------------------------------------------
Property Let Dim3D(Optional ByVal pvDim3D As Variant)
&apos;&apos;&apos; Set the updatable property Dim3D
_PropertySet(&quot;Dim3D&quot;, pvDim3D)
End Property &apos; SFDocuments.SF_Chart.Dim3D (let)
REM -----------------------------------------------------------------------------
Property Get Exploded() As Variant
&apos;&apos;&apos; the offset by which pie segments in a PieDiagram (pie or donut) are dragged outside from the center.
&apos;&apos;&apos; This value is given in percent of the radius.
Exploded = _PropertyGet(&quot;Exploded&quot;)
End Property &apos; SFDocuments.SF_Chart.Exploded (get)_ChartObject
REM -----------------------------------------------------------------------------
Property Let Exploded(Optional ByVal pvExploded As Variant)
&apos;&apos;&apos; Set the updatable property Exploded
_PropertySet(&quot;Exploded&quot;, pvExploded)
End Property &apos; SFDocuments.SF_Chart.Exploded (let)
REM -----------------------------------------------------------------------------
Property Get Filled() As Variant
&apos;&apos;&apos; When True, the Net diagram is said of FilledNet type
&apos;&apos;&apos; Net chart type only
Filled = _PropertyGet(&quot;Filled&quot;)
End Property &apos; SFDocuments.SF_Chart.Filled (get)
REM -----------------------------------------------------------------------------
Property Let Filled(Optional ByVal pvFilled As Variant)
&apos;&apos;&apos; Set the updatable property Filled
_PropertySet(&quot;Filled&quot;, pvFilled)
End Property &apos; SFDocuments.SF_Chart.Filled (let)
REM -----------------------------------------------------------------------------
Property Get Legend() As Variant
&apos;&apos;&apos; Specifies if the chart has a legend
Legend = _PropertyGet(&quot;Legend&quot;)
End Property &apos; SFDocuments.SF_Chart.Legend (get)
REM -----------------------------------------------------------------------------
Property Let Legend(Optional ByVal pvLegend As Variant)
&apos;&apos;&apos; Set the updatable property Legend
_PropertySet(&quot;Legend&quot;, pvLegend)
End Property &apos; SFDocuments.SF_Chart.Legend (let)
REM -----------------------------------------------------------------------------
Property Get Percent() As Variant
&apos;&apos;&apos; When True, the series of the diagram are stacked and each category sums up to 100%.
&apos;&apos;&apos; Area, Bar, Bubble, Column and Net chart types only_ChartObject
Percent = _PropertyGet(&quot;Percent&quot;)
End Property &apos; SFDocuments.SF_Chart.Percent (get)
REM -----------------------------------------------------------------------------
Property Let Percent(Optional ByVal pvPercent As Variant)
&apos;&apos;&apos; Set the updatable property Percent
_PropertySet(&quot;Percent&quot;, pvPercent)
End Property &apos; SFDocuments.SF_Chart.Percent (let)
REM -----------------------------------------------------------------------------
Property Get Stacked() As Variant
&apos;&apos;&apos; When True, the series of the diagram are stacked.
&apos;&apos;&apos; Area, Bar, Bubble, Column and Net chart types only
Stacked = _PropertyGet(&quot;Stacked&quot;)
End Property &apos; SFDocuments.SF_Chart.Stacked (get)
REM -----------------------------------------------------------------------------
Property Let Stacked(Optional ByVal pvStacked As Variant)
&apos;&apos;&apos; Set the updatable property Stacked
_PropertySet(&quot;Stacked&quot;, pvStacked)
End Property &apos; SFDocuments.SF_Chart.Stacked (let)
REM -----------------------------------------------------------------------------
Property Get Title() As Variant
&apos;&apos;&apos; Specifies the main title of the chart
Title = _PropertyGet(&quot;Title&quot;)
End Property &apos; SFDocuments.SF_Chart.Title (get)
REM -----------------------------------------------------------------------------
Property Let Title(Optional ByVal pvTitle As Variant)
&apos;&apos;&apos; Set the updatable property Title
_PropertySet(&quot;Title&quot;, pvTitle)
End Property &apos; SFDocuments.SF_Chart.Title (let)
REM -----------------------------------------------------------------------------
Property Get XTitle() As Variant
&apos;&apos;&apos; Specifies the main XTitle of the chart
XTitle = _PropertyGet(&quot;XTitle&quot;)
End Property &apos; SFDocuments.SF_Chart.XTitle (get)
REM -----------------------------------------------------------------------------
Property Let XTitle(Optional ByVal pvXTitle As Variant)
&apos;&apos;&apos; Set the updatable property XTitle
_PropertySet(&quot;XTitle&quot;, pvXTitle)
End Property &apos; SFDocuments.SF_Chart.XTitle (let)
REM -----------------------------------------------------------------------------
Property Get YTitle() As Variant
&apos;&apos;&apos; Specifies the main YTitle of the chart
YTitle = _PropertyGet(&quot;YTitle&quot;)
End Property &apos; SFDocuments.SF_Chart.YTitle (get)
REM -----------------------------------------------------------------------------
Property Let YTitle(Optional ByVal pvYTitle As Variant)
&apos;&apos;&apos; Set the updatable property YTitle
_PropertySet(&quot;YTitle&quot;, pvYTitle)
End Property &apos; SFDocuments.SF_Chart.YTitle (let)
REM -----------------------------------------------------------------------------
Property Get XChartObj() As Variant
&apos;&apos;&apos; com.sun.star.lang.XComponent - ScChartObj
ChartType = _PropertyGet(&quot;XChartObj&quot;)
End Property &apos; SFDocuments.SF_Chart.XChartObj (get)
REM -----------------------------------------------------------------------------
Property Get XDiagram() As Variant
&apos;&apos;&apos; com.sun.star.chart.XDiagram
ChartType = _PropertyGet(&quot;XDiagram&quot;)
End Property &apos; SFDocuments.SF_Chart.XDiagram (get)
REM -----------------------------------------------------------------------------
Property Get XShape() As Variant
&apos;&apos;&apos; com.sun.star.drawing.XShape
ChartType = _PropertyGet(&quot;XShape&quot;)
End Property &apos; SFDocuments.SF_Chart.XShape (get)
REM -----------------------------------------------------------------------------
Property Get XTableChart() As Variant
&apos;&apos;&apos; com.sun.star.table.XTableChart
ChartType = _PropertyGet(&quot;XTableChart&quot;)
End Property &apos; SFDocuments.SF_Chart.XTableChart (get)
REM ===================================================================== METHODS
REM -----------------------------------------------------------------------------
Public Function ExportToFile(Optional ByVal FileName As Variant _
, Optional ByVal ImageType As Variant _
, Optional ByVal Overwrite As Variant _
) As Boolean
&apos;&apos;&apos; Store the chart as an image to the given file location
&apos;&apos;&apos; Args:
&apos;&apos;&apos; FileName: Identifies the file where to save. It must follow the SF_FileSystem.FileNaming notation
&apos;&apos;&apos; ImageType: the name of the targeted image type
&apos;&apos;&apos; Allowed values: gif, jpeg, png (default), svg and tiff
&apos;&apos;&apos; Overwrite: True if the destination file may be overwritten (default = False)
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; False if the document could not be saved
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; CHARTEXPORTERROR The destination has its readonly attribute set or overwriting rejected
&apos;&apos;&apos; Examples:
&apos;&apos;&apos; oChart.ExportToFile(&quot;C:\Me\Chart2.gif&quot;, ImageType := &quot;gif&quot;, Overwrite := True)
Dim bSaved As Boolean &apos; return value
Dim oSfa As Object &apos; com.sun.star.ucb.SimpleFileAccess
Dim sFile As String &apos; Alias of FileName
Dim vStoreArguments As Variant &apos; Array of com.sun.star.beans.PropertyValue
Dim FSO As Object &apos; SF_FileSystem
Dim oExport As Object &apos; com.sun.star.drawing.GraphicExportFilter
Dim vImageTypes As Variant &apos; Array of permitted image types
Dim vMimeTypes As Variant &apos; Array of corresponding mime types in the same order as vImageTypes
Const cstImageTypes = &quot;gif,jpeg,png,svg,tiff&quot;
Const cstMimeTypes = &quot;image/gif,image/jpeg,image/png,image/svg+xml,image/tiff&quot;
Const cstThisSub = &quot;SFDocuments.Chart.ExportToFile&quot;
Const cstSubArgs = &quot;FileName, [ImageType=&quot;&quot;png&quot;&quot;|&quot;&quot;gif&quot;&quot;|&quot;&quot;jpeg&quot;&quot;|&quot;&quot;svg&quot;&quot;|&quot;&quot;tiff&quot;&quot;], [Overwrite=False]&quot;
If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo CatchError
bSaved = False
Check:
If IsMissing(ImageType) Or IsEmpty(ImageType) Then ImageType = &quot;png&quot;
If IsMissing(Overwrite) Or IsEmpty(Overwrite) Then Overwrite = False
vImageTypes = Split(cstImageTypes, &quot;,&quot;)
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Parent]._IsStillAlive() Then GoTo Finally
If Not ScriptForge.SF_Utils._ValidateFile(FileName, &quot;FileName&quot;) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(ImageType, &quot;ImageType&quot;, V_STRING, vImageTypes) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(Overwrite, &quot;Overwrite&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
End If
&apos; Check destination file overwriting
Set FSO = CreateScriptService(&quot;FileSystem&quot;)
sFile = FSO._ConvertToUrl(FileName)
If FSO.FileExists(FileName) Then
If Overwrite = False Then GoTo CatchError
Set oSfa = ScriptForge.SF_Utils._GetUNOService(&quot;FileAccess&quot;)
If oSfa.isReadonly(sFile) Then GoTo CatchError
End If
Try:
&apos; Setup arguments
vMimeTypes = Split(cstMimeTypes, &quot;,&quot;)
vStoreArguments = Array( _
ScriptForge.SF_Utils._MakePropertyValue(&quot;URL&quot;, sFile) _
, ScriptForge.SF_Utils._MakePropertyValue(&quot;MediaType&quot; _
, vMimeTypes(ScriptForge.SF_Array.IndexOf(vImageTypes, ImageType, CaseSensitive := False))) _
)
&apos; Export with the com.sun.star.drawing.GraphicExportFilter UNO service
Set oExport = ScriptForge.SF_Utils._GetUNOService(&quot;GraphicExportFilter&quot;)
With oExport
.setSourceDocument(_Shape)
.filter(vStoreArguments)
End With
bSaved = True
Finally:
ExportToFile = bSaved
ScriptForge.SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
CatchError:
ScriptForge.SF_Exception.RaiseFatal(CHARTEXPORTERROR, &quot;FileName&quot;, FileName, &quot;Overwrite&quot;, Overwrite)
GoTo Finally
End Function &apos; SFDocuments.SF_Chart.ExportToFile
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; If the property does not exist, returns Null
&apos;&apos;&apos; Exceptions:
&apos;&apos;&apos; ARGUMENTERROR The property does not exist
Const cstThisSub = &quot;SFDocuments.Chart.GetProperty&quot;
Const cstSubArgs = &quot;&quot;
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
GetProperty = Null
Check:
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
End If
Try:
GetProperty = _PropertyGet(PropertyName)
Finally:
SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
End Function &apos; SFDocuments.SF_Chart.GetProperty
REM -----------------------------------------------------------------------------
Public Function Methods() As Variant
&apos;&apos;&apos; Return the list of public methods of the Chart service as an array
Methods = Array( _
&quot;ExportToFile&quot; _
, &quot;Resize&quot; _
)
End Function &apos; SFDocuments.SF_Chart.Methods
REM -----------------------------------------------------------------------------
Public Function Properties() As Variant
&apos;&apos;&apos; Return the list or properties of the Chart class as an array
Properties = Array( _
&quot;ChartType&quot; _
, &quot;Deep&quot; _
, &quot;Dim3D&quot; _
, &quot;Exploded&quot; _
, &quot;Filled&quot; _
, &quot;Legend&quot; _
, &quot;Percent&quot; _
, &quot;Stacked&quot; _
, &quot;Title&quot; _
, &quot;XChartObj&quot; _
, &quot;XDiagram&quot; _
, &quot;XShape&quot; _
, &quot;XTableChart&quot; _
, &quot;XTitle&quot; _
, &quot;YTitle&quot; _
)
End Function &apos; SFDocuments.SF_Chart.Properties
REM -----------------------------------------------------------------------------
Public Function Resize(Optional ByVal XPos As Variant _
, Optional ByVal YPos As Variant _
, Optional ByVal Width As Variant _
, Optional ByVal Height As Variant _
) As Boolean
&apos;&apos;&apos; Move the topleft corner of a chart to new coordinates and/or modify its dimensions
&apos;&apos;&apos; All distances are expressed in 1/100th mm
&apos;&apos;&apos; Args:
&apos;&apos;&apos; XPos : the vertical distance from the topleft corner
&apos;&apos;&apos; YPos : the horizontal distance from the topleft corner
&apos;&apos;&apos; Width : the horizontal width of the shape containing the chart
&apos;&apos;&apos; Height : the vertical height of the shape containing the chart
&apos;&apos;&apos; Negative or missing arguments are left unchanged
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; True when successful
&apos;&apos;&apos; Examples:
&apos;&apos;&apos; oChart.Resize(1000, 2000, Height := 6000) &apos; Width is not changed
Dim bResize As Boolean &apos; Return value
Dim oPosition As Object &apos; com.sun.star.awt.Point
Dim oSize As Object &apos; com.sun.star.awt.Size
Const cstThisSub = &quot;SFDocuments.Chart.Resize&quot;
Const cstSubArgs = &quot;[XPos], [YPos], [Width], [Height]&quot;
If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
bResize = False
Check:
If IsMissing(XPos) Or IsEmpty(XPos) Then XPos = -1
If IsMissing(YPos) Or IsEmpty(YPos) Then YPos = -1
If IsMissing(Height) Or IsEmpty(Height) Then Height = -1
If IsMissing(Width) Or IsEmpty(Width) Then Width = -1
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not [_Parent]._IsStillAlive() Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(XPos, &quot;XPos&quot;, ScriptForge.V_NUMERIC) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(YPos, &quot;YPos&quot;, ScriptForge.V_NUMERIC) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(Width, &quot;Width&quot;, ScriptForge.V_NUMERIC) Then GoTo Finally
If Not ScriptForge.SF_Utils._Validate(Height, &quot;Height&quot;, ScriptForge.V_NUMERIC) Then GoTo Finally
End If
Try:
With _Shape
&apos; Get the current values
Set oPosition = .Position
Set oSize = .Size
&apos; Modify relevant elements
If XPos &gt;= 0 Then oPosition.X = CLng(XPos)
If YPos &gt;= 0 Then oPosition.Y = CLng(YPos)
If Width &gt; 0 Then oSize.Width = CLng(Width)
If Height &gt; 0 Then oSize.Height = CLng(Height)
&apos; Rewrite
.setPosition(oPosition)
.setSize(oSize)
End With
bResize = True
Finally:
Resize = bResize
ScriptForge.SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
End Function &apos; SF_Documents.SF_Chart.Resize
REM -----------------------------------------------------------------------------
Public Function SetProperty(Optional ByVal PropertyName As Variant _
, Optional ByRef Value As Variant _
) As Boolean
&apos;&apos;&apos; Set a new value to the given property
&apos;&apos;&apos; Args:
&apos;&apos;&apos; PropertyName: the name of the property as a string
&apos;&apos;&apos; Value: its new value
&apos;&apos;&apos; Exceptions
&apos;&apos;&apos; ARGUMENTERROR The property does not exist
Const cstThisSub = &quot;SFDocuments.Chart.SetProperty&quot;
Const cstSubArgs = &quot;PropertyName, Value&quot;
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
SetProperty = False
Check:
If 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:
SetProperty = _PropertySet(PropertyName, Value)
Finally:
SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
GoTo Finally
End Function &apos; SFDocuments.SF_Chart.SetProperty
REM =========================================================== PRIVATE FUNCTIONS
REM -----------------------------------------------------------------------------
Private Function _PropertyGet(Optional ByVal psProperty As String) 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
Static oSession As Object &apos; Alias of SF_Session
Dim vData As Variant &apos; Data points array of values
Dim cstThisSub As String
Const cstSubArgs = &quot;&quot;
cstThisSub = &quot;SFDocuments.Chart.get&quot; &amp; psProperty
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
If Not [_Parent]._IsStillAlive() Then GoTo Finally
If IsNull(oSession) Then Set oSession = ScriptForge.SF_Services.CreateScriptService(&quot;Session&quot;)
Select Case UCase(psProperty)
Case UCase(&quot;ChartType&quot;)
With _Diagram
Select Case .DiagramType
Case &quot;com.sun.star.chart.BarDiagram&quot;
If .Vertical Then _PropertyGet = &quot;Bar&quot; Else _PropertyGet = &quot;Column&quot;
Case &quot;com.sun.star.chart.PieDiagram&quot;
_PropertyGet = &quot;Pie&quot;
Case &quot;com.sun.star.chart.DonutDiagram&quot;
_PropertyGet = &quot;Donut&quot;
Case &quot;com.sun.star.chart.AreaDiagram&quot;
_PropertyGet = &quot;Area&quot;
Case &quot;com.sun.star.chart.LineDiagram&quot;
_PropertyGet = &quot;Line&quot;
Case &quot;com.sun.star.chart.XYDiagram&quot;
_PropertyGet = &quot;XY&quot;
Case &quot;com.sun.star.chart.BubbleDiagram&quot;
_PropertyGet = &quot;Bubble&quot;
Case &quot;com.sun.star.chart.NetDiagram&quot;, &quot;com.sun.star.chart.FilledNetDiagram&quot;
_PropertyGet = &quot;Net&quot;
Case Else
_PropertyGet = &quot;&quot;
End Select
End With
Case UCase(&quot;Deep&quot;)
If oSession.HasUnoProperty(_Diagram, &quot;Deep&quot;) Then _PropertyGet = _Diagram.Deep Else _PropertyGet = False
Case UCase(&quot;Dim3D&quot;)
If oSession.HasUnoProperty(_Diagram, &quot;Dim3D&quot;) Then
If _Diagram.Dim3D Then
If oSession.HasUnoProperty(_Diagram, &quot;SolidType&quot;) Then
Select Case _Diagram.SolidType
Case com.sun.star.chart.ChartSolidType.RECTANGULAR_SOLID : _PropertyGet = &quot;Bar&quot;
Case com.sun.star.chart.ChartSolidType.CYLINDER : _PropertyGet = &quot;Cylinder&quot;
Case com.sun.star.chart.ChartSolidType.CONE : _PropertyGet = &quot;Cone&quot;
Case com.sun.star.chart.ChartSolidType.PYRAMID : _PropertyGet = &quot;Pyramid&quot;
End Select
Else
_PropertyGet = _Diagram.Dim3D
End If
Else
_PropertyGet = False
End If
Else
_PropertyGet = False
End If
Case UCase(&quot;Exploded&quot;)
If oSession.HasUnoProperty(_ChartObject, &quot;Data&quot;) Then
&apos; All data points are presumed exploded with the same coefficient. Determine the (0, 0)th
With _ChartObject
vData = .Data.Data
_PropertyGet = 0
If IsArray(vData) Then
If UBound(vData) &gt;= 0 Then
If IsArray(vData(0)) Then
If UBound(vData(0)) &gt;= 0 Then _PropertyGet = _Diagram.getDataPointProperties(0, 0).SegmentOffset
End If
End If
End If
End With
End If
Case UCase(&quot;Filled&quot;)
_PropertyGet = ( _Diagram.DiagramType = &quot;com.sun.star.chart.FilledNetDiagram&quot; )
Case UCase(&quot;Legend&quot;)
If oSession.HasUnoProperty(_ChartObject, &quot;HasLegend&quot;) Then _PropertyGet = _ChartObject.HasLegend Else _PropertyGet = False
Case UCase(&quot;Percent&quot;)
If oSession.HasUnoProperty(_Diagram, &quot;Percent&quot;) Then _PropertyGet = _Diagram.Percent Else _PropertyGet = False
Case UCase(&quot;Stacked&quot;)
If oSession.HasUnoProperty(_Diagram, &quot;Stacked&quot;) Then _PropertyGet = _Diagram.Stacked Else _PropertyGet = False
Case UCase(&quot;Title&quot;)
If oSession.HasUnoProperty(_ChartObject, &quot;HasMainTitle&quot;) Then
If _ChartObject.HasMainTitle Then _PropertyGet = _ChartObject.Title.String Else _PropertyGet = &quot;&quot;
End If
Case UCase(&quot;XTitle&quot;)
If oSession.HasUnoProperty(_Diagram, &quot;HasXAxisTitle&quot;) Then
If _Diagram.HasXAxisTitle Then _PropertyGet = _Diagram.XAxisTitle.String Else _PropertyGet = &quot;&quot;
End If
Case UCase(&quot;YTitle&quot;)
If oSession.HasUnoProperty(_Diagram, &quot;HasYAxisTitle&quot;) Then
If _Diagram.HasYAxisTitle Then _PropertyGet = _Diagram.YAxisTitle.String Else _PropertyGet = &quot;&quot;
End If
Case UCase(&quot;XChartObj&quot;)
Set _PropertyGet = _ChartObject
Case UCase(&quot;XDiagram&quot;)
Set _PropertyGet = _Diagram
Case UCase(&quot;XShape&quot;)
Set _PropertyGet = _Shape
Case UCase(&quot;XTableChart&quot;)
Set _PropertyGet = _Chart
Case Else
_PropertyGet = Null
End Select
Finally:
SF_Utils._ExitFunction(cstThisSub)
Exit Function
End Function &apos; SFDocuments.SF_Chart._PropertyGet
REM -----------------------------------------------------------------------------
Private Function _PropertySet(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
Dim bSet As Boolean &apos; Return value
Static oSession As Object &apos; Alias of SF_Session
Dim sChartType As String &apos; Diagram type
Dim bDim3D As Boolean &apos; Alias of Dim3D property of diagram
Dim bVertical As Boolean &apos; When True, chart type is a bar, not a column
Dim vData As Variant &apos; Data points array of values
Dim i As Long, j As Long
Const cstChart = &quot;com.sun.star.chart.&quot;
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.Chart.set&quot; &amp; psProperty
ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
If Not [_Parent]._IsStillAlive() Then GoTo Catch
bSet = True
If IsNull(oSession) Then Set oSession = ScriptForge.SF_Services.CreateScriptService(&quot;Session&quot;)
Select Case UCase(psProperty)
Case UCase(&quot;ChartType&quot;)
If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;ChartType&quot;, V_STRING _
, Array(&quot;Bar&quot;, &quot;Column&quot;, &quot;Pie&quot;, &quot;Donut&quot;, &quot;Area&quot;, &quot;Line&quot;, &quot;XY&quot;, &quot;Bubble&quot;, &quot;Net&quot;) _
) Then GoTo Finally
With _Diagram
&apos; Specify the targeted chart type
Select Case UCase(pvValue)
Case &quot;BAR&quot;, &quot;COLUMN&quot; : sChartType = cstChart &amp; &quot;BarDiagram&quot;
Case &quot;PIE&quot; : sChartType = cstChart &amp; &quot;PieDiagram&quot;
Case &quot;DONUT&quot; : sChartType = cstChart &amp; &quot;DonutDiagram&quot;
Case &quot;AREA&quot; : sChartType = cstChart &amp; &quot;AreaDiagram&quot;
Case &quot;LINE&quot; : sChartType = cstChart &amp; &quot;LineDiagram&quot;
Case &quot;XY&quot; : sChartType = cstChart &amp; &quot;XYDiagram&quot;
Case &quot;BUBBLE&quot; : sChartType = cstChart &amp; &quot;BubbleDiagram&quot;
Case &quot;NET&quot; : sChartType = cstChart &amp; &quot;NetDiagram&quot;
End Select
&apos; If there is no change, do nothing
If sChartType &lt;&gt; .DiagramType Then
&apos; Some combinations old type =&gt; new type require the cancellation of 3D graphs
bDim3D = .Dim3D
.Dim3D = False
_ChartObject.createInstance(sChartType)
Set _Diagram = _ChartObject.Diagram
.Dim3D = bDim3D
End If
If UCase(pvValue) = &quot;BAR&quot; Or UCase(pvValue) = &quot;COLUMN&quot; Then .Vertical = ( UCase(pvValue) = &quot;BAR&quot; )
End With
Case UCase(&quot;Deep&quot;)
If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Deep&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
If oSession.HasUnoProperty(_Diagram, &quot;Deep&quot;) Then _Diagram.Deep = pvValue
Case UCase(&quot;Dim3D&quot;)
If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Dim3D&quot;, Array(ScriptForge.V_Boolean, V_STRING) _
, Array(False, True, &quot;Bar&quot;, &quot;Cylinder&quot;, &quot;Cone&quot;, &quot;Pyramid&quot;) _
) Then GoTo Finally
With _Diagram
If oSession.HasUnoProperty(_Diagram, &quot;Dim3D&quot;) Then
If _Diagram.DiagramType = &quot;com.sun.star.chart.BubbleDiagram&quot; Then
.Dim3D = False &apos; Force False value to avoid empty graph
ElseIf VarType(pvValue) = V_STRING Then
bVertical = .Vertical
.Dim3D = True
.Vertical = bVertical
If oSession.HasUnoProperty(_Diagram, &quot;SolidType&quot;) Then
If .DiagramType = cstChart &amp; &quot;BarDiagram&quot; Then
Select Case UCase(pvValue)
Case &quot;BAR&quot; : .SolidType = com.sun.star.chart.ChartSolidType.RECTANGULAR_SOLID
Case &quot;CYLINDER&quot; : .SolidType = com.sun.star.chart.ChartSolidType.CYLINDER
Case &quot;CONE&quot; : .SolidType = com.sun.star.chart.ChartSolidType.CONE
Case &quot;PYRAMID&quot; : .SolidType = com.sun.star.chart.ChartSolidType.PYRAMID
End Select
Else
.SolidType = 0
End If
End If
Else &apos; Boolean
If oSession.HasUnoProperty(_Diagram, &quot;SolidType&quot;) Then .SolidType = 0
.Dim3D = pvValue
End If
End If
End With
Case UCase(&quot;Exploded&quot;)
If oSession.HasUnoProperty(_ChartObject, &quot;Data&quot;) And _Diagram.DiagramType &lt;&gt; &quot;com.sun.star.chart.BubbleDiagram&quot; Then
&apos; All data points are presumed exploded with the same coefficient
If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Exploded&quot;, ScriptForge.V_NUMERIC) Then GoTo Finally
With _ChartObject
vData = .Data.Data
If IsArray(vData) Then
For i = 0 To UBound(vData)
If IsArray(vData(i)) Then
For j = 0 To UBound(vData(i))
_Diagram.getDataPointProperties(i, j).SegmentOffset = CLng(pvValue)
Next j
End If
Next i
End If
End With
End If
Case UCase(&quot;Filled&quot;)
&apos; Flipflop between NetDiagram and FilledNetDiagram
If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Filled&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
With _Diagram
&apos; Specify the targeted chart type
sChartType = cstChart &amp; Iif(pvValue, &quot;Filled&quot;, &quot;&quot;) &amp; &quot;NetDiagram&quot;
&apos; If there is no change, do nothing
If sChartType &lt;&gt; .DiagramType then
&apos; Do not apply if the chart type not = &quot;Net&quot;
If (pvValue And .DiagramType = cstChart &amp; &quot;NetDiagram&quot;) _
Or (Not pvValue And .DiagramType = cstChart &amp; &quot;FilledNetDiagram&quot;) Then
&apos; Some combinations old type =&gt; new type require the cancellation of 3D graphs
bDim3D = .Dim3D
.Dim3D = False
_ChartObject.createInstance(sChartType)
Set _Diagram = _ChartObject.Diagram
.Dim3D = bDim3D
End If
End If
End With
Case UCase(&quot;Legend&quot;)
If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Legend&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
If oSession.HasUnoProperty(_ChartObject, &quot;HasLegend&quot;) Then _ChartObject.HasLegend = pvValue
Case UCase(&quot;Percent&quot;)
If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Percent&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
If oSession.HasUnoProperty(_Diagram, &quot;Percent&quot;) Then
_Diagram.Stacked = pvValue
_Diagram.Percent = pvValue
End If
Case UCase(&quot;Stacked&quot;)
If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Stacked&quot;, ScriptForge.V_BOOLEAN) Then GoTo Finally
If oSession.HasUnoProperty(_Diagram, &quot;Stacked&quot;) Then
_Diagram.Stacked = pvValue
If Not pvValue Then _Diagram.Percent = False
End If
Case UCase(&quot;Title&quot;)
If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;Title&quot;, V_STRING) Then GoTo Finally
If oSession.HasUnoProperty(_ChartObject, &quot;HasMainTitle&quot;) Then
_ChartObject.HasMainTitle = ( Len(pvValue) &gt; 0 )
If Len(pvValue) &gt; 0 Then _ChartObject.Title.String = pvValue
End If
Case UCase(&quot;XTitle&quot;)
If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;XTitle&quot;, V_STRING) Then GoTo Finally
If oSession.HasUnoProperty(_Diagram, &quot;HasXAxisTitle&quot;) Then
_Diagram.HasXAxisTitle = ( Len(pvValue) &gt; 0 )
If Len(pvValue) &gt; 0 Then _Diagram.XAxisTitle.String = pvValue
End If
Case UCase(&quot;YTitle&quot;)
If Not ScriptForge.SF_Utils._Validate(pvValue, &quot;YTitle&quot;, V_STRING) Then GoTo Finally
If oSession.HasUnoProperty(_Diagram, &quot;HasYAxisTitle&quot;) Then
_Diagram.HasYAxisTitle = ( Len(pvValue) &gt; 0 )
If Len(pvValue) &gt; 0 Then _Diagram.YAxisTitle.String = pvValue
End If
Case Else
bSet = False
End Select
Finally:
_PropertySet = bSet
ScriptForge.SF_Utils._ExitFunction(cstThisSub)
Exit Function
Catch:
bSet = False
GoTo Finally
End Function &apos; SFDocuments.SF_FormControl._PropertySet
REM -----------------------------------------------------------------------------
Private Function _Repr() As String
&apos;&apos;&apos; Convert the Chart instance to a readable string, typically for debugging purposes (DebugPrint ...)
&apos;&apos;&apos; Args:
&apos;&apos;&apos; Return:
&apos;&apos;&apos; &quot;[Chart]: Name - Type
_Repr = &quot;[Chart]: &quot; &amp; ChartName &amp; &quot; - &quot; &amp; ChartType
End Function &apos; SFDocuments.SF_Chart._Repr
REM ============================================ END OF SFDOCUMENTS.SF_CHART
</script:module>

View File

@@ -0,0 +1,114 @@
<?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_DocumentListener" 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 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_DocumentListener
&apos;&apos;&apos; ===================
&apos;&apos;&apos; The current module is dedicated to the management of document events + listeners, triggered by user actions,
&apos;&apos;&apos; which cannot be defined with the Basic IDE
&apos;&apos;&apos;
&apos;&apos;&apos; Concerned listeners:
&apos;&apos;&apos; com.sun.star.sheet.XRangeSelectionListener
&apos;&apos;&apos; allowing a user to select a cell range at any moment
&apos;&apos;&apos;
&apos;&apos;&apos; The described events/listeners are processed by UNO listeners
&apos;&apos;&apos;
&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&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 ================================================================= DEFINITIONS
REM ============================================================= PRIVATE MEMBERS
Private _SelectedRange As String &apos; The selected range is returned by a &quot;done&quot; event
Private _RangeSelectionFinished As Boolean &apos; Flag indicating that the interaction with the user has stopped
REM ================================================================== EXCEPTIONS
REM ============================================================== PUBLIC METHODS
REM -----------------------------------------------------------------------------
Public Function RunRangeSelector(ByRef poComponent As Object _
, ByRef pvPropertyValues As Variant _
) As String
&apos;&apos;&apos; Called from the SF_Calc.OpenRangeSelector() method
&apos;&apos;&apos; Opens a non-modal dialog with a text box,
&apos;&apos;&apos; let the user make a selection in the current or another sheet and
&apos;&apos;&apos; returns the selected area as a string.
Dim oController As Object &apos; com.sun.star.frame.Controller
Dim oListener As Object &apos; com.sun.star.sheet.XRangeSelectionListener
Dim lCountLoops As Long &apos; Sleep cycles counter
Const cstListenerPrefix = &quot;_SFRGSEL_&quot; &apos; Prefix used for naming events Subs
Const cstSleep = 50 &apos; Sleep steps in ms while waiting for the end of the interaction
Const cstMaxSleep = (60 * 5 * 1000) / cstSleep &apos; Never sleep more than 5 minutes. Afterwards, processing continues
On Local Error GoTo Catch &apos; Avoid stopping event scripts
Try:
&apos; Create the listener
Set oController = poComponent.CurrentController
Set oListener = CreateUnoListener(cstListenerPrefix, &quot;com.sun.star.sheet.XRangeSelectionListener&quot;)
oController.addRangeSelectionListener(oListener)
&apos; Open the selector
_SelectedRange = &quot;&quot;
_RangeSelectionFinished = False
oController.startRangeSelection(pvPropertyValues)
&apos; Dummy thread synchronization
lCountLoops = 0
Do While Not _RangeSelectionFinished And lCountLoops &lt; cstMaxSleep
Wait(cstSleep)
lCountLoops = lCountLoops + 1
Loop
Finally:
If Not IsNull(oListener) Then oController.removeRangeSelectionListener(oListener)
RunRangeSelector = _SelectedRange
Exit Function
Catch:
GoTo Finally
End Function &apos; SFDocuments.SF_DocumentListener.RunRangeSelector
REM ============================================================= PRIVATE METHODS
REM -----------------------------------------------------------------------------
Sub _SFRGSEL_done(Optional poEvent As Object) &apos; com.sun.star.sheet.RangeSelectionEvent
On Local Error GoTo Catch &apos; Avoid stopping event scripts
Try:
_SelectedRange = poEvent.RangeDescriptor
_RangeSelectionFinished = True
Finally:
Exit Sub
Catch:
GoTo Finally
End Sub
REM -----------------------------------------------------------------------------
Sub _SFRGSEL_aborted(Optional poEvent As Object) &apos; com.sun.star.sheet.RangeSelectionEvent
On Local Error GoTo Catch &apos; Avoid stopping event scripts
Try:
_RangeSelectionFinished = True
Finally:
Exit Sub
Catch:
GoTo Finally
End Sub
REM ============================================ END OF SFDIALOGS.SF_DIALOGLISTENER
</script:module>

View File

@@ -0,0 +1,546 @@
<?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_Register" 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 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_Register
&apos;&apos;&apos; ===========
&apos;&apos;&apos; The ScriptForge framework includes
&apos;&apos;&apos; the master ScriptForge library
&apos;&apos;&apos; a number of &quot;associated&quot; libraries SF*
&apos;&apos;&apos; any user/contributor extension wanting to fit into the framework
&apos;&apos;&apos;
&apos;&apos;&apos; The main methods in this module allow the current library to cling to ScriptForge
&apos;&apos;&apos; - RegisterScriptServices
&apos;&apos;&apos; Register the list of services implemented by the current library
&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&apos;&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
REM ================================================================= DEFINITIONS
&apos;&apos;&apos; Strategy for management of Form and FormControl events:
&apos;&apos;&apos; ------------------------------------------------------
&apos;&apos;&apos; At the contrary of Dialogs and DialogControls, which are always started from some code,
&apos;&apos;&apos; Forms and FormControls will be initiated most often by the user, even if the SFDocuments library
&apos;&apos;&apos; allows to start forms programmatically
&apos;&apos;&apos;
&apos;&apos;&apos; For Forms started programmatically, the corresponding objects are built top-down
&apos;&apos;&apos; Event management of forms and their controls requires to being able to rebuild Form
&apos;&apos;&apos; and FormControl objects bottom-up
&apos;&apos;&apos;
&apos;&apos;&apos; To avoid multiple rebuilds requested by multiple events,
&apos;&apos;&apos; 1. The active form objects are cached in a global array of _FormCache types
&apos;&apos;&apos; 2. FormControl objects are cached in Form objects
&apos;&apos;&apos; 3. The bottom-up rebuild is executed only once, at instance creation
Type _FormCache
Terminated As Boolean
XUnoForm As Object
BasicForm As Object
End Type
REM ============================================================== PUBLIC METHODS
REM -----------------------------------------------------------------------------
Public Sub RegisterScriptServices() As Variant
&apos;&apos;&apos; Register into ScriptForge the list of the services implemented by the current library
&apos;&apos;&apos; Each library pertaining to the framework must implement its own version of this method
&apos;&apos;&apos;
&apos;&apos;&apos; It consists in successive calls to the RegisterService() and RegisterEventManager() methods
&apos;&apos;&apos; with 2 arguments:
&apos;&apos;&apos; ServiceName: the name of the service as a case-insensitive string
&apos;&apos;&apos; ServiceReference: the reference as an object
&apos;&apos;&apos; If the reference refers to a module, then return the module as an object:
&apos;&apos;&apos; GlobalScope.Library.Module
&apos;&apos;&apos; If the reference is a class instance, then return a string referring to the method
&apos;&apos;&apos; containing the New statement creating the instance
&apos;&apos;&apos; &quot;libraryname.modulename.function&quot;
With GlobalScope.ScriptForge.SF_Services
.RegisterService(&quot;Document&quot;, &quot;SFDocuments.SF_Register._NewDocument&quot;) &apos; Reference to the function initializing the service
.RegisterService(&quot;Base&quot;, &quot;SFDocuments.SF_Register._NewDocument&quot;) &apos; Same reference, distinction is made inside the function
.RegisterService(&quot;Calc&quot;, &quot;SFDocuments.SF_Register._NewDocument&quot;) &apos; Same reference, distinction is made inside the function
.RegisterService(&quot;Writer&quot;, &quot;SFDocuments.SF_Register._NewDocument&quot;) &apos; Same reference, distinction is made inside the function
.RegisterEventManager(&quot;DocumentEvent&quot;, &quot;SFDocuments.SF_Register._EventManager&quot;) &apos; Reference to the events manager
.RegisterEventManager(&quot;FormEvent&quot;, &quot;SFDocuments.SF_Register._FormEventManager&quot;)&apos; Reference to the form and controls events manager
End With
End Sub &apos; SFDocuments.SF_Register.RegisterScriptServices
REM =========================================================== PRIVATE FUNCTIONS
REM -----------------------------------------------------------------------------
Private Function _AddFormToCache(ByRef pvUnoForm As Object _
, ByRef pvBasicForm As Object _
) As Long
&apos;&apos;&apos; Add a new entry in the cache array with the references of the actual Form
&apos;&apos;&apos; If relevant, the last entry of the cache is reused.
&apos;&apos;&apos; The cache is located in the global _SF_ variable
&apos;&apos;&apos; Args:
&apos;&apos;&apos; pvUnoForm: com.sun.star.form.XForm or com.sun.star.comp.forms.ODatabaseForm
&apos;&apos;&apos; pvBasicForm: its corresponding Basic object
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; The index of the new or modified entry
Dim vCache As New _FormCache &apos; Entry to be added
Dim lIndex As Long &apos; UBound of _SF_.SFForms
Dim vCacheArray As Variant &apos; Alias of _SF_.SFForms
Try:
vCacheArray = _SF_.SFForms
If IsEmpty(vCacheArray) Then vCacheArray = Array()
lIndex = UBound(vCacheArray)
If lIndex &lt; LBound(vCacheArray) Then
ReDim vCacheArray(0 To 0)
lIndex = 0
ElseIf Not vCacheArray(lIndex).Terminated Then &apos; Often last entry can be reused
lIndex = lIndex + 1
ReDim Preserve vCacheArray(0 To lIndex)
End If
With vCache
.Terminated = False
Set .XUnoForm = pvUnoForm
Set .BasicForm = pvBasicForm
End With
Set vCacheArray(lIndex) = vCache
_SF_.SFForms = vCacheArray
Finally:
_AddFormToCache = lIndex
Exit Function
End Function &apos; SFDocuments.SF_Register._AddFormToCache
REM -----------------------------------------------------------------------------
Private Sub _CleanCacheEntry(ByVal plIndex As Long)
&apos;&apos;&apos; Clean the plIndex-th entry in the Forms cache
&apos;&apos;&apos; Args:
&apos;&apos;&apos; plIndex: must fit within the actual boundaries of the cache, otherwise the request is ignored
Dim vCache As New _FormCache &apos; Cleaned entry
With _SF_
If Not IsArray(.SFForms) Then Exit Sub
If plIndex &lt; LBound(.SFForms) Or plIndex &gt; UBound(.SFForms) Then Exit Sub
With vCache
.Terminated = True
Set .XUnoForm = Nothing
Set .BasicForm = Nothing
End With
.SFForms(plIndex) = vCache
End With
Finally:
Exit Sub
End Sub &apos; SFDocuments.SF_Register._CleanCacheEntry
REM -----------------------------------------------------------------------------
Public Function _EventManager(Optional ByRef pvArgs As Variant) As Object
&apos;&apos;&apos; Returns a Document, Calc or Base object corresponding with the active component
&apos;&apos;&apos; which triggered the event in argument
&apos;&apos;&apos; This method should be triggered only thru the invocation of CreateScriptService
&apos;&apos;&apos; Args:
&apos;&apos;&apos; pvEvent: com.sun.star.document.DocumentEvent
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; the output of a Document, Calc, ... service or Nothing
&apos;&apos;&apos; Example:
&apos;&apos;&apos; Sub TriggeredByEvent(ByRef poEvent As Object)
&apos;&apos;&apos; Dim oDoc As Object
&apos;&apos;&apos; Set oDoc = CreateScriptService(&quot;SFDocuments.DocumentEvent&quot;, poEvent)
&apos;&apos;&apos; If Not IsNull(oDoc) Then
&apos;&apos;&apos; &apos; ... (a valid document has been identified)
&apos;&apos;&apos; End Sub
Dim oSource As Object &apos; Return value
Dim vEvent As Variant &apos; Alias of pvArgs(0)
&apos; Never abort while an event is processed
If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Finally
Set oSource = Nothing
Check:
If IsMissing(pvArgs) Or IsEmpty(pvArgs) Then pvArgs = Array()
If UBound(pvArgs) &gt;= 0 Then vEvent = pvArgs(0) Else Set vEvent = Empty
If VarType(vEvent) &lt;&gt; ScriptForge.V_OBJECT Then GoTo Finally
Try:
If ScriptForge.SF_Session.UnoObjectType(vEvent) = &quot;com.sun.star.document.DocumentEvent&quot; Then
Set oSource = SF_Register._NewDocument(vEvent.Source)
End If
Finally:
Set _EventManager = oSource
Exit Function
End Function &apos; SFDocuments.SF_Register._EventManager
REM -----------------------------------------------------------------------------
Private Function _FindFormInCache(ByRef poForm As Object) As Object
&apos;&apos;&apos; Find the Form based on its XUnoForm
&apos;&apos;&apos; The Form must not be terminated
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; The corresponding Basic Form part or Nothing
Dim oBasicForm As Object &apos; Return value
Dim oCache As _FormCache &apos; Entry in the cache
Set oBasicForm = Nothing
Try:
With _SF_
If Not IsEmpty(.SFForms) Then
For Each oCache In .SFForms
If EqualUnoObjects(poForm, oCache.XUnoForm) And Not oCache.Terminated Then
Set oBasicForm = oCache.BasicForm
Exit For
End If
Next oCache
End If
End With
Finally:
Set _FindFormInCache = oBasicForm
Exit Function
End Function &apos; SFDocuments.SF_Register._FindFormInCache
REM -----------------------------------------------------------------------------
Public Function _FormEventManager(Optional ByRef pvArgs As Variant) As Object
&apos;&apos;&apos; Returns a Form or FormControl object corresponding with the form or control
&apos;&apos;&apos; which triggered the event in argument
&apos;&apos;&apos; This method should be triggered only thru the invocation of CreateScriptService
&apos;&apos;&apos; Args:
&apos;&apos;&apos; pvEvent: com.sun.star.lang.EventObject
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; the output of a Form, FormControl service or Nothing
&apos;&apos;&apos; Example:
&apos;&apos;&apos; Sub TriggeredByEvent(ByRef poEvent As Object)
&apos;&apos;&apos; Dim oForm As Object
&apos;&apos;&apos; Set oForm = CreateScriptService(&quot;SFDocuments.FormEvent&quot;, poEvent)
&apos;&apos;&apos; If Not IsNull(oForm) Then
&apos;&apos;&apos; &apos; ... (a valid form or subform has been identified)
&apos;&apos;&apos; End Sub
Dim oSource As Object &apos; Return value
Dim vEvent As Variant &apos; Alias of pvArgs(0)
Dim oControlModel As Object &apos; com.sun.star.awt.XControlModel
Dim oParent As Object &apos; com.sun.star.form.OGridControlModel or com.sun.star.comp.forms.ODatabaseForm
Dim sParentType As String &apos; &quot;com.sun.star.form.OGridControlModel&quot; or &quot;com.sun.star.comp.forms.ODatabaseForm&quot;
Dim oSFParent As Object &apos; The parent as a ScriptForge instance: SF_Form or SF_FormControl
Dim oSFForm As Object &apos; The grand-parent SF_Form instance
Dim oSession As Object : Set oSession = ScriptForge.SF_Session
&apos; Never abort while an event is processed
If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Finally
Set oSource = Nothing
Check:
If IsMissing(pvArgs) Or IsEmpty(pvArgs) Then pvArgs = Array()
If UBound(pvArgs) &gt;= 0 Then vEvent = pvArgs(0) Else Set vEvent = Empty
If VarType(vEvent) &lt;&gt; ScriptForge.V_OBJECT Then GoTo Finally
Try:
If oSession.HasUnoProperty(vEvent, &quot;Source&quot;) Then
&apos; FORM EVENT
If oSession.UnoObjectType(vEvent.Source) = &quot;com.sun.star.comp.forms.ODatabaseForm&quot; Then
Set oSource = SF_Register._NewForm(vEvent.Source, pbForceInit := True)
&apos; CONTROL EVENT
Else
&apos; A SF_FormControl instance is always created from its parent, either a form, a subform or a table control
Set oControlModel = vEvent.Source.Model &apos; The event source is a control view com.sun.star.awt.XControl
Set oParent = oControlModel.Parent
sParentType = oSession.UnoObjectType(oParent)
Select Case sParentType
Case &quot;com.sun.star.form.OGridControlModel&quot;
Set oSFForm = SF_Register._NewForm(oParent.Parent, pbForceInit := True)
Set oSFParent = oSFForm.Controls(oParent.Name)
Case &quot;com.sun.star.comp.forms.ODatabaseForm&quot;
Set oSFParent = SF_Register._NewForm(oParent, pbForceInit := True)
End Select
&apos; The final instance is derived from its parent instance
Set oSource = oSFParent.Controls(oControlModel.Name)
End If
End If
Finally:
Set _FormEventManager = oSource
Exit Function
End Function &apos; SFDocuments.SF_Register._FormEventManager
REM -----------------------------------------------------------------------------
Public Function _GetEventScriptCode(poObject As Object _
, ByVal psEvent As String _
, ByVal psName As String _
) As String
&apos;&apos;&apos; Extract from the parent of poObject the Basic script linked to psEvent.
&apos;&apos;&apos; Helper function common to forms and form controls
&apos;&apos;&apos; Args:
&apos;&apos;&apos; poObject: a com.sun.star.form.XForm or XControl object
&apos;&apos;&apos; psEvent: the &quot;On...&quot; name of the event
&apos;&apos;&apos; psName: the name of the object to be identified from the parent object
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; The script to trigger when psEvent occurs
&apos;&apos;&apos; See Scripting Framework URI Specification : https://wiki.documentfoundation.org/Documentation/DevGuide/Scripting_Framework#Scripting_Framework_URI_Specification
Dim vEvents As Variant &apos; List of available events in the parent object
&apos; Array of com.sun.star.script.ScriptEventDescriptor
Dim sEvent As String &apos; The targeted event name
Dim oParent As Object &apos; The parent object
Dim lIndex As Long &apos; The index of the targeted event in the events list of the parent object
Dim sName As String &apos; The corrected UNO event name
Dim i As Long
_GetEventScriptCode = &quot;&quot;
On Local Error GoTo Catch
If Not ScriptForge.SF_Session.HasUnoMethod(poObject, &quot;getParent&quot;) Then GoTo Finally
Try:
&apos; Find form index i.e. find control via getByIndex()
&apos; The name is known (= psName) but getByIndex() is not in the same sequence as getElementNames()
Set oParent = poObject.getParent()
lIndex = -1
For i = 0 To oParent.getCount() - 1
sName = oParent.getByIndex(i).Name
If (sName = psName) Then
lIndex = i
Exit For
End If
Next i
If lIndex &lt; 0 Then GoTo Finally &apos; Not found, should not happen
&apos; Find script triggered by event
vEvents = oParent.getScriptEvents(lIndex) &apos; Returns an array
&apos; Fix historical typo error
sEvent = Replace(LCase(Mid(psEvent, 3, 1)) &amp; Mid(psEvent, 4), &quot;errorOccurred&quot;, &quot;errorOccured&quot;)
For i = 0 To UBound(vEvents)
If vEvents(i).EventMethod = sEvent Then
_GetEventScriptCode = vEvents(i).ScriptCode
Exit For
End If
Next i
Finally:
Exit Function
Catch:
GoTo Finally
End Function &apos; SFDocuments.SF_Register._GetEventScriptCode
REM -----------------------------------------------------------------------------
Public Function _NewDocument(Optional ByVal pvArgs As Variant) As Object
&apos;&apos;&apos; Create a new instance of the (super) SF_Document class or of one of its subclasses (SF_Calc, ...)
&apos; Args:
&apos;&apos;&apos; WindowName: see the definition of WindowName in the description of the UI service
&apos;&apos;&apos; If absent, the document is presumed to be in the active window
&apos;&apos;&apos; If WindowName is an object, it must be a component
&apos;&apos;&apos; (com.sun.star.lang.XComponent or com.sun.star.comp.dba.ODatabaseDocument)
&apos;&apos;&apos; Returns: the instance or Nothing
Dim oDocument As Object &apos; Return value
Dim oSuperDocument As Object &apos; Companion superclass document
Dim vWindowName As Variant &apos; Alias of pvArgs(0)
Dim oEnum As Object &apos; com.sun.star.container.XEnumeration
Dim oComp As Object &apos; com.sun.star.lang.XComponent
Dim vWindow As Window &apos; A single component
Dim oUi As Object &apos; &quot;UI&quot; service
Dim bFound As Boolean &apos; True if the document is found on the desktop
If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
Check:
If IsMissing(pvArgs) Or IsEmpty(pvArgs) Then pvArgs = Array()
If Not IsArray(pvArgs) Then pvArgs = Array(pvArgs) &apos; Needed when _NewDocument called from _EventManager
If UBound(pvArgs) &gt;= 0 Then vWindowName = pvArgs(0) Else vWindowName = &quot;&quot;
If Not ScriptForge.SF_Utils._Validate(vWindowName, &quot;WindowName&quot;, Array(V_STRING, ScriptForge.V_OBJECT)) Then GoTo Finally
Set oDocument = Nothing
Try:
Set oUi = ScriptForge.SF_Services.CreateScriptService(&quot;UI&quot;)
Select Case VarType(vWindowName)
Case V_STRING
If Len(vWindowName) &gt; 0 Then
bFound = False
Set oEnum = StarDesktop.Components().createEnumeration
Do While oEnum.hasMoreElements
Set oComp = oEnum.nextElement
vWindow = oUi._IdentifyWindow(oComp)
With vWindow
&apos; Does the current window match the argument ?
If (Len(.WindowFileName) &gt; 0 And .WindowFileName = ScriptForge.SF_FileSystem._ConvertToUrl(vWindowName)) _
Or (Len(.WindowName) &gt; 0 And .WindowName = vWindowName) _
Or (Len(.WindowTitle) &gt; 0 And .WindowTitle = vWindowName) Then
bFound = True
Exit Do
End If
End With
Loop
Else
bFound = True
vWindow = oUi._IdentifyWindow(StarDesktop.CurrentComponent)
End If
Case ScriptForge.V_OBJECT &apos; com.sun.star.lang.XComponent
bFound = True
vWindow = oUi._IdentifyWindow(vWindowName)
End Select
If bFound And Not IsNull(vWindow.Frame) And Len(vWindow.DocumentType) &gt; 0 Then
&apos; Create the right subclass and associate to it a new instance of the superclass
Select Case vWindow.DocumentType
Case &quot;Base&quot;
Set oDocument = New SF_Base
Set oSuperDocument = New SF_Document
Set oDocument.[_Super] = oSuperDocument &apos; Now both super and subclass are twinned
Set oSuperDocument.[_SubClass] = oDocument
Case &quot;Calc&quot;
Set oDocument = New SF_Calc
Set oSuperDocument = New SF_Document
Set oDocument.[_Super] = oSuperDocument &apos; Now both super and subclass are twinned
Set oSuperDocument.[_SubClass] = oDocument
Case &quot;Writer&quot;
Set oDocument = New SF_Writer
Set oSuperDocument = New SF_Document
Set oDocument.[_Super] = oSuperDocument &apos; Now both super and subclass are twinned
Set oSuperDocument.[_SubClass] = oDocument
Case Else &apos; Only superclass
Set oDocument = New SF_Document
Set oSuperDocument = oDocument
End Select
With oDocument &apos; Initialize attributes of subclass
Set .[Me] = oDocument
Set ._Component = vWindow.Component
&apos; Initialize specific attributes
Select Case vWindow.DocumentType
Case &quot;Base&quot;
Set ._DataSource = ._Component.DataSource
Case Else
End Select
End With
With oSuperDocument &apos; Initialize attributes of superclass
Set .[Me] = oSuperDocument
Set ._Component = vWindow.Component
Set ._Frame = vWindow.Frame
._WindowName = vWindow.WindowName
._WindowTitle = vWindow.WindowTitle
._WindowFileName = vWindow.WindowFileName
._DocumentType = vWindow.DocumentType
End With
End If
Finally:
Set _NewDocument = oDocument
Exit Function
Catch:
GoTo Finally
End Function &apos; SFDocuments.SF_Register._NewDocument
REM -----------------------------------------------------------------------------
Public Function _NewForm(ByRef poForm As Object _
, Optional pbForceInit As Boolean _
) As Object
&apos;&apos;&apos; Returns an existing or a new SF_Form instance based on the argument
&apos;&apos;&apos; If the instance is new (not found in cache), the minimal members are initialized
&apos;&apos;&apos; Args:
&apos;&apos;&apos; poForm: com.sun.star.form.XForm or com.sun.star.comp.forms.ODatabaseForm
&apos;&apos;&apos; pbForceInit: when True, initialize the form instance. Default = False
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; A SF_Form instance
Dim oForm As Object &apos; Return value
Try:
Set oForm = SF_Register._FindFormInCache(poForm)
If IsNull(oForm) Then &apos; Not found
If IsMissing(pbForceInit) Or IsEmpty(pbForceInit) Then pbForceInit = False
Set oForm = New SF_Form
With oForm
._Name = poForm.Name
Set .[Me] = oForm
Set ._Form = poForm
If pbForceInit Then ._Initialize()
End With
End If
Finally:
Set _NewForm = oForm
Exit Function
End Function &apos; SFDocuments.SF_Register._NewForm
REM -----------------------------------------------------------------------------
Public Function _RegisterEventScript(poObject As Object _
, ByVal psEvent As String _
, ByVal psListener As String _
, ByVal psScriptCode As String _
, ByVal psName As String _
) As Boolean
&apos;&apos;&apos; Register a script event (psEvent) to poObject (Form, SubForm or Control)
&apos;&apos;&apos; Args:
&apos;&apos;&apos; poObject: a com.sun.star.form.XForm or XControl object
&apos;&apos;&apos; psEvent: the &quot;On...&quot; name of the event
&apos;&apos;&apos; psListener: the listener name corresponding with the event
&apos;&apos;&apos; psScriptCode: The script to trigger when psEvent occurs
&apos;&apos;&apos; See Scripting Framework URI Specification : https://wiki.documentfoundation.org/Documentation/DevGuide/Scripting_Framework#Scripting_Framework_URI_Specification
&apos;&apos;&apos; psName: the name of the object to associate with the event
&apos;&apos;&apos; Returns:
&apos;&apos;&apos; True when successful
Dim oEvent As Object &apos; com.sun.star.script.ScriptEventDescriptor
Dim sEvent As String &apos; The targeted event name
Dim oParent As Object &apos; The parent object
Dim lIndex As Long &apos; The index of the targeted event in the events list of the parent object
Dim sName As String &apos; The corrected UNO event name
Dim i As Long
_RegisterEventScript = False
On Local Error GoTo Catch
If Not ScriptForge.SF_Session.HasUnoMethod(poObject, &quot;getParent&quot;) Then GoTo Finally
Try:
&apos; Find object&apos;s internal index i.e. how to reach it via getByIndex()
Set oParent = poObject.getParent()
lIndex = -1
For i = 0 To oParent.getCount() - 1
sName = oParent.getByIndex(i).Name
If (sName = psName) Then
lIndex = i
Exit For
End If
Next i
If lIndex &lt; 0 Then GoTo Finally &apos; Not found, should not happen
&apos; Fix historical typo error
sEvent = Replace(LCase(Mid(psEvent, 3, 1)) &amp; Mid(psEvent, 4), &quot;errorOccurred&quot;, &quot;errorOccured&quot;)
&apos; Apply new script code. Erasing it is done with a specific UNO method
If psScriptCode = &quot;&quot; Then
oParent.revokeScriptEvent(lIndex, psListener, sEvent, &quot;&quot;)
Else
Set oEvent = CreateUnoStruct(&quot;com.sun.star.script.ScriptEventDescriptor&quot;)
With oEvent
.ListenerType = psListener
.EventMethod = sEvent
.ScriptType = &quot;Script&quot; &apos; Better than &quot;Basic&quot;
.ScriptCode = psScriptCode
End With
oParent.registerScriptEvent(lIndex, oEvent)
End If
_RegisterEventScript = True
Finally:
Exit Function
Catch:
GoTo Finally
End Function &apos; SFDocuments.SF_Register._RegisterEventScript
REM ============================================== END OF SFDOCUMENTS.SF_REGISTER
</script:module>

View File

@@ -0,0 +1,635 @@
<?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 :
&apos;&apos;&apos; TBD
&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;, &quot;Untitled 1&quot;) &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; TBD
&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;
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
REM ============================================================ MODULE CONSTANTS
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 ===================================================================== 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 _
, Optional ObjectName 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; ObjectName: a sheet or range name
&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 IsMissing(ObjectName) Or IsEmpty(ObjectName) Then ObjectName = &quot;&quot;
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
If Not ScriptForge.SF_Utils._Validate(PropertyName, &quot;PropertyName&quot;, V_STRING, Properties()) Then GoTo Catch
If Not ScriptForge.SF_Utils._Validate(ObjectName, &quot;ObjectName&quot;, V_STRING) Then GoTo Catch
End If
Try:
&apos; Superclass or subclass property ?
If ScriptForge.SF_Array.Contains([_Super].Properties(), PropertyName) Then
GetProperty = [_Super].GetProperty(PropertyName)
ElseIf Len(ObjectName) = 0 Then
GetProperty = _PropertyGet(PropertyName)
Else
GetProperty = _PropertyGet(PropertyName, ObjectName)
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;CustomProperties&quot; _
, &quot;Description&quot; _
, &quot;DocumentProperties&quot; _
, &quot;DocumentType&quot; _
, &quot;ExportFilters&quot; _
, &quot;ImportFilters&quot; _
, &quot;IsBase&quot; _
, &quot;IsCalc&quot; _
, &quot;IsDraw&quot; _
, &quot;IsImpress&quot; _
, &quot;IsMath&quot; _
, &quot;IsWriter&quot; _
, &quot;Keywords&quot; _
, &quot;Readonly&quot; _
, &quot;Subject&quot; _
, &quot;Title&quot; _
, &quot;XComponent&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 ImportFilters() As Variant
ImportFilters = [_Super].GetProperty(&quot;ImportFilters&quot;)
End Property &apos; SFDocuments.SF_Writer.ImportFilters
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 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 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 ========================================================== 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 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 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 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 =========================================================== 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 _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 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 psProperty
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>

View File

@@ -0,0 +1,26 @@
<?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="__License" script:language="StarBasic" script:moduleType="normal">
&apos;&apos;&apos; Copyright 2019-2022 Jean-Pierre LEDURE, Rafael LIMA, Alain ROMEDENNE
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 =======================================================================================================================
&apos;&apos;&apos; ScriptForge is distributed in the hope that it will be useful,
&apos;&apos;&apos; but WITHOUT ANY WARRANTY; without even the implied warranty of
&apos;&apos;&apos; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
&apos;&apos;&apos; ScriptForge is free software; you can redistribute it and/or modify it under the terms of either (at your option):
&apos;&apos;&apos; 1) The Mozilla Public License, v. 2.0. If a copy of the MPL was not
&apos;&apos;&apos; distributed with this file, you can obtain one at http://mozilla.org/MPL/2.0/ .
&apos;&apos;&apos; 2) The GNU Lesser General Public License as published by
&apos;&apos;&apos; the Free Software Foundation, either version 3 of the License, or
&apos;&apos;&apos; (at your option) any later version. If a copy of the LGPL was not
&apos;&apos;&apos; distributed with this file, see http://www.gnu.org/licenses/ .
</script:module>

View File

@@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE library:library PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "library.dtd">
<library:library xmlns:library="http://openoffice.org/2000/library" library:name="SFDocuments" library:readonly="false" library:passwordprotected="false"/>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE library:library PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "library.dtd">
<library:library xmlns:library="http://openoffice.org/2000/library" library:name="SFDocuments" library:readonly="false" library:passwordprotected="false">
<library:element library:name="__License"/>
<library:element library:name="SF_Document"/>
<library:element library:name="SF_Calc"/>
<library:element library:name="SF_Register"/>
<library:element library:name="SF_Base"/>
<library:element library:name="SF_Form"/>
<library:element library:name="SF_FormControl"/>
<library:element library:name="SF_Writer"/>
<library:element library:name="SF_Chart"/>
<library:element library:name="SF_DocumentListener"/>
</library:library>