update
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,959 @@
|
||||
<?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_Dictionary" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
|
||||
REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
|
||||
REM === Full documentation is available on https://help.libreoffice.org/ ===
|
||||
REM =======================================================================================================================
|
||||
|
||||
Option Compatible
|
||||
Option ClassModule
|
||||
|
||||
Option Explicit
|
||||
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
''' SF_Dictionary
|
||||
''' =============
|
||||
''' Class for management of dictionaries
|
||||
''' A dictionary is a collection of key-item pairs
|
||||
''' The key is a not case-sensitive string
|
||||
''' Items may be of any type
|
||||
''' Keys, items can be retrieved, counted, etc.
|
||||
'''
|
||||
''' The implementation is based on
|
||||
''' - one collection mapping keys and entries in the array
|
||||
''' - one 1-column array: key + data
|
||||
'''
|
||||
''' Why a Dictionary class beside the builtin Collection class ?
|
||||
''' A standard Basic collection does not support the retrieval of the keys
|
||||
''' Additionally it may contain only simple data (strings, numbers, ...)
|
||||
'''
|
||||
''' Service instantiation example:
|
||||
''' Dim myDict As Variant
|
||||
''' myDict = CreateScriptService("Dictionary") ' Once per dictionary
|
||||
'''
|
||||
''' Detailed user documentation:
|
||||
''' https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03/sf_dictionary.html?DbPAR=BASIC
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
REM ================================================================== EXCEPTIONS
|
||||
|
||||
Const DUPLICATEKEYERROR = "DUPLICATEKEYERROR" ' Key exists already
|
||||
Const UNKNOWNKEYERROR = "UNKNOWNKEYERROR" ' Key not found
|
||||
Const INVALIDKEYERROR = "INVALIDKEYERROR" ' Key contains only spaces
|
||||
|
||||
REM ============================================================= PRIVATE MEMBERS
|
||||
|
||||
' Defines an entry in the MapItems array
|
||||
Type ItemMap
|
||||
Key As String
|
||||
Value As Variant
|
||||
End Type
|
||||
|
||||
Private [Me] As Object
|
||||
Private [_Parent] As Object
|
||||
Private ObjectType As String ' Must be "DICTIONARY"
|
||||
Private ServiceName As String
|
||||
Private MapKeys As Variant ' To retain the original keys
|
||||
Private MapItems As Variant ' Array of ItemMaps
|
||||
Private _MapSize As Long ' Total number of entries in the dictionary
|
||||
Private _MapRemoved As Long ' Number of inactive entries in the dictionary
|
||||
|
||||
REM ===================================================== CONSTRUCTOR/DESTRUCTOR
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Sub Class_Initialize()
|
||||
Set [Me] = Nothing
|
||||
Set [_Parent] = Nothing
|
||||
ObjectType = "DICTIONARY"
|
||||
ServiceName = "ScriptForge.Dictionary"
|
||||
Set MapKeys = New Collection
|
||||
Set MapItems = Array()
|
||||
_MapSize = 0
|
||||
_MapRemoved = 0
|
||||
End Sub ' ScriptForge.SF_Dictionary Constructor
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Sub Class_Terminate()
|
||||
Call Class_Initialize()
|
||||
End Sub ' ScriptForge.SF_Dictionary Destructor
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Dispose() As Variant
|
||||
RemoveAll()
|
||||
Set Dispose = Nothing
|
||||
End Function ' ScriptForge.SF_Dictionary Explicit destructor
|
||||
|
||||
REM ================================================================== PROPERTIES
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get Count() As Long
|
||||
''' Actual number of entries in the dictionary
|
||||
''' Example:
|
||||
''' myDict.Count
|
||||
|
||||
Count = _PropertyGet("Count")
|
||||
|
||||
End Property ' ScriptForge.SF_Dictionary.Count
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Item(Optional ByVal Key As Variant) As Variant
|
||||
''' Return the value of the item related to Key
|
||||
''' Args:
|
||||
''' Key: the key value (string)
|
||||
''' Returns:
|
||||
''' Empty if not found, otherwise the found value
|
||||
''' Example:
|
||||
''' myDict.Item("ThisKey")
|
||||
''' NB: defined as a function to not disrupt the Basic IDE debugger
|
||||
|
||||
Item = _PropertyGet("Item", Key)
|
||||
|
||||
End Function ' ScriptForge.SF_Dictionary.Item
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get Items() as Variant
|
||||
''' Return the list of Items as a 1D array
|
||||
''' The Items and Keys properties return their respective contents in the same order
|
||||
''' The order is however not necessarily identical to the creation sequence
|
||||
''' Returns:
|
||||
''' The array is empty if the dictionary is empty
|
||||
''' Examples
|
||||
''' a = myDict.Items
|
||||
''' For Each b In a ...
|
||||
|
||||
Items = _PropertyGet("Items")
|
||||
|
||||
End Property ' ScriptForge.SF_Dictionary.Items
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get Keys() as Variant
|
||||
''' Return the list of keys as a 1D array
|
||||
''' The Keys and Items properties return their respective contents in the same order
|
||||
''' The order is however not necessarily identical to the creation sequence
|
||||
''' Returns:
|
||||
''' The array is empty if the dictionary is empty
|
||||
''' Examples
|
||||
''' a = myDict.Keys
|
||||
''' For each b In a ...
|
||||
|
||||
Keys = _PropertyGet("Keys")
|
||||
|
||||
End Property ' ScriptForge.SF_Dictionary.Keys
|
||||
|
||||
REM ===================================================================== METHODS
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Add(Optional ByVal Key As Variant _
|
||||
, Optional ByVal Item As Variant _
|
||||
) As Boolean
|
||||
''' Add a new key-item pair into the dictionary
|
||||
''' Args:
|
||||
''' Key: must not yet exist in the dictionary
|
||||
''' Item: any value, including an array, a Basic object, a UNO object, ...
|
||||
''' Returns: True if successful
|
||||
''' Exceptions:
|
||||
''' DUPLICATEKEYERROR: such a key exists already
|
||||
''' INVALIDKEYERROR: zero-length string or only spaces
|
||||
''' Examples:
|
||||
''' myDict.Add("NewKey", NewValue)
|
||||
|
||||
Dim oItemMap As ItemMap ' New entry in the MapItems array
|
||||
Const cstThisSub = "Dictionary.Add"
|
||||
Const cstSubArgs = "Key, Item"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
Add = False
|
||||
|
||||
Check:
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(Key, "Key", V_STRING) Then GoTo Catch
|
||||
If IsArray(Item) Then
|
||||
If Not SF_Utils._ValidateArray(Item, "Item") Then GoTo Catch
|
||||
Else
|
||||
If Not SF_Utils._Validate(Item, "Item") Then GoTo Catch
|
||||
End If
|
||||
End If
|
||||
If Key = Space(Len(Key)) Then GoTo CatchInvalid
|
||||
If Exists(Key) Then GoTo CatchDuplicate
|
||||
|
||||
Try:
|
||||
_MapSize = _MapSize + 1
|
||||
MapKeys.Add(_MapSize, Key)
|
||||
oItemMap.Key = Key
|
||||
oItemMap.Value = Item
|
||||
ReDim Preserve MapItems(1 To _MapSize)
|
||||
MapItems(_MapSize) = oItemMap
|
||||
Add = True
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
CatchDuplicate:
|
||||
SF_Exception.RaiseFatal(DUPLICATEKEYERROR, "Key", Key)
|
||||
GoTo Finally
|
||||
CatchInvalid:
|
||||
SF_Exception.RaiseFatal(INVALIDKEYERROR, "Key")
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Dictionary.Add
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function ConvertToArray() As Variant
|
||||
''' Store the content of the dictionary in a 2-columns array:
|
||||
''' Key stored in 1st column, Item stored in 2nd
|
||||
''' Args:
|
||||
''' Returns:
|
||||
''' a zero-based 2D array(0:Count - 1, 0:1)
|
||||
''' an empty array if the dictionary is empty
|
||||
|
||||
Dim vArray As Variant ' Return value
|
||||
Dim sKey As String ' Tempry key
|
||||
Dim vKeys As Variant ' Array of keys
|
||||
Dim lCount As Long ' Counter
|
||||
Const cstThisSub = "Dictionary.ConvertToArray"
|
||||
Const cstSubArgs = ""
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
|
||||
Check:
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Try:
|
||||
vArray = Array()
|
||||
If Count = 0 Then
|
||||
Else
|
||||
ReDim vArray(0 To Count - 1, 0 To 1)
|
||||
lCount = -1
|
||||
vKeys = Keys
|
||||
For Each sKey in vKeys
|
||||
lCount = lCount + 1
|
||||
vArray(lCount, 0) = sKey
|
||||
vArray(lCount, 1) = Item(sKey)
|
||||
Next sKey
|
||||
End If
|
||||
|
||||
Finally:
|
||||
ConvertToArray = vArray()
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Dictionary.ConvertToArray
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function ConvertToJson(ByVal Optional Indent As Variant) As Variant
|
||||
''' Convert the content of the dictionary to a JSON string
|
||||
''' JSON = JavaScript Object Notation: https://en.wikipedia.org/wiki/JSON
|
||||
''' Limitations
|
||||
''' Allowed item types: String, Boolean, numbers, Null and Empty
|
||||
''' Arrays containing above types are allowed
|
||||
''' Dates are converted into strings (not within arrays)
|
||||
''' Other types are converted to their string representation (cfr. SF_String.Represent)
|
||||
''' Args:
|
||||
''' Indent:
|
||||
''' If indent is a non-negative integer or string, then JSON array elements and object members will be pretty-printed with that indent level.
|
||||
''' An indent level <= 0 will only insert newlines.
|
||||
''' "", (the default) selects the most compact representation.
|
||||
''' Using a positive integer indent indents that many spaces per level.
|
||||
''' If indent is a string (such as Chr(9)), that string is used to indent each level.
|
||||
''' Returns:
|
||||
''' the JSON string
|
||||
''' Example:
|
||||
''' myDict.Add("p0", 12.5)
|
||||
''' myDict.Add("p1", "a string àé""ê")
|
||||
''' myDict.Add("p2", DateSerial(2020,9,28))
|
||||
''' myDict.Add("p3", True)
|
||||
''' myDict.Add("p4", Array(1,2,3))
|
||||
''' MsgBox a.ConvertToJson() ' {"p0": 12.5, "p1": "a string \u00e0\u00e9\"\u00ea", "p2": "2020-09-28", "p3": true, "p4": [1, 2, 3]}
|
||||
|
||||
Dim sJson As String ' Return value
|
||||
Dim vArray As Variant ' Array of property values
|
||||
Dim oPropertyValue As Object ' com.sun.star.beans.PropertyValue
|
||||
Dim sKey As String ' Tempry key
|
||||
Dim vKeys As Variant ' Array of keys
|
||||
Dim vItem As Variant ' Tempry item
|
||||
Dim iVarType As Integer ' Extended VarType
|
||||
Dim lCount As Long ' Counter
|
||||
Dim vIndent As Variant ' Python alias of Indent
|
||||
Const cstPyHelper = "$" & "_SF_Dictionary__ConvertToJson"
|
||||
|
||||
Const cstThisSub = "Dictionary.ConvertToJson"
|
||||
Const cstSubArgs = "[Indent=Null]"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
|
||||
Check:
|
||||
If IsMissing(Indent) Or IsEmpty(INDENT) Then Indent = ""
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(Indent, "Indent", Array(V_STRING, V_NUMERIC)) Then GoTo Finally
|
||||
End If
|
||||
sJson = ""
|
||||
|
||||
Try:
|
||||
vArray = Array()
|
||||
If Count = 0 Then
|
||||
Else
|
||||
ReDim vArray(0 To Count - 1)
|
||||
lCount = -1
|
||||
vKeys = Keys
|
||||
For Each sKey in vKeys
|
||||
' Check item type
|
||||
vItem = Item(sKey)
|
||||
iVarType = SF_Utils._VarTypeExt(vItem)
|
||||
Select Case iVarType
|
||||
Case V_STRING, V_BOOLEAN, V_NUMERIC, V_NULL, V_EMPTY
|
||||
Case V_DATE
|
||||
vItem = SF_Utils._CDateToIso(vItem)
|
||||
Case >= V_ARRAY
|
||||
Case Else
|
||||
vItem = SF_Utils._Repr(vItem)
|
||||
End Select
|
||||
' Build in each array entry a (Name, Value) pair
|
||||
Set oPropertyValue = SF_Utils._MakePropertyValue(sKey, vItem)
|
||||
lCount = lCount + 1
|
||||
Set vArray(lCount) = oPropertyValue
|
||||
Next sKey
|
||||
End If
|
||||
|
||||
'Pass array to Python script for the JSON conversion
|
||||
With ScriptForge.SF_Session
|
||||
vIndent = Indent
|
||||
If VarType(Indent) = V_STRING Then
|
||||
If Len(Indent) = 0 Then vIndent = Null
|
||||
End If
|
||||
sJson = .ExecutePythonScript(.SCRIPTISSHARED, _SF_.PythonHelper & cstPyHelper, vArray, vIndent)
|
||||
End With
|
||||
|
||||
Finally:
|
||||
ConvertToJson = sJson
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Dictionary.ConvertToJson
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function ConvertToPropertyValues() As Variant
|
||||
''' Store the content of the dictionary in an array of PropertyValues
|
||||
''' Key stored in Name, Item stored in Value
|
||||
''' Args:
|
||||
''' Returns:
|
||||
''' a zero-based 1D array(0:Count - 1). Each entry is a com.sun.star.beans.PropertyValue
|
||||
''' Name: the key in the dictionary
|
||||
''' Value:
|
||||
''' Dates are converted to UNO dates
|
||||
''' Empty arrays are replaced by Null
|
||||
''' an empty array if the dictionary is empty
|
||||
|
||||
Dim vArray As Variant ' Return value
|
||||
Dim oPropertyValue As Object ' com.sun.star.beans.PropertyValue
|
||||
Dim sKey As String ' Tempry key
|
||||
Dim vKeys As Variant ' Array of keys
|
||||
Dim lCount As Long ' Counter
|
||||
Const cstThisSub = "Dictionary.ConvertToPropertyValues"
|
||||
Const cstSubArgs = ""
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
|
||||
Check:
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Try:
|
||||
vArray = Array()
|
||||
If Count = 0 Then
|
||||
Else
|
||||
ReDim vArray(0 To Count - 1)
|
||||
lCount = -1
|
||||
vKeys = Keys
|
||||
For Each sKey in vKeys
|
||||
' Build in each array entry a (Name, Value) pair
|
||||
Set oPropertyValue = SF_Utils._MakePropertyValue(sKey, Item(sKey))
|
||||
lCount = lCount + 1
|
||||
Set vArray(lCount) = oPropertyValue
|
||||
Next sKey
|
||||
End If
|
||||
|
||||
Finally:
|
||||
ConvertToPropertyValues = vArray()
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Dictionary.ConvertToPropertyValues
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Exists(Optional ByVal Key As Variant) As Boolean
|
||||
''' Determine if a key exists in the dictionary
|
||||
''' Args:
|
||||
''' Key: the key value (string)
|
||||
''' Returns: True if key exists
|
||||
''' Examples:
|
||||
''' If myDict.Exists("SomeKey") Then ' don't add again
|
||||
|
||||
Dim vItem As Variant ' Item part in MapKeys
|
||||
Const cstThisSub = "Dictionary.Exists"
|
||||
Const cstSubArgs = "Key"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
Exists = False
|
||||
|
||||
Check:
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(Key, "Key", V_STRING) Then GoTo Catch
|
||||
End If
|
||||
|
||||
Try:
|
||||
' Dirty but preferred to go through whole collection
|
||||
On Local Error GoTo NotFound
|
||||
vItem = MapKeys(Key)
|
||||
NotFound:
|
||||
Exists = ( Not ( Err = 5 ) And vItem > 0 )
|
||||
On Local Error GoTo 0
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Dictionary.Exists
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function GetProperty(Optional ByVal PropertyName As Variant _
|
||||
, Optional ByVal Key As Variant _
|
||||
) As Variant
|
||||
''' Return the actual value of the given property
|
||||
''' Args:
|
||||
''' PropertyName: the name of the property as a string
|
||||
''' Key: mandatory if PropertyName = "Item", ignored otherwise
|
||||
''' Returns:
|
||||
''' The actual value of the property
|
||||
''' Exceptions:
|
||||
''' ARGUMENTERROR The property does not exist
|
||||
''' Examples:
|
||||
''' myDict.GetProperty("Count")
|
||||
|
||||
Const cstThisSub = "Dictionary.GetProperty"
|
||||
Const cstSubArgs = "PropertyName, [Key]"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
GetProperty = Null
|
||||
|
||||
Check:
|
||||
If IsMissing(Key) Or IsEmpty(Key) Then Key = ""
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(PropertyName, "PropertyName", V_STRING, Properties()) Then GoTo Catch
|
||||
End If
|
||||
|
||||
Try:
|
||||
GetProperty = _PropertyGet(PropertyName, Key)
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Dictionary.GetProperty
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function ImportFromJson(Optional ByVal InputStr As Variant _
|
||||
, Optional ByVal Overwrite As Variant _
|
||||
) As Boolean
|
||||
''' Adds the content of a Json string into the current dictionary
|
||||
''' JSON = JavaScript Object Notation: https://en.wikipedia.org/wiki/JSON
|
||||
''' Limitations
|
||||
''' The JSON string may contain numbers, strings, booleans, null values and arrays containing those types
|
||||
''' It must not contain JSON objects, i.e. sub-dictionaries
|
||||
''' An attempt is made to convert strings to dates if they fit one of next patterns:
|
||||
''' YYYY-MM-DD, HH:MM:SS or YYYY-MM-DD HH:MM:SS
|
||||
''' Args:
|
||||
''' InputStr: the json string to import
|
||||
''' Overwrite: when True entries with same name may exist in the dictionary and their values are overwritten
|
||||
''' Default = False
|
||||
''' Returns:
|
||||
''' True if successful
|
||||
''' Exceptions:
|
||||
''' DUPLICATEKEYERROR: such a key exists already
|
||||
''' INVALIDKEYERROR: zero-length string or only spaces
|
||||
''' Example:
|
||||
''' Dim s As String
|
||||
''' s = "{'firstName': 'John','lastName': 'Smith','isAlive': true,'age': 66, 'birth': '1954-09-28 20:15:00'" _
|
||||
''' & ",'address': {'streetAddress': '21 2nd Street','city': 'New York','state': 'NY','postalCode': '10021-3100'}" _
|
||||
''' & ",'phoneNumbers': [{'type': 'home','number': '212 555-1234'},{'type': 'office','number': '646 555-4567'}]" _
|
||||
''' & ",'children': ['Q','M','G','T'],'spouse': null}"
|
||||
''' s = Replace(s, "'", """")
|
||||
''' myDict.ImportFromJson(s, OverWrite := True)
|
||||
''' ' The (sub)-dictionaries "address" and "phoneNumbers(0) and (1) are reduced to Empty
|
||||
|
||||
Dim bImport As Boolean ' Return value
|
||||
Dim vArray As Variant ' JSON string converted to array
|
||||
Dim vArrayEntry As Variant ' A single entry in vArray
|
||||
Dim vKey As Variant ' Tempry key
|
||||
Dim vItem As Variant ' Tempry item
|
||||
Dim bExists As Boolean ' True when an entry exists
|
||||
Dim dDate As Date ' String converted to Date
|
||||
Const cstPyHelper = "$" & "_SF_Dictionary__ImportFromJson"
|
||||
|
||||
Const cstThisSub = "Dictionary.ImportFromJson"
|
||||
Const cstSubArgs = "InputStr, [Overwrite=False]"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
bImport = False
|
||||
|
||||
Check:
|
||||
If IsMissing(Overwrite) Or IsEmpty(Overwrite) Then Overwrite = False
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(InputStr, "InputStr", V_STRING) Then GoTo Finally
|
||||
If Not SF_Utils._Validate(Overwrite, "Overwrite", V_BOOLEAN) Then GoYo Finally
|
||||
End If
|
||||
|
||||
Try:
|
||||
With ScriptForge.SF_Session
|
||||
vArray = .ExecutePythonScript(.SCRIPTISSHARED, _SF_.PythonHelper & cstPyHelper, InputStr)
|
||||
End With
|
||||
If Not IsArray(vArray) Then GoTo Finally ' Conversion error or nothing to do
|
||||
|
||||
' vArray = Array of subarrays = 2D DataArray (cfr. Calc)
|
||||
For Each vArrayEntry In vArray
|
||||
vKey = vArrayEntry(0)
|
||||
If VarType(vKey) = V_STRING Then ' Else skip
|
||||
vItem = vArrayEntry(1)
|
||||
If Overwrite Then bExists = Exists(vKey) Else bExists = False
|
||||
' When the item matches a date pattern, convert it to a date
|
||||
If VarType(vItem) = V_STRING Then
|
||||
dDate = SF_Utils._CStrToDate(vItem)
|
||||
If dDate > -1 Then vItem = dDate
|
||||
End If
|
||||
If bExists Then
|
||||
ReplaceItem(vKey, vItem)
|
||||
Else
|
||||
Add(vKey, vItem) ' Key controls are done in Add
|
||||
End If
|
||||
End If
|
||||
Next vArrayEntry
|
||||
|
||||
bImport = True
|
||||
|
||||
Finally:
|
||||
ImportFromJson = bImport
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Dictionary.ImportFromJson
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function ImportFromPropertyValues(Optional ByVal PropertyValues As Variant _
|
||||
, Optional ByVal Overwrite As Variant _
|
||||
) As Boolean
|
||||
''' Adds the content of an array of PropertyValues into the current dictionary
|
||||
''' Names contain Keys, Values contain Items
|
||||
''' UNO dates are replaced by Basic dates
|
||||
''' Args:
|
||||
''' PropertyValues: a zero-based 1D array. Each entry is a com.sun.star.beans.PropertyValue
|
||||
''' Overwrite: when True entries with same name may exist in the dictionary and their values are overwritten
|
||||
''' Default = False
|
||||
''' Returns:
|
||||
''' True if successful
|
||||
''' Exceptions:
|
||||
''' DUPLICATEKEYERROR: such a key exists already
|
||||
''' INVALIDKEYERROR: zero-length string or only spaces
|
||||
|
||||
Dim bImport As Boolean ' Return value
|
||||
Dim oPropertyValue As Object ' com.sun.star.beans.PropertyValue
|
||||
Dim vItem As Variant ' Tempry item
|
||||
Dim sObjectType As String ' UNO object type of dates
|
||||
Dim bExists As Boolean ' True when an entry exists
|
||||
Const cstThisSub = "Dictionary.ImportFromPropertyValues"
|
||||
Const cstSubArgs = "PropertyValues, [Overwrite=False]"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
bImport = False
|
||||
|
||||
Check:
|
||||
If IsMissing(Overwrite) Or IsEmpty(Overwrite) Then Overwrite = False
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If IsArray(PropertyValues) Then
|
||||
If Not SF_Utils._ValidateArray(PropertyValues, "PropertyValues", 1, V_OBJECT, True) Then GoTo Finally
|
||||
Else
|
||||
If Not SF_Utils._Validate(PropertyValues, "PropertyValues", V_OBJECT) Then GoTo Finally
|
||||
End If
|
||||
If Not SF_Utils._Validate(Overwrite, "Overwrite", V_BOOLEAN) Then GoYo Finally
|
||||
End If
|
||||
|
||||
Try:
|
||||
If Not IsArray(PropertyValues) Then PropertyValues = Array(PropertyValues)
|
||||
With oPropertyValue
|
||||
For Each oPropertyValue In PropertyValues
|
||||
If Overwrite Then bExists = Exists(.Name) Else bExists = False
|
||||
If SF_Session.UnoObjectType(oPropertyValue) = "com.sun.star.beans.PropertyValue" Then
|
||||
If IsUnoStruct(.Value) Then
|
||||
sObjectType = SF_Session.UnoObjectType(.Value)
|
||||
Select Case sObjectType
|
||||
Case "com.sun.star.util.DateTime" : vItem = CDateFromUnoDateTime(.Value)
|
||||
Case "com.sun.star.util.Date" : vItem = CDateFromUnoDate(.Value)
|
||||
Case "com.sun.star.util.Time" : vItem = CDateFromUnoTime(.Value)
|
||||
Case Else : vItem = .Value
|
||||
End Select
|
||||
Else
|
||||
vItem = .Value
|
||||
End If
|
||||
If bExists Then
|
||||
ReplaceItem(.Name, vItem)
|
||||
Else
|
||||
Add(.Name, vItem) ' Key controls are done in Add
|
||||
End If
|
||||
End If
|
||||
Next oPropertyValue
|
||||
End With
|
||||
bImport = True
|
||||
|
||||
Finally:
|
||||
ImportFromPropertyValues = bImport
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Dictionary.ImportFromPropertyValues
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Methods() As Variant
|
||||
''' Return the list or methods of the Dictionary class as an array
|
||||
|
||||
Methods = Array( _
|
||||
"Add" _
|
||||
, "ConvertToArray" _
|
||||
, "ConvertToJson" _
|
||||
, "ConvertToPropertyValues" _
|
||||
, "Exists" _
|
||||
, "ImportFromJson" _
|
||||
, "ImportFromPropertyValues" _
|
||||
, "Remove" _
|
||||
, "RemoveAll" _
|
||||
, "ReplaceItem" _
|
||||
, "ReplaceKey" _
|
||||
)
|
||||
|
||||
End Function ' ScriptForge.SF_Dictionary.Methods
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Properties() As Variant
|
||||
''' Return the list or properties of the Dictionary class as an array
|
||||
|
||||
Properties = Array( _
|
||||
"Count" _
|
||||
, "Item" _
|
||||
, "Items" _
|
||||
, "Keys" _
|
||||
)
|
||||
|
||||
End Function ' ScriptForge.SF_Dictionary.Properties
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Remove(Optional ByVal Key As Variant) As Boolean
|
||||
''' Remove an existing dictionary entry based on its key
|
||||
''' Args:
|
||||
''' Key: must exist in the dictionary
|
||||
''' Returns: True if successful
|
||||
''' Exceptions:
|
||||
''' UNKNOWNKEYERROR: the key does not exist
|
||||
''' Examples:
|
||||
''' myDict.Remove("OldKey")
|
||||
|
||||
Dim lIndex As Long ' To remove entry in the MapItems array
|
||||
Const cstThisSub = "Dictionary.Remove"
|
||||
Const cstSubArgs = "Key"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
Remove = False
|
||||
|
||||
Check:
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(Key, "Key", V_STRING) Then GoTo Catch
|
||||
End If
|
||||
If Not Exists(Key) Then GoTo CatchUnknown
|
||||
|
||||
Try:
|
||||
lIndex = MapKeys.Item(Key)
|
||||
MapKeys.Remove(Key)
|
||||
Erase MapItems(lIndex) ' Is now Empty
|
||||
_MapRemoved = _MapRemoved + 1
|
||||
Remove = True
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
CatchUnknown:
|
||||
SF_Exception.RaiseFatal(UNKNOWNKEYERROR, "Key", Key)
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Dictionary.Remove
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function RemoveAll() As Boolean
|
||||
''' Remove all the entries from the dictionary
|
||||
''' Args:
|
||||
''' Returns: True if successful
|
||||
''' Examples:
|
||||
''' myDict.RemoveAll()
|
||||
|
||||
Dim vKeys As Variant ' Array of keys
|
||||
Dim sColl As String ' A collection key in MapKeys
|
||||
Const cstThisSub = "Dictionary.RemoveAll"
|
||||
Const cstSubArgs = ""
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
RemoveAll = False
|
||||
|
||||
Check:
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Try:
|
||||
vKeys = Keys
|
||||
For Each sColl In vKeys
|
||||
MapKeys.Remove(sColl)
|
||||
Next sColl
|
||||
Erase MapKeys
|
||||
Erase MapItems
|
||||
' Make dictionary ready to receive new entries
|
||||
Call Class_Initialize()
|
||||
RemoveAll = True
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Dictionary.RemoveAll
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function ReplaceItem(Optional ByVal Key As Variant _
|
||||
, Optional ByVal Value As Variant _
|
||||
) As Boolean
|
||||
''' Replace the item value
|
||||
''' Args:
|
||||
''' Key: must exist in the dictionary
|
||||
''' Returns: True if successful
|
||||
''' Exceptions:
|
||||
''' UNKNOWNKEYERROR: the old key does not exist
|
||||
''' Examples:
|
||||
''' myDict.ReplaceItem("Key", NewValue)
|
||||
|
||||
Dim oItemMap As ItemMap ' Content to update in the MapItems array
|
||||
Dim lIndex As Long ' Entry in the MapItems array
|
||||
Const cstThisSub = "Dictionary.ReplaceItem"
|
||||
Const cstSubArgs = "Key, Value"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
ReplaceItem = False
|
||||
|
||||
Check:
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(Key, "Key", V_STRING) Then GoTo Catch
|
||||
If IsArray(Value) Then
|
||||
If Not SF_Utils._ValidateArray(Value, "Value") Then GoTo Catch
|
||||
Else
|
||||
If Not SF_Utils._Validate(Value, "Value") Then GoTo Catch
|
||||
End If
|
||||
End If
|
||||
If Not Exists(Key) Then GoTo CatchUnknown
|
||||
|
||||
Try:
|
||||
' Find entry in MapItems and update it with the new value
|
||||
lIndex = MapKeys.Item(Key)
|
||||
oItemMap = MapItems(lIndex)
|
||||
oItemMap.Value = Value
|
||||
ReplaceItem = True
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
CatchUnknown:
|
||||
SF_Exception.RaiseFatal(UNKNOWNKEYERROR, "Key", Key)
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Dictionary.ReplaceItem
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function ReplaceKey(Optional ByVal Key As Variant _
|
||||
, Optional ByVal Value As Variant _
|
||||
) As Boolean
|
||||
''' Replace existing key
|
||||
''' Args:
|
||||
''' Key: must exist in the dictionary
|
||||
''' Value: must not exist in the dictionary
|
||||
''' Returns: True if successful
|
||||
''' Exceptions:
|
||||
''' UNKNOWNKEYERROR: the old key does not exist
|
||||
''' DUPLICATEKEYERROR: the new key exists
|
||||
''' Examples:
|
||||
''' myDict.ReplaceKey("OldKey", "NewKey")
|
||||
|
||||
Dim oItemMap As ItemMap ' Content to update in the MapItems array
|
||||
Dim lIndex As Long ' Entry in the MapItems array
|
||||
Const cstThisSub = "Dictionary.ReplaceKey"
|
||||
Const cstSubArgs = "Key, Value"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
ReplaceKey = False
|
||||
|
||||
Check:
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(Key, "Key", V_STRING) Then GoTo Catch
|
||||
If Not SF_Utils._Validate(Value, "Value", V_STRING) Then GoTo Catch
|
||||
End If
|
||||
If Not Exists(Key) Then GoTo CatchUnknown
|
||||
If Value = Space(Len(Value)) Then GoTo CatchInvalid
|
||||
If Exists(Value) Then GoTo CatchDuplicate
|
||||
|
||||
Try:
|
||||
' Remove the Key entry and create a new one in MapKeys
|
||||
With MapKeys
|
||||
lIndex = .Item(Key)
|
||||
.Remove(Key)
|
||||
.Add(lIndex, Value)
|
||||
End With
|
||||
oItemMap = MapItems(lIndex)
|
||||
oItemMap.Key = Value
|
||||
ReplaceKey = True
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
CatchUnknown:
|
||||
SF_Exception.RaiseFatal(UNKNOWNKEYERROR, "Key", Key)
|
||||
GoTo Finally
|
||||
CatchDuplicate:
|
||||
SF_Exception.RaiseFatal(DUPLICATEKEYERROR, "Value", Value)
|
||||
GoTo Finally
|
||||
CatchInvalid:
|
||||
SF_Exception.RaiseFatal(INVALIDKEYERROR, "Key")
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Dictionary.ReplaceKey
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function SetProperty(Optional ByVal PropertyName As Variant _
|
||||
, Optional ByRef Value As Variant _
|
||||
) As Boolean
|
||||
''' Set a new value to the given property
|
||||
''' Args:
|
||||
''' PropertyName: the name of the property as a string
|
||||
''' Value: its new value
|
||||
''' Exceptions
|
||||
''' ARGUMENTERROR The property does not exist
|
||||
|
||||
Const cstThisSub = "Dictionary.SetProperty"
|
||||
Const cstSubArgs = "PropertyName, Value"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
SetProperty = False
|
||||
|
||||
Check:
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(PropertyName, "PropertyName", V_STRING, Properties()) Then GoTo Catch
|
||||
End If
|
||||
|
||||
Try:
|
||||
Select Case UCase(PropertyName)
|
||||
Case Else
|
||||
End Select
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Dictionary.SetProperty
|
||||
|
||||
REM =========================================================== PRIVATE FUNCTIONS
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Function _PropertyGet(Optional ByVal psProperty As String _
|
||||
, Optional pvKey As Variant _
|
||||
)
|
||||
''' Return the named property
|
||||
''' Args:
|
||||
''' psProperty: the name of the property
|
||||
''' pvKey: the key to retrieve, numeric or string
|
||||
|
||||
Dim vItemMap As Variant ' Entry in the MapItems array
|
||||
Dim vArray As Variant ' To get Keys or Values
|
||||
Dim i As Long
|
||||
Dim cstThisSub As String
|
||||
Dim cstSubArgs As String
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
|
||||
cstThisSub = "SF_Dictionary.get" & psProperty
|
||||
If IsMissing(pvKey) Then cstSubArgs = "" Else cstSubArgs = "[Key]"
|
||||
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Select Case UCase(psProperty)
|
||||
Case UCase("Count")
|
||||
_PropertyGet = _MapSize - _MapRemoved
|
||||
Case UCase("Item")
|
||||
If Not SF_Utils._Validate(pvKey, "Key", V_STRING) Then GoTo Catch
|
||||
If Exists(pvKey) Then _PropertyGet = MapItems(MapKeys(pvKey)).Value Else _PropertyGet = Empty
|
||||
Case UCase("Keys"), UCase("Items")
|
||||
vArray = Array()
|
||||
If _MapSize - _MapRemoved - 1 >= 0 Then
|
||||
ReDim vArray(0 To (_MapSize - _MapRemoved - 1))
|
||||
i = -1
|
||||
For each vItemMap In MapItems()
|
||||
If Not IsEmpty(vItemMap) Then
|
||||
i = i + 1
|
||||
If UCase(psProperty) = "KEYS" Then vArray(i) = vItemMap.Key Else vArray(i) = vItemMap.Value
|
||||
End If
|
||||
Next vItemMap
|
||||
End If
|
||||
_PropertyGet = vArray
|
||||
End Select
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Dictionary._PropertyGet
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Function _Repr() As String
|
||||
''' Convert the Dictionary instance to a readable string, typically for debugging purposes (DebugPrint ...)
|
||||
''' Args:
|
||||
''' Return:
|
||||
''' "[Dictionary] (key1:value1, key2:value2, ...)
|
||||
|
||||
Dim sDict As String ' Return value
|
||||
Dim vKeys As Variant ' Array of keys
|
||||
Dim sKey As String ' Tempry key
|
||||
Dim vItem As Variant ' Tempry item
|
||||
Const cstDictEmpty = "[Dictionary] ()"
|
||||
Const cstDict = "[Dictionary]"
|
||||
Const cstMaxLength = 50 ' Maximum length for items
|
||||
Const cstSeparator = ", "
|
||||
|
||||
_Repr = ""
|
||||
|
||||
If Count = 0 Then
|
||||
sDict = cstDictEmpty
|
||||
Else
|
||||
sDict = cstDict & " ("
|
||||
vKeys = Keys
|
||||
For Each sKey in vKeys
|
||||
vItem = Item(sKey)
|
||||
sDict = sDict & sKey & ":" & SF_Utils._Repr(vItem, cstMaxLength) & cstSeparator
|
||||
Next sKey
|
||||
sDict = Left(sDict, Len(sDict) - Len(cstSeparator)) & ")" ' Suppress last comma
|
||||
End If
|
||||
|
||||
_Repr = sDict
|
||||
|
||||
End Function ' ScriptForge.SF_Dictionary._Repr
|
||||
|
||||
REM ============================================ END OF SCRIPTFORGE.SF_DICTIONARY
|
||||
</script:module>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,825 @@
|
||||
<?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_L10N" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
|
||||
REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
|
||||
REM === Full documentation is available on https://help.libreoffice.org/ ===
|
||||
REM =======================================================================================================================
|
||||
|
||||
Option Compatible
|
||||
Option ClassModule
|
||||
'Option Private Module
|
||||
|
||||
Option Explicit
|
||||
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
''' L10N (aka SF_L10N)
|
||||
''' ====
|
||||
''' Implementation of a Basic class for providing a number of services
|
||||
''' related to the translation of user interfaces into a huge number of languages
|
||||
''' with a minimal impact on the program code itself
|
||||
'''
|
||||
''' The design choices of this module are based on so-called PO-files
|
||||
''' PO-files (portable object files) have long been promoted in the free software industry
|
||||
''' as a mean of providing multilingual UIs. This is accomplished through the use of human-readable
|
||||
''' text files with a well defined structure that specifies, for any given language,
|
||||
''' the source language string and the localized string
|
||||
'''
|
||||
''' To read more about the PO format and its ecosystem of associated toolsets:
|
||||
''' https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html#PO-Files
|
||||
''' and, IMHO, a very good tutorial:
|
||||
''' http://pology.nedohodnik.net/doc/user/en_US/ch-about.html
|
||||
'''
|
||||
''' The main advantage of the PO format is the complete dissociation between the two
|
||||
''' very different profiles, i.e. the programmer and the translator(s).
|
||||
''' Being independent text files, one per language to support, the programmer may give away
|
||||
''' pristine PO template files (known as POT-files) for a translator to process.
|
||||
'''
|
||||
''' This class implements mainly 4 mechanisms:
|
||||
''' 1. AddText: for the programmer to build a set of words or sentences
|
||||
''' meant for being translated later
|
||||
''' 2. AddTextsFromDialog: to automatically execute AddText() on each fixed text of a dialog
|
||||
''' 3. ExportToPOTFile: All the above texts are exported into a pristine POT-file
|
||||
''' 4. GetText: At runtime get the text in the user language
|
||||
''' Note that the first two are optional: POT and PO-files may be built with a simple text editor
|
||||
'''
|
||||
''' Several instances of the L10N class may coexist
|
||||
' The constraint however is that each instance should find its PO-files
|
||||
''' in a separate directory
|
||||
''' PO-files must be named with the targeted locale: f.i. "en-US.po" or "fr-BE.po"
|
||||
'''
|
||||
''' Service invocation syntax
|
||||
''' CreateScriptService("L10N"[, FolderName[, Locale]])
|
||||
''' FolderName: the folder containing the PO-files (in SF_FileSystem.FileNaming notation)
|
||||
''' Locale: in the form la-CO (language-COUNTRY)
|
||||
''' Encoding: The character set that should be used (default = UTF-8)
|
||||
''' Use one of the Names listed in https://www.iana.org/assignments/character-sets/character-sets.xhtml
|
||||
''' Locale2: fallback Locale to select if Locale po file does not exist (typically "en-US")
|
||||
''' Encoding2: Encoding of the 2nd Locale file
|
||||
''' Service invocation examples:
|
||||
''' Dim myPO As Variant
|
||||
''' myPO = CreateScriptService("L10N") ' AddText, AddTextsFromDialog and ExportToPOTFile are allowed
|
||||
''' myPO = CreateScriptService("L10N", "C:\myPOFiles\", "fr-BE")
|
||||
''' 'All functionalities are available
|
||||
'''
|
||||
''' Detailed user documentation:
|
||||
''' https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03/sf_l10n.html?DbPAR=BASIC
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
REM =============================================================== PRIVATE TYPES
|
||||
|
||||
''' The recognized elements of an entry in a PO file are (other elements are ignored) :
|
||||
''' #. Extracted comments (given by the programmer to the translator)
|
||||
''' #, flag (the kde-format flag when the string contains tokens)
|
||||
''' msgctxt Context (to store an acronym associated with the message, this is a distortion of the norm)
|
||||
''' msgid untranslated-string
|
||||
''' msgstr translated-string
|
||||
''' NB: plural forms are not supported
|
||||
|
||||
Type POEntry
|
||||
Comment As String
|
||||
Flag As String
|
||||
Context As String
|
||||
MsgId As String
|
||||
MsgStr As String
|
||||
End Type
|
||||
|
||||
REM ================================================================== EXCEPTIONS
|
||||
|
||||
Const DUPLICATEKEYERROR = "DUPLICATEKEYERROR"
|
||||
|
||||
REM ============================================================= PRIVATE MEMBERS
|
||||
|
||||
Private [Me] As Object
|
||||
Private [_Parent] As Object
|
||||
Private ObjectType As String ' Must be "L10N"
|
||||
Private ServiceName As String
|
||||
Private _POFolder As String ' PO files container
|
||||
Private _Locale As String ' la-CO
|
||||
Private _POFile As String ' PO file in URL format
|
||||
Private _Encoding As String ' Used to open the PO file, default = UTF-8
|
||||
Private _Dictionary As Object ' SF_Dictionary
|
||||
|
||||
REM ===================================================== CONSTRUCTOR/DESTRUCTOR
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Sub Class_Initialize()
|
||||
Set [Me] = Nothing
|
||||
Set [_Parent] = Nothing
|
||||
ObjectType = "L10N"
|
||||
ServiceName = "ScriptForge.L10N"
|
||||
_POFolder = ""
|
||||
_Locale = ""
|
||||
_POFile = ""
|
||||
Set _Dictionary = Nothing
|
||||
End Sub ' ScriptForge.SF_L10N Constructor
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Sub Class_Terminate()
|
||||
|
||||
If Not IsNull(_Dictionary) Then Set _Dictionary = _Dictionary.Dispose()
|
||||
Call Class_Initialize()
|
||||
End Sub ' ScriptForge.SF_L10N Destructor
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Dispose() As Variant
|
||||
Call Class_Terminate()
|
||||
Set Dispose = Nothing
|
||||
End Function ' ScriptForge.SF_L10N Explicit Destructor
|
||||
|
||||
REM ================================================================== PROPERTIES
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get Folder() As String
|
||||
''' Returns the FolderName containing the PO-files expressed as given by the current FileNaming
|
||||
''' property of the SF_FileSystem service. Default = URL format
|
||||
''' May be empty
|
||||
''' Example:
|
||||
''' myPO.Folder
|
||||
|
||||
Folder = _PropertyGet("Folder")
|
||||
|
||||
End Property ' ScriptForge.SF_L10N.Folder
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get Languages() As Variant
|
||||
''' Returns a zero-based array listing all the BaseNames of the PO-files found in Folder,
|
||||
''' Example:
|
||||
''' myPO.Languages
|
||||
|
||||
Languages = _PropertyGet("Languages")
|
||||
|
||||
End Property ' ScriptForge.SF_L10N.Languages
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get Locale() As String
|
||||
''' Returns the currently active language-COUNTRY combination. May be empty
|
||||
''' Example:
|
||||
''' myPO.Locale
|
||||
|
||||
Locale = _PropertyGet("Locale")
|
||||
|
||||
End Property ' ScriptForge.SF_L10N.Locale
|
||||
|
||||
REM ===================================================================== METHODS
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function AddText(Optional ByVal Context As Variant _
|
||||
, Optional ByVal MsgId As Variant _
|
||||
, Optional ByVal Comment As Variant _
|
||||
, Optional ByVal MsgStr As Variant _
|
||||
) As Boolean
|
||||
''' Add a new entry in the list of localizable text strings
|
||||
''' Args:
|
||||
''' Context: when not empty, the key to retrieve the translated string via GetText. Default = ""
|
||||
''' MsgId: the untranslated string, i.e. the text appearing in the program code. Must not be empty
|
||||
''' The key to retrieve the translated string via GetText when Context is empty
|
||||
''' May contain placeholders (%1 ... %9) for dynamic arguments to be inserted in the text at run-time
|
||||
''' If the string spans multiple lines, insert escape sequences (\n) where relevant
|
||||
''' Comment: the so-called "extracted-comments" intended to inform/help translators
|
||||
''' If the string spans multiple lines, insert escape sequences (\n) where relevant
|
||||
''' MsgStr: (internal use only) the translated string
|
||||
''' If the string spans multiple lines, insert escape sequences (\n) where relevant
|
||||
''' Returns:
|
||||
''' True if successful
|
||||
''' Exceptions:
|
||||
''' DUPLICATEKEYERROR: such a key exists already
|
||||
''' Examples:
|
||||
''' myPO.AddText(, "This is a text to be included in a POT file")
|
||||
|
||||
Dim bAdd As Boolean ' Output buffer
|
||||
Dim sKey As String ' The key part of the new entry in the dictionary
|
||||
Dim vItem As POEntry ' The item part of the new entry in the dictionary
|
||||
Const cstPipe = "|" ' Pipe forbidden in MsgId's
|
||||
Const cstThisSub = "L10N.AddText"
|
||||
Const cstSubArgs = "[Context=""""], MsgId, [Comment=""""]"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
bAdd = False
|
||||
|
||||
Check:
|
||||
If IsMissing(Context) Or IsMissing(Context) Then Context = ""
|
||||
If IsMissing(Comment) Or IsMissing(Comment) Then Comment = ""
|
||||
If IsMissing(MsgStr) Or IsMissing(MsgStr) Then MsgStr = ""
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(Context, "Context", V_STRING) Then GoTo Finally
|
||||
If Not SF_Utils._Validate(MsgId, "MsgId", V_STRING) Then GoTo Finally
|
||||
If Not SF_Utils._Validate(Comment, "Comment", V_STRING) Then GoTo Finally
|
||||
If Not SF_Utils._Validate(MsgStr, "MsgStr", V_STRING) Then GoTo Finally
|
||||
End If
|
||||
If Len(MsgId) = 0 Then GoTo Finally
|
||||
|
||||
Try:
|
||||
If Len(Context) > 0 Then sKey = Context Else sKey = MsgId
|
||||
If _Dictionary.Exists(sKey) Then GoTo CatchDuplicate
|
||||
|
||||
With vItem
|
||||
.Comment = Comment
|
||||
If InStr(MsgId, "%") > 0 Then .Flag = "kde-format" Else .Flag = ""
|
||||
.Context = Replace(Context, cstPipe, " ")
|
||||
.MsgId = Replace(MsgId, cstPipe, " ")
|
||||
.MsgStr = MsgStr
|
||||
End With
|
||||
_Dictionary.Add(sKey, vItem)
|
||||
bAdd = True
|
||||
|
||||
Finally:
|
||||
AddText = bAdd
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
CatchDuplicate:
|
||||
SF_Exception.RaiseFatal(DUPLICATEKEYERROR, Iif(Len(Context) > 0, "Context", "MsgId"), sKey)
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_L10N.AddText
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function AddTextsFromDialog(Optional ByRef Dialog As Variant) As Boolean
|
||||
''' Add all fixed text strings of a dialog to the list of localizable text strings
|
||||
''' Added texts are:
|
||||
''' - the title of the dialog
|
||||
''' - the caption associated with next control types: Button, CheckBox, FixedLine, FixedText, GroupBox and RadioButton
|
||||
''' - the content of list- and comboboxes
|
||||
''' - the tip- or helptext displayed when the mouse is hovering the control
|
||||
''' The current method has method SFDialogs.SF_Dialog.GetTextsFromL10N as counterpart
|
||||
''' The targeted dialog must not be open when the current method is run
|
||||
''' Args:
|
||||
''' Dialog: a SFDialogs.Dialog service instance
|
||||
''' Returns:
|
||||
''' True when successful
|
||||
''' Examples:
|
||||
''' Dim myDialog As Object
|
||||
''' Set myDialog = CreateScriptService("SFDialogs.Dialog", "GlobalScope", "XrayTool", "DlgXray")
|
||||
''' myPO.AddTextsFromDialog(myDialog)
|
||||
|
||||
Dim bAdd As Boolean ' Return value
|
||||
Dim vControls As Variant ' Array of control names
|
||||
Dim sControl As String ' A single control name
|
||||
Dim oControl As Object ' SFDialogs.DialogControl
|
||||
Dim sText As String ' The text to insert in the dictionary
|
||||
Dim sDialogComment As String ' The prefix in the comment to insert in the dictionary for the dialog
|
||||
Dim sControlComment As String ' The prefix in the comment to insert in the dictionary for a control
|
||||
Dim vSource As Variant ' RowSource property of dialog control as an array
|
||||
Dim i As Long
|
||||
|
||||
Const cstThisSub = "L10N.AddTextsFromDialog"
|
||||
Const cstSubArgs = "Dialog"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
bAdd = False
|
||||
|
||||
Check:
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(Dialog, "Dialog", V_OBJECT, , , "DIALOG") Then GoTo Finally
|
||||
End If
|
||||
|
||||
Try:
|
||||
With Dialog
|
||||
' Store the title of the dialog
|
||||
sDialogComment = "Dialog => " & ._Container & " : " & ._Library & " : " & ._Name & " : "
|
||||
stext = .Caption
|
||||
If Len(sText) > 0 Then
|
||||
If Not _ReplaceText("", sText, sDialogComment & "Caption") Then GoTo Catch
|
||||
End If
|
||||
' Scan all controls
|
||||
vControls = .Controls()
|
||||
For Each sControl In vControls
|
||||
Set oControl = .Controls(sControl)
|
||||
sControlComment = sDialogComment & sControl & "."
|
||||
With oControl
|
||||
' Extract fixed texts
|
||||
sText = .Caption
|
||||
If Len(sText) > 0 Then
|
||||
If Not _ReplaceText("", sText, sControlComment & "Caption") Then GoTo Catch
|
||||
End If
|
||||
vSource = .RowSource ' List and comboboxes only
|
||||
If IsArray(vSource) Then
|
||||
For i = 0 To UBound(vSource)
|
||||
If Len(vSource(i)) > 0 Then
|
||||
If Not _ReplaceText("", vSource(i), sControlComment & "RowSource[" & i & "]") Then GoTo Catch
|
||||
End If
|
||||
Next i
|
||||
End If
|
||||
sText = .TipText
|
||||
If Len(sText) > 0 Then
|
||||
If Not _ReplaceText("", sText, sControlComment & "TipText") Then GoTo Catch
|
||||
End If
|
||||
End With
|
||||
Next sControl
|
||||
End With
|
||||
|
||||
bAdd = True
|
||||
|
||||
Finally:
|
||||
AddTextsFromDialog = bAdd
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_L10N.AddTextsFromDialog
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function ExportToPOTFile(Optional ByVal FileName As Variant _
|
||||
, Optional ByVal Header As Variant _
|
||||
, Optional ByVal Encoding As Variant _
|
||||
) As Boolean
|
||||
''' Export a set of untranslated strings as a POT file
|
||||
''' The set of strings has been built either by a succession of AddText() methods
|
||||
''' or by a successful invocation of the L10N service with the FolderName argument
|
||||
''' The generated file should pass successfully the "msgfmt --check 'the pofile'" GNU command
|
||||
''' Args:
|
||||
''' FileName: the complete file name to export to. If it exists, is overwritten without warning
|
||||
''' Header: Comments that will appear on top of the generated file. Do not include any leading "#"
|
||||
''' If the string spans multiple lines, insert escape sequences (\n) where relevant
|
||||
''' A standard header will be added anyway
|
||||
''' Encoding: The character set that should be used
|
||||
''' Use one of the Names listed in https://www.iana.org/assignments/character-sets/character-sets.xhtml
|
||||
''' Note that LibreOffice probably does not implement all existing sets
|
||||
''' Default = UTF-8
|
||||
''' Returns:
|
||||
''' True if successful
|
||||
''' Examples:
|
||||
''' myPO.ExportToPOTFile("myFile.pot", Header := "Top comment\nSecond line of top comment")
|
||||
|
||||
Dim bExport As Boolean ' Return value
|
||||
Dim oFile As Object ' Generated file handler
|
||||
Dim vLines As Variant ' Wrapped lines
|
||||
Dim sLine As String ' A single line
|
||||
Dim vItems As Variant ' Array of dictionary items
|
||||
Dim vItem As Variant ' POEntry type
|
||||
Const cstSharp = "# ", cstSharpDot = "#. ", cstFlag = "#, kde-format"
|
||||
Const cstTabSize = 4
|
||||
Const cstWrap = 70
|
||||
Const cstThisSub = "L10N.ExportToPOTFile"
|
||||
Const cstSubArgs = "FileName, [Header=""""], [Encoding=""UTF-8"""
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
bExport = False
|
||||
|
||||
Check:
|
||||
If IsMissing(Header) Or IsEmpty(Header) Then Header = ""
|
||||
If IsMissing(Encoding) Or IsEmpty(Encoding) Then Encoding = "UTF-8"
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._ValidateFile(FileName, "FileName") Then GoTo Finally
|
||||
If Not SF_Utils._Validate(Header, "Header", V_STRING) Then GoTo Finally
|
||||
If Not SF_Utils._Validate(Encoding, "Encoding", V_STRING) Then GoTo Finally
|
||||
End If
|
||||
|
||||
Try:
|
||||
Set oFile = SF_FileSystem.CreateTextFile(FileName, Overwrite := True, Encoding := Encoding)
|
||||
If Not IsNull(oFile) Then
|
||||
With oFile
|
||||
' Standard header
|
||||
.WriteLine(cstSharp)
|
||||
.WriteLine(cstSharp & "This pristine POT file has been generated by LibreOffice/ScriptForge")
|
||||
.WriteLine(cstSharp & "Full documentation is available on https://help.libreoffice.org/")
|
||||
' User header
|
||||
If Len(Header) > 0 Then
|
||||
.WriteLine(cstSharp)
|
||||
vLines = SF_String.Wrap(Header, cstWrap, cstTabSize)
|
||||
For Each sLine In vLines
|
||||
.WriteLine(cstSharp & Replace(sLine, SF_String.sfLF, ""))
|
||||
Next sLine
|
||||
End If
|
||||
' Standard header
|
||||
.WriteLine(cstSharp)
|
||||
.WriteLine("msgid """"")
|
||||
.WriteLine("msgstr """"")
|
||||
.WriteLine(SF_String.Quote("Project-Id-Version: PACKAGE VERSION\n"))
|
||||
.WriteLine(SF_String.Quote("Report-Msgid-Bugs-To: " _
|
||||
& "https://bugs.libreoffice.org/enter_bug.cgi?product=LibreOffice&bug_status=UNCONFIRMED&component=UI\n"))
|
||||
.WriteLine(SF_String.Quote("POT-Creation-Date: " & SF_STring.Represent(Now()) & "\n"))
|
||||
.WriteLine(SF_String.Quote("PO-Revision-Date: YYYY-MM-DD HH:MM:SS\n"))
|
||||
.WriteLine(SF_String.Quote("Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"))
|
||||
.WriteLine(SF_String.Quote("Language-Team: LANGUAGE <EMAIL@ADDRESS>\n"))
|
||||
.WriteLine(SF_String.Quote("Language: en_US\n"))
|
||||
.WriteLine(SF_String.Quote("MIME-Version: 1.0\n"))
|
||||
.WriteLine(SF_String.Quote("Content-Type: text/plain; charset=" & Encoding & "\n"))
|
||||
.WriteLine(SF_String.Quote("Content-Transfer-Encoding: 8bit\n"))
|
||||
.WriteLine(SF_String.Quote("Plural-Forms: nplurals=2; plural=n > 1;\n"))
|
||||
.WriteLine(SF_String.Quote("X-Generator: LibreOffice - ScriptForge\n"))
|
||||
.WriteLine(SF_String.Quote("X-Accelerator-Marker: ~\n"))
|
||||
' Individual translatable strings
|
||||
vItems = _Dictionary.Items()
|
||||
For Each vItem in vItems
|
||||
.WriteBlankLines(1)
|
||||
' Comments
|
||||
vLines = Split(vItem.Comment, "\n")
|
||||
For Each sLine In vLines
|
||||
.WriteLine(cstSharpDot & SF_String.ExpandTabs(SF_String.Unescape(sLine), cstTabSize))
|
||||
Next sLine
|
||||
' Flag
|
||||
If InStr(vItem.MsgId, "%") > 0 Then .WriteLine(cstFlag)
|
||||
' Context
|
||||
If Len(vItem.Context) > 0 Then
|
||||
.WriteLine("msgctxt " & SF_String.Quote(vItem.Context))
|
||||
End If
|
||||
' MsgId
|
||||
vLines = SF_String.Wrap(vItem.MsgId, cstWrap, cstTabSize)
|
||||
If UBound(vLines) = 0 Then
|
||||
.WriteLine("msgid " & SF_String.Quote(SF_String.Escape(vLines(0))))
|
||||
Else
|
||||
.WriteLine("msgid """"")
|
||||
For Each sLine in vLines
|
||||
.WriteLine(SF_String.Quote(SF_String.Escape(sLine)))
|
||||
Next sLine
|
||||
End If
|
||||
' MsgStr
|
||||
.WriteLine("msgstr """"")
|
||||
Next vItem
|
||||
.CloseFile()
|
||||
End With
|
||||
End If
|
||||
bExport = True
|
||||
|
||||
Finally:
|
||||
If Not IsNull(oFile) Then Set oFile = oFile.Dispose()
|
||||
ExportToPOTFile = bExport
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_L10N.ExportToPOTFile
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function GetProperty(Optional ByVal PropertyName As Variant) As Variant
|
||||
''' Return the actual value of the given property
|
||||
''' Args:
|
||||
''' PropertyName: the name of the property as a string
|
||||
''' Returns:
|
||||
''' The actual value of the property
|
||||
''' If the property does not exist, returns Null
|
||||
''' Exceptions:
|
||||
''' ARGUMENTERROR The property does not exist
|
||||
''' Examples:
|
||||
''' myL10N.GetProperty("MyProperty")
|
||||
|
||||
Const cstThisSub = "L10N.GetProperty"
|
||||
Const cstSubArgs = ""
|
||||
|
||||
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, "PropertyName", V_STRING, Properties()) Then GoTo Catch
|
||||
End If
|
||||
|
||||
Try:
|
||||
GetProperty = _PropertyGet(PropertyName)
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_L10N.GetProperty
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function GetText(Optional ByVal MsgId As Variant _
|
||||
, ParamArray pvArgs As Variant _
|
||||
) As String
|
||||
''' Get the translated string corresponding with the given argument
|
||||
''' Args:
|
||||
''' MsgId: the identifier of the string or the untranslated string
|
||||
''' Either - the untranslated text (MsgId)
|
||||
''' - the reference to the untranslated text (Context)
|
||||
''' - both (Context|MsgId) : the pipe character is essential
|
||||
''' pvArgs(): a list of arguments present as %1, %2, ... in the (un)translated string)
|
||||
''' to be substituted in the returned string
|
||||
''' Any type is admitted but only strings, numbers or dates are relevant
|
||||
''' Returns:
|
||||
''' The translated string
|
||||
''' If not found the MsgId string or the Context string
|
||||
''' Anyway the substitution is done
|
||||
''' Examples:
|
||||
''' myPO.GetText("This is a text to be included in a POT file")
|
||||
''' ' Ceci est un text à inclure dans un fichier POT
|
||||
|
||||
Dim sText As String ' Output buffer
|
||||
Dim sContext As String ' Context part of argument
|
||||
Dim sMsgId As String ' MsgId part of argument
|
||||
Dim vItem As POEntry ' Entry in the dictionary
|
||||
Dim vMsgId As Variant ' MsgId split on pipe
|
||||
Dim sKey As String ' Key of dictionary
|
||||
Dim sPercent As String ' %1, %2, ... placeholders
|
||||
Dim i As Long
|
||||
Const cstPipe = "|"
|
||||
Const cstThisSub = "L10N.GetText"
|
||||
Const cstSubArgs = "MsgId, [Arg0, Arg1, ...]"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
sText = ""
|
||||
|
||||
Check:
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(MsgId, "MsgId", V_STRING) Then GoTo Finally
|
||||
End If
|
||||
If Len(Trim(MsgId)) = 0 Then GoTo Finally
|
||||
sText = MsgId
|
||||
|
||||
Try:
|
||||
' Find and load entry from dictionary
|
||||
If Left(MsgId, 1) = cstPipe then MsgId = Mid(MsgId, 2)
|
||||
vMsgId = Split(MsgId, cstPipe)
|
||||
sKey = vMsgId(0)
|
||||
If Not _Dictionary.Exists(sKey) Then ' Not found
|
||||
If UBound(vMsgId) = 0 Then sText = vMsgId(0) Else sText = Mid(MsgId, InStr(MsgId, cstPipe) + 1)
|
||||
Else
|
||||
vItem = _Dictionary.Item(sKey)
|
||||
If Len(vItem.MsgStr) > 0 Then sText = vItem.MsgStr Else sText = vItem.MsgId
|
||||
End If
|
||||
|
||||
' Substitute %i placeholders
|
||||
For i = UBound(pvArgs) To 0 Step -1 ' Go downwards to not have a limit in number of args
|
||||
sPercent = "%" & (i + 1)
|
||||
sText = Replace(sText, sPercent, SF_String.Represent(pvArgs(i)))
|
||||
Next i
|
||||
|
||||
Finally:
|
||||
GetText = sText
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_L10N.GetText
|
||||
|
||||
REM - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
Public Function _(Optional ByVal MsgId As Variant _
|
||||
, ParamArray pvArgs As Variant _
|
||||
) As String
|
||||
''' Get the translated string corresponding with the given argument
|
||||
''' Alias of GetText() - See above
|
||||
''' Examples:
|
||||
''' myPO._("This is a text to be included in a POT file")
|
||||
''' ' Ceci est un text à inclure dans un fichier POT
|
||||
|
||||
Dim sText As String ' Output buffer
|
||||
Dim sPercent As String ' %1, %2, ... placeholders
|
||||
Dim i As Long
|
||||
Const cstPipe = "|"
|
||||
Const cstThisSub = "L10N._"
|
||||
Const cstSubArgs = "MsgId, [Arg0, Arg1, ...]"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
sText = ""
|
||||
|
||||
Check:
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(MsgId, "MsgId", V_STRING) Then GoTo Finally
|
||||
End If
|
||||
If Len(Trim(MsgId)) = 0 Then GoTo Finally
|
||||
|
||||
Try:
|
||||
' Find and load entry from dictionary
|
||||
sText = GetText(MsgId)
|
||||
|
||||
' Substitute %i placeholders - done here, not in GetText(), because # of arguments is undefined
|
||||
For i = 0 To UBound(pvArgs)
|
||||
sPercent = "%" & (i + 1)
|
||||
sText = Replace(sText, sPercent, SF_String.Represent(pvArgs(i)))
|
||||
Next i
|
||||
|
||||
Finally:
|
||||
_ = sText
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_L10N._
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Methods() As Variant
|
||||
''' Return the list of public methods of the L10N service as an array
|
||||
|
||||
Methods = Array( _
|
||||
"AddText" _
|
||||
, "ExportToPOTFile" _
|
||||
, "GetText" _
|
||||
, "AddTextsFromDialog" _
|
||||
, "_" _
|
||||
)
|
||||
|
||||
End Function ' ScriptForge.SF_L10N.Methods
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Properties() As Variant
|
||||
''' Return the list or properties of the Timer class as an array
|
||||
|
||||
Properties = Array( _
|
||||
"Folder" _
|
||||
, "Languages" _
|
||||
, "Locale" _
|
||||
)
|
||||
|
||||
End Function ' ScriptForge.SF_L10N.Properties
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function SetProperty(Optional ByVal PropertyName As Variant _
|
||||
, Optional ByRef Value As Variant _
|
||||
) As Boolean
|
||||
''' Set a new value to the given property
|
||||
''' Args:
|
||||
''' PropertyName: the name of the property as a string
|
||||
''' Value: its new value
|
||||
''' Exceptions
|
||||
''' ARGUMENTERROR The property does not exist
|
||||
|
||||
Const cstThisSub = "L10N.SetProperty"
|
||||
Const cstSubArgs = "PropertyName, Value"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
SetProperty = False
|
||||
|
||||
Check:
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(PropertyName, "PropertyName", V_STRING, Properties()) Then GoTo Catch
|
||||
End If
|
||||
|
||||
Try:
|
||||
Select Case UCase(PropertyName)
|
||||
Case Else
|
||||
End Select
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_L10N.SetProperty
|
||||
|
||||
REM =========================================================== PRIVATE FUNCTIONS
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Sub _Initialize(ByVal psPOFile As String _
|
||||
, ByVal Encoding As String _
|
||||
)
|
||||
''' Completes initialization of the current instance requested from CreateScriptService()
|
||||
''' Load the POFile in the dictionary, otherwise leave the dictionary empty
|
||||
''' Args:
|
||||
''' psPOFile: the file to load the translated strings from
|
||||
''' Encoding: The character set that should be used. Default = UTF-8
|
||||
|
||||
Dim oFile As Object ' PO file handler
|
||||
Dim sContext As String ' Collected context string
|
||||
Dim sMsgId As String ' Collected untranslated string
|
||||
Dim sComment As String ' Collected comment string
|
||||
Dim sMsgStr As String ' Collected translated string
|
||||
Dim sLine As String ' Last line read
|
||||
Dim iContinue As Integer ' 0 = None, 1 = MsgId, 2 = MsgStr
|
||||
Const cstMsgId = 1, cstMsgStr = 2
|
||||
|
||||
Try:
|
||||
' Initialize dictionary anyway
|
||||
Set _Dictionary = SF_Services.CreateScriptService("Dictionary")
|
||||
Set _Dictionary.[_Parent] = [Me]
|
||||
|
||||
' Load PO file
|
||||
If Len(psPOFile) > 0 Then
|
||||
With SF_FileSystem
|
||||
_POFolder = ._ConvertToUrl(.GetParentFolderName(psPOFile))
|
||||
_Locale = .GetBaseName(psPOFile)
|
||||
_POFile = ._ConvertToUrl(psPOFile)
|
||||
End With
|
||||
' Load PO file
|
||||
Set oFile = SF_FileSystem.OpenTextFile(psPOFile, IOMode := SF_FileSystem.ForReading, Encoding := Encoding)
|
||||
If Not IsNull(oFile) Then
|
||||
With oFile
|
||||
' The PO file is presumed valid => syntax check is not very strict
|
||||
sContext = "" : sMsgId = "" : sComment = "" : sMsgStr = ""
|
||||
Do While Not .AtEndOfStream
|
||||
sLine = Trim(.ReadLine())
|
||||
' Trivial examination of line header
|
||||
Select Case True
|
||||
Case sLine = ""
|
||||
If Len(sMsgId) > 0 Then AddText(sContext, sMsgId, sComment, sMsgStr)
|
||||
sContext = "" : sMsgId = "" : sComment = "" : sMsgStr = ""
|
||||
iContinue = 0
|
||||
Case Left(sLine, 3) = "#. "
|
||||
sComment = sComment & Iif(Len(sComment) > 0, "\n", "") & Trim(Mid(sLine, 4))
|
||||
iContinue = 0
|
||||
Case Left(sLine, 8) = "msgctxt "
|
||||
sContext = SF_String.Unquote(Trim(Mid(sLine, 9)))
|
||||
iContinue = 0
|
||||
Case Left(sLine, 6) = "msgid "
|
||||
sMsgId = SF_String.Unquote(Trim(Mid(sLine, 7)))
|
||||
iContinue = cstMsgId
|
||||
Case Left(sLine, 7) = "msgstr "
|
||||
sMsgStr = sMsgStr & SF_String.Unquote(Trim(Mid(sLine, 8)))
|
||||
iContinue = cstMsgStr
|
||||
Case Left(sLine, 1) = """"
|
||||
If iContinue = cstMsgId Then
|
||||
sMsgId = sMsgId & SF_String.Unquote(sLine)
|
||||
ElseIf iContinue = cstMsgStr Then
|
||||
sMsgStr = sMsgStr & SF_String.Unquote(sLine)
|
||||
Else
|
||||
iContinue = 0
|
||||
End If
|
||||
Case Else ' Skip line
|
||||
iContinue = 0
|
||||
End Select
|
||||
Loop
|
||||
' Be sure to store the last entry
|
||||
If Len(sMsgId) > 0 Then AddText(sContext, sMsgId, sComment, sMsgStr)
|
||||
.CloseFile()
|
||||
Set oFile = .Dispose()
|
||||
End With
|
||||
End If
|
||||
Else
|
||||
_POFolder = ""
|
||||
_Locale = ""
|
||||
_POFile = ""
|
||||
End If
|
||||
|
||||
Finally:
|
||||
Exit Sub
|
||||
End Sub ' ScriptForge.SF_L10N._Initialize
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Function _PropertyGet(Optional ByVal psProperty As String)
|
||||
''' Return the value of the named property
|
||||
''' Args:
|
||||
''' psProperty: the name of the property
|
||||
|
||||
Dim vFiles As Variant ' Array of PO-files
|
||||
Dim i As Long
|
||||
Dim cstThisSub As String
|
||||
Dim cstSubArgs As String
|
||||
|
||||
cstThisSub = "SF_L10N.get" & psProperty
|
||||
cstSubArgs = ""
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
With SF_FileSystem
|
||||
Select Case psProperty
|
||||
Case "Folder"
|
||||
If Len(_POFolder) > 0 Then _PropertyGet = ._ConvertFromUrl(_POFolder) Else _PropertyGet = ""
|
||||
Case "Languages"
|
||||
If Len(_POFolder) > 0 Then
|
||||
vFiles = .Files(._ConvertFromUrl(_POFolder), "*.po")
|
||||
For i = 0 To UBound(vFiles)
|
||||
vFiles(i) = SF_FileSystem.GetBaseName(vFiles(i))
|
||||
Next i
|
||||
Else
|
||||
vFiles = Array()
|
||||
End If
|
||||
_PropertyGet = vFiles
|
||||
Case "Locale"
|
||||
_PropertyGet = _Locale
|
||||
Case Else
|
||||
_PropertyGet = Null
|
||||
End Select
|
||||
End With
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
End Function ' ScriptForge.SF_L10N._PropertyGet
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Function _ReplaceText(ByVal psContext As String _
|
||||
, ByVal psMsgId As String _
|
||||
, ByVal psComment As String _
|
||||
) As Boolean
|
||||
''' When the entry in the dictionary does not yet exist, equivalent to AddText
|
||||
''' When it exists already, extend the existing comment with the psComment argument
|
||||
''' Used from AddTextsFromDialog to manage identical strings without raising errors,
|
||||
''' e.g. when multiple dialogs have the same "Close" button
|
||||
|
||||
Dim bAdd As Boolean ' Return value
|
||||
Dim sKey As String ' The key part of an entry in the dictionary
|
||||
Dim vItem As POEntry ' The item part of the new entry in the dictionary
|
||||
|
||||
Try:
|
||||
bAdd = False
|
||||
If Len(psContext) > 0 Then sKey = psContext Else sKey = psMsgId
|
||||
If _Dictionary.Exists(sKey) Then
|
||||
' Load the entry, adapt comment and rewrite
|
||||
vItem = _Dictionary.Item(sKey)
|
||||
If Len(vItem.Comment) = 0 Then vItem.Comment = psComment Else vItem.Comment = vItem.Comment & "\n" & psComment
|
||||
bAdd = _Dictionary.ReplaceItem(sKey, vItem)
|
||||
Else
|
||||
' Add a new entry as usual
|
||||
bAdd = AddText(psContext, psMsgId, psComment)
|
||||
End If
|
||||
|
||||
Finally:
|
||||
_ReplaceText = bAdd
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_L10N._ReplaceText
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Function _Repr() As String
|
||||
''' Convert the L10N instance to a readable string, typically for debugging purposes (DebugPrint ...)
|
||||
''' Args:
|
||||
''' Return:
|
||||
''' "[L10N]: PO file"
|
||||
|
||||
_Repr = "[L10N]: " & _POFile
|
||||
|
||||
End Function ' ScriptForge.SF_L10N._Repr
|
||||
|
||||
REM ============================================ END OF SCRIPTFORGE.SF_L10N
|
||||
</script:module>
|
||||
@@ -0,0 +1,451 @@
|
||||
<?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_Platform" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
|
||||
REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
|
||||
REM === Full documentation is available on https://help.libreoffice.org/ ===
|
||||
REM =======================================================================================================================
|
||||
|
||||
Option Compatible
|
||||
Option Explicit
|
||||
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
''' SF_Platform
|
||||
''' ===========
|
||||
''' Singleton class implementing the "ScriptForge.Platform" service
|
||||
''' Implemented as a usual Basic module
|
||||
'''
|
||||
''' A collection of properties about the execution environment:
|
||||
''' - HW platform
|
||||
''' - Operating System
|
||||
''' - current user
|
||||
''' - LibreOffice version
|
||||
'''
|
||||
''' Service invocation example:
|
||||
''' Dim platform As Variant
|
||||
''' platform = CreateScriptService("Platform")
|
||||
'''
|
||||
''' Detailed user documentation:
|
||||
''' https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03/sf_platform.html?DbPAR=BASIC
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
REM ================================================================== EXCEPTIONS
|
||||
|
||||
REM ============================================================ MODULE CONSTANTS
|
||||
|
||||
REM ===================================================== CONSTRUCTOR/DESTRUCTOR
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Dispose() As Variant
|
||||
Set Dispose = Nothing
|
||||
End Function ' ScriptForge.SF_Array Explicit destructor
|
||||
|
||||
REM ================================================================== PROPERTIES
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get Architecture() As String
|
||||
''' Returns the actual bit architecture
|
||||
''' Example:
|
||||
''' MsgBox platform.Architecture ' 64bit
|
||||
Architecture = _PropertyGet("Architecture")
|
||||
End Property ' ScriptForge.SF_Platform.Architecture (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get ComputerName() As String
|
||||
''' Returns the computer's network name
|
||||
''' Example:
|
||||
''' MsgBox platform.ComputerName
|
||||
ComputerName = _PropertyGet("ComputerName")
|
||||
End Property ' ScriptForge.SF_Platform.ComputerName (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get CPUCount() As Integer
|
||||
''' Returns the number of Central Processor Units
|
||||
''' Example:
|
||||
''' MsgBox platform.CPUCount ' 4
|
||||
CPUCount = _PropertyGet("CPUCount")
|
||||
End Property ' ScriptForge.SF_Platform.CPUCount (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get CurrentUser() As String
|
||||
''' Returns the name of logged in user
|
||||
''' Example:
|
||||
''' MsgBox platform.CurrentUser
|
||||
CurrentUser = _PropertyGet("CurrentUser")
|
||||
End Property ' ScriptForge.SF_Platform.CurrentUser (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get Extensions() As Variant
|
||||
''' Returns the list of availableeExtensions as an unsorted array of unique strings
|
||||
''' To get the list sorted, use SF_Array.Sort()
|
||||
''' Example:
|
||||
''' myExtensionsList = platform.Extensions
|
||||
Extensions = _PropertyGet("Extensions")
|
||||
End Property ' ScriptForge.SF_Platform.Extensions (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get FilterNames() As Variant
|
||||
''' Returns the list of available document import and export filter names as an unsorted array of unique strings
|
||||
''' To get the list sorted, use SF_Array.Sort()
|
||||
''' Example:
|
||||
''' myFilterNamesList = platform.FilterNames
|
||||
FilterNames = _PropertyGet("FilterNames")
|
||||
End Property ' ScriptForge.SF_Platform.FilterNames (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get Fonts() As Variant
|
||||
''' Returns the list of available fonts as an unsorted array of unique strings
|
||||
''' To get the list sorted, use SF_Array.Sort()
|
||||
''' Example:
|
||||
''' myFontsList = platform.Fonts
|
||||
Fonts = _PropertyGet("Fonts")
|
||||
End Property ' ScriptForge.SF_Platform.Fonts (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get FormatLocale() As String
|
||||
''' Returns the locale used for number and date formats, combining language-COUNTRY (la-CO)
|
||||
''' Example:
|
||||
''' MsgBox platform.FormatLocale
|
||||
FormatLocale = _PropertyGet("FormatLocale")
|
||||
End Property ' ScriptForge.SF_Platform.FormatLocale (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get Locale() As String
|
||||
''' Returns the locale of the operating system, combining language-COUNTRY (la-CO)
|
||||
''' Example:
|
||||
''' MsgBox platform.Locale
|
||||
Locale = _PropertyGet("Locale")
|
||||
End Property ' ScriptForge.SF_Platform.Locale (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get Machine() As String
|
||||
''' Returns the machine type like 'i386' or 'x86_64'
|
||||
''' Example:
|
||||
''' MsgBox platform.Machine
|
||||
Machine = _PropertyGet("Machine")
|
||||
End Property ' ScriptForge.SF_Platform.Machine (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get ObjectType As String
|
||||
''' Only to enable object representation
|
||||
ObjectType = "SF_Platform"
|
||||
End Property ' ScriptForge.SF_Platform.ObjectType
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get OfficeLocale() As String
|
||||
''' Returns the locale of the user interface, combining language-COUNTRY (la-CO)
|
||||
''' Example:
|
||||
''' MsgBox platform.OfficeLocale
|
||||
OfficeLocale = _PropertyGet("OfficeLocale")
|
||||
End Property ' ScriptForge.SF_Platform.OfficeLocale (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get OfficeVersion() As String
|
||||
''' Returns the office software version in the form 'LibreOffice w.x.y.z (The Document Foundation)'
|
||||
''' Example:
|
||||
''' MsgBox platform.OfficeVersion
|
||||
OfficeVersion = _PropertyGet("OfficeVersion")
|
||||
End Property ' ScriptForge.SF_Platform.OfficeVersion (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get OSName() As String
|
||||
''' Returns the name of the operating system like 'Linux' or 'Windows'
|
||||
''' Example:
|
||||
''' MsgBox platform.OSName
|
||||
OSName = _PropertyGet("OSName")
|
||||
End Property ' ScriptForge.SF_Platform.OSName (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get OSPlatform() As String
|
||||
''' Returns a single string identifying the underlying platform with as much useful and human-readable information as possible
|
||||
''' Example:
|
||||
''' MsgBox platform.OSPlatform ' Linux-4.15.0-117-generic-x86_64-with-Ubuntu-18.04-bionic
|
||||
OSPlatform = _PropertyGet("OSPlatform")
|
||||
End Property ' ScriptForge.SF_Platform.OSPlatform (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get OSRelease() As String
|
||||
''' Returns the operating system's release
|
||||
''' Example:
|
||||
''' MsgBox platform.OSRelease ' 4.15.0-117-generic
|
||||
OSRelease = _PropertyGet("OSRelease")
|
||||
End Property ' ScriptForge.SF_Platform.OSRelease (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get OSVersion() As String
|
||||
''' Returns the name of the operating system build or version
|
||||
''' Example:
|
||||
''' MsgBox platform.OSVersion ' #118-Ubuntu SMP Fri Sep 4 20:02:41 UTC 2020
|
||||
OSVersion = _PropertyGet("OSVersion")
|
||||
End Property ' ScriptForge.SF_Platform.OSVersion (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get Printers() As Variant
|
||||
''' Returns the list of available printers type as a zero-based array
|
||||
''' The default printer is put in the 1st position in the list (index = 0)
|
||||
''' Example:
|
||||
''' MsgBox join(platform.Printers, ",")
|
||||
Printers = _PropertyGet("Printers")
|
||||
End Property ' ScriptForge.SF_Platform.Printers (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get Processor() As String
|
||||
''' Returns the (real) processor name, e.g. 'amdk6'. Might return the same value as Machine
|
||||
''' Example:
|
||||
''' MsgBox platform.Processor
|
||||
Processor = _PropertyGet("Processor")
|
||||
End Property ' ScriptForge.SF_Platform.Processor (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get PythonVersion() As String
|
||||
''' Returns the Python version as string 'Python major.minor.patchlevel'
|
||||
''' Example:
|
||||
''' MsgBox platform.PythonVersion ' Python 3.7.7
|
||||
PythonVersion = _PropertyGet("PythonVersion")
|
||||
End Property ' ScriptForge.SF_Platform.PythonVersion (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get ServiceName As String
|
||||
''' Internal use
|
||||
ServiceName = "ScriptForge.Platform"
|
||||
End Property ' ScriptForge.SF_Platform.ServiceName
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get SystemLocale() As String
|
||||
''' Returns the locale of the operating system, combining language-COUNTRY (la-CO)
|
||||
''' Example:
|
||||
''' MsgBox platform.SystemLocale
|
||||
SystemLocale = _PropertyGet("SystemLocale")
|
||||
End Property ' ScriptForge.SF_Platform.SystemLocale (get)
|
||||
|
||||
REM ===================================================================== METHODS
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function GetProperty(Optional ByVal PropertyName As Variant) As Variant
|
||||
''' Return the actual value of the given property
|
||||
''' Args:
|
||||
''' PropertyName: the name of the property as a string
|
||||
''' Returns:
|
||||
''' The actual value of the property
|
||||
''' If the property does not exist, returns Null
|
||||
''' Exceptions:
|
||||
''' ARGUMENTERROR The property does not exist
|
||||
|
||||
Const cstThisSub = "Platform.GetProperty"
|
||||
Const cstSubArgs = ""
|
||||
|
||||
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, "PropertyName", V_STRING, Properties()) Then GoTo Catch
|
||||
End If
|
||||
|
||||
Try:
|
||||
GetProperty = _PropertyGet(PropertyName)
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Platform.GetProperty
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Methods() As Variant
|
||||
''' Return the list of public methods of the Model service as an array
|
||||
|
||||
Methods = Array( _
|
||||
)
|
||||
|
||||
End Function ' ScriptForge.SF_Platform.Methods
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Properties() As Variant
|
||||
''' Return the list or properties of the Platform class as an array
|
||||
|
||||
Properties = Array( _
|
||||
"Architecture" _
|
||||
, "ComputerName" _
|
||||
, "CPUCount" _
|
||||
, "CurrentUser" _
|
||||
, "Extensions" _
|
||||
, "FilterNames" _
|
||||
, "Fonts" _
|
||||
, "FormatLocale" _
|
||||
, "Locale" _
|
||||
, "Machine" _
|
||||
, "OfficeLocale" _
|
||||
, "OfficeVersion" _
|
||||
, "OSName" _
|
||||
, "OSPlatform" _
|
||||
, "OSRelease" _
|
||||
, "OSVersion" _
|
||||
, "Printers" _
|
||||
, "Processor" _
|
||||
, "PythonVersion" _
|
||||
, "SystemLocale" _
|
||||
)
|
||||
|
||||
End Function ' ScriptForge.SF_Platform.Properties
|
||||
|
||||
REM =========================================================== PRIVATE FUNCTIONS
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function _GetPrinters() as Variant
|
||||
''' Returns the list of available printers.
|
||||
''' The default printer is put in the 1st position (index = 0)
|
||||
|
||||
Dim oPrinterServer As Object ' com.sun.star.awt.PrinterServer
|
||||
Dim vPrinters As Variant ' Array of printer names
|
||||
Dim sDefaultPrinter As String ' The default printer
|
||||
Dim lDefault As Long ' Initial position of the default printer in the list
|
||||
|
||||
On Local Error GoTo Catch ' Prevent any error
|
||||
vPrinters = Array()
|
||||
|
||||
Try:
|
||||
' Find printers
|
||||
Set oPrinterServer = SF_Utils._GetUNOService("PrinterServer")
|
||||
With oPrinterServer
|
||||
vPrinters = .getPrinterNames()
|
||||
sDefaultPrinter = .getDefaultPrinterName()
|
||||
End With
|
||||
|
||||
' Put the default printer on top of the list
|
||||
If Len(sDefaultPrinter) > 0 Then
|
||||
lDefault = SF_Array.IndexOf(vPrinters, sDefaultPrinter, CaseSensitive := True)
|
||||
If lDefault > 0 Then ' Invert 2 printers
|
||||
vPrinters(lDefault) = vPrinters(0)
|
||||
vPrinters(0) = sDefaultPrinter
|
||||
End If
|
||||
End If
|
||||
|
||||
Finally:
|
||||
_GetPrinters() = vPrinters()
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Platform._GetPrinters
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function _GetProductName() as String
|
||||
''' Returns Office product and version numbers found in configuration registry
|
||||
''' Derived from the Tools library
|
||||
|
||||
Dim oProdNameAccess as Object ' configmgr.RootAccess
|
||||
Dim sProdName as String
|
||||
Dim sVersion as String
|
||||
Dim sVendor As String
|
||||
|
||||
On Local Error GoTo Catch ' Prevent any error
|
||||
_GetProductName = ""
|
||||
|
||||
Try:
|
||||
Set oProdNameAccess = SF_Utils._GetRegistryKeyContent("org.openoffice.Setup/Product")
|
||||
|
||||
sProdName = oProdNameAccess.ooName
|
||||
sVersion = oProdNameAccess.ooSetupVersionAboutBox
|
||||
sVendor = oProdNameAccess.ooVendor
|
||||
|
||||
_GetProductName = sProdName & " " & sVersion & " (" & sVendor & ")"
|
||||
|
||||
Finally:
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Platform._GetProductName
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Function _PropertyGet(Optional ByVal psProperty As String) As Variant
|
||||
''' Return the value of the named property
|
||||
''' Args:
|
||||
''' psProperty: the name of the property
|
||||
|
||||
Dim sOSName As String ' Operating system
|
||||
Dim oLocale As Object ' com.sun.star.lang.Locale
|
||||
Dim oPrinterServer As Object ' com.sun.star.awt.PrinterServer
|
||||
Dim oToolkit As Object ' com.sun.star.awt.Toolkit
|
||||
Dim oDevice As Object ' com.sun.star.awt.XDevice
|
||||
Dim oFilterFactory As Object ' com.sun.star.document.FilterFactory
|
||||
Dim oFontDescriptors As Variant ' Array of com.sun.star.awt.FontDescriptor
|
||||
Dim sFonts As String ' Comma-separated list of fonts
|
||||
Dim sFont As String ' A single font name
|
||||
Dim vExtensionsList As Variant ' Array of extension descriptors
|
||||
Dim sExtensions As String ' Comma separated list of extensions
|
||||
Dim sExtension As String ' A single extension name
|
||||
Dim i As Long
|
||||
|
||||
Const cstPyHelper = "$" & "_SF_Platform"
|
||||
Dim cstThisSub As String
|
||||
Const cstSubArgs = ""
|
||||
|
||||
cstThisSub = "Platform.get" & psProperty
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Select Case psProperty
|
||||
Case "Architecture", "ComputerName", "CPUCount", "CurrentUser", "Machine" _
|
||||
, "OSPlatform", "OSRelease", "OSVersion", "Processor", "PythonVersion"
|
||||
With ScriptForge.SF_Session
|
||||
_PropertyGet = .ExecutePythonScript(.SCRIPTISSHARED, _SF_.PythonHelper & cstPyHelper, psProperty)
|
||||
End With
|
||||
Case "Extensions"
|
||||
Set vExtensionsList = SF_Utils._GetUnoService("PackageInformationProvider").ExtensionList
|
||||
sExtensions = ""
|
||||
For i = 0 To UBound(vExtensionsList)
|
||||
sExtensions = sExtensions & "," & vExtensionsList(i)(0)
|
||||
Next i
|
||||
If Len(sExtensions) > 0 Then _PropertyGet = Split(Mid(sExtensions, 2), ",") Else _PropertyGet = Array()
|
||||
Case "FilterNames"
|
||||
Set oFilterFactory = SF_Utils._GetUNOService("FilterFactory")
|
||||
_PropertyGet = oFilterFactory.getElementNames()
|
||||
Case "Fonts"
|
||||
Set oToolkit = SF_Utils._GetUnoService("Toolkit")
|
||||
Set oDevice = oToolkit.createScreenCompatibleDevice(0, 0)
|
||||
oFontDescriptors = oDevice.FontDescriptors()
|
||||
sFonts = ","
|
||||
' Select only not yet registered fonts
|
||||
For i = 0 To UBound(oFontDescriptors)
|
||||
sFont = oFontDescriptors(i).Name
|
||||
If InStr(1, sFonts, "," & sFont & ",", 0) = 0 Then sFonts = sFonts & sFont & "," ' Case-sensitive comparison
|
||||
Next i
|
||||
' Remove leading and trailing commas
|
||||
If Len(sFonts) > 1 Then _PropertyGet = Split(Mid(sFonts, 2, Len(sFonts) - 2), ",") Else _PropertyGet = Array()
|
||||
Case "FormatLocale"
|
||||
Set oLocale = SF_Utils._GetUNOService("FormatLocale")
|
||||
_PropertyGet = oLocale.Language & "-" & oLocale.Country
|
||||
Case "OfficeLocale"
|
||||
Set oLocale = SF_Utils._GetUNOService("OfficeLocale")
|
||||
_PropertyGet = oLocale.Language & "-" & oLocale.Country
|
||||
Case "OfficeVersion"
|
||||
_PropertyGet = _GetProductName()
|
||||
Case "OSName"
|
||||
' Calc INFO function preferred to Python script to avoid ScriptForge initialization risks when Python is not installed
|
||||
sOSName = _SF_.OSName
|
||||
If sOSName = "" Then
|
||||
sOSName = SF_Session.ExecuteCalcFunction("INFO", "system")
|
||||
Select Case sOSName
|
||||
Case "WNT" : sOSName = "Windows"
|
||||
Case "MACOSX" : sOSName = "macOS"
|
||||
Case "LINUX" : sOSName = "Linux"
|
||||
Case "SOLARIS" : sOSName = "Solaris"
|
||||
Case Else : sOSName = SF_String.Capitalize(sOSName)
|
||||
End Select
|
||||
EndIf
|
||||
_PropertyGet = sOSName
|
||||
Case "Printers"
|
||||
_PropertyGet = _GetPrinters()
|
||||
Case "SystemLocale", "Locale"
|
||||
Set oLocale = SF_Utils._GetUNOService("SystemLocale")
|
||||
_PropertyGet = oLocale.Language & "-" & oLocale.Country
|
||||
Case Else
|
||||
_PropertyGet = Null
|
||||
End Select
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
End Function ' ScriptForge.SF_Platform._PropertyGet
|
||||
|
||||
REM ============================================ END OF SCRIPTFORGE.SF_PLATFORM
|
||||
</script:module>
|
||||
@@ -0,0 +1,967 @@
|
||||
<?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_PythonHelper" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
|
||||
REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
|
||||
REM === Full documentation is available on https://help.libreoffice.org/ ===
|
||||
REM =======================================================================================================================
|
||||
|
||||
Option Compatible
|
||||
Option Explicit
|
||||
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
''' SF_PythonHelper (aka Basic)
|
||||
''' ===============
|
||||
''' Singleton class implementing the "ScriptForge.Basic" service
|
||||
''' Implemented as a usual Basic module
|
||||
'''
|
||||
''' The "Basic" service must be called ONLY from a PYTHON script
|
||||
''' Service invocations: Next Python code lines are equivalent:
|
||||
''' bas = CreateScriptService('ScriptForge.Basic')
|
||||
''' bas = CreateScriptService('Basic')
|
||||
'''
|
||||
''' This service proposes a collection of methods to be executed in a Python context
|
||||
''' to simulate the exact behaviour of the identical Basic builtin method.
|
||||
''' Typical example:
|
||||
''' bas.MsgBox('This has to be displayed in a message box')
|
||||
'''
|
||||
''' The service includes also an agnostic "Python Dispatcher" function.
|
||||
''' It dispatches Python script requests to execute Basic services to the
|
||||
''' appropriate properties and methods via dynamic call techniques
|
||||
'''
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
REM ================================================================== EXCEPTIONS
|
||||
|
||||
REM ============================================================ MODULE CONSTANTS
|
||||
|
||||
REM ===================================================== CONSTRUCTOR/DESTRUCTOR
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Dispose() As Variant
|
||||
Set Dispose = Nothing
|
||||
End Function ' ScriptForge.SF_PythonHelper Explicit destructor
|
||||
|
||||
REM ================================================================== PROPERTIES
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get ObjectType As String
|
||||
''' Only to enable object representation
|
||||
ObjectType = "SF_PythonHelper"
|
||||
End Property ' ScriptForge.SF_PythonHelper.ObjectType
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get ServiceName As String
|
||||
''' Internal use
|
||||
ServiceName = "ScriptForge.Basic"
|
||||
End Property ' ScriptForge.SF_PythonHelper.ServiceName
|
||||
|
||||
REM ============================================================== PUBLIC METHODS
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function PyCDate(ByVal DateArg As Variant) As Variant
|
||||
''' Convenient function to replicate CDate() in Python scripts
|
||||
''' Args:
|
||||
''' DateArg: a date as a string or as a double
|
||||
''' Returns:
|
||||
''' The converted date as a UNO DateTime structure
|
||||
''' If the input argument could not be recognized as a date, return the argument unchanged
|
||||
''' Example: (Python code)
|
||||
''' a = bas.CDate('2021-02-18')
|
||||
|
||||
Dim vDate As Variant ' Return value
|
||||
Const cstThisSub = "Basic.CDate"
|
||||
Const cstSubArgs = "datearg"
|
||||
|
||||
On Local Error GoTo Catch
|
||||
vDate = Null
|
||||
|
||||
Check:
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Try:
|
||||
vDate = CDate(DateArg)
|
||||
|
||||
Finally:
|
||||
If VarType(vDate) = V_DATE Then PyCDate = CDateToUnoDateTime(vDate) Else PyCDate = DateArg
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
On Local Error GoTo 0
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_PythonHelper.PyCDate
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function PyConvertFromUrl(ByVal FileName As Variant) As String
|
||||
''' Convenient function to replicate ConvertFromUrl() in Python scripts
|
||||
''' Args:
|
||||
''' FileName: a string representing a file in URL format
|
||||
''' Returns:
|
||||
''' The same file name in native operating system notation
|
||||
''' Example: (Python code)
|
||||
''' a = bas.ConvertFromUrl('file:////boot.sys')
|
||||
|
||||
Dim sFileName As String ' Return value
|
||||
Const cstThisSub = "Basic.ConvertFromUrl"
|
||||
Const cstSubArgs = "filename"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
sFileName = ""
|
||||
|
||||
Check:
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Try:
|
||||
sFileName = ConvertFromUrl(FileName)
|
||||
|
||||
Finally:
|
||||
PyConvertFromUrl = sFileName
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_PythonHelper.PyConvertFromUrl
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function PyConvertToUrl(ByVal FileName As Variant) As String
|
||||
''' Convenient function to replicate ConvertToUrl() in Python scripts
|
||||
''' Args:
|
||||
''' FileName: a string representing a file in native operating system notation
|
||||
''' Returns:
|
||||
''' The same file name in URL format
|
||||
''' Example: (Python code)
|
||||
''' a = bas.ConvertToUrl('C:\boot.sys')
|
||||
|
||||
Dim sFileName As String ' Return value
|
||||
Const cstThisSub = "Basic.ConvertToUrl"
|
||||
Const cstSubArgs = "filename"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
sFileName = ""
|
||||
|
||||
Check:
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Try:
|
||||
sFileName = ConvertToUrl(FileName)
|
||||
|
||||
Finally:
|
||||
PyConvertToUrl = sFileName
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_PythonHelper.PyConvertToUrl
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function PyCreateUnoService(ByVal UnoService As Variant) As Variant
|
||||
''' Convenient function to replicate CreateUnoService() in Python scripts
|
||||
''' Args:
|
||||
''' UnoService: a string representing the service to create
|
||||
''' Returns:
|
||||
''' A UNO object
|
||||
''' Example: (Python code)
|
||||
''' a = bas.CreateUnoService('com.sun.star.i18n.CharacterClassification')
|
||||
|
||||
Dim vUno As Variant ' Return value
|
||||
Const cstThisSub = "Basic.CreateUnoService"
|
||||
Const cstSubArgs = "unoservice"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
Set vUno = Nothing
|
||||
|
||||
Check:
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Try:
|
||||
Set vUno = CreateUnoService(UnoService)
|
||||
|
||||
Finally:
|
||||
Set PyCreateUnoService = vUno
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_PythonHelper.PyCreateUnoService
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function PyDateAdd(ByVal Add As Variant _
|
||||
, ByVal Count As Variant _
|
||||
, ByVal DateArg As Variant _
|
||||
) As Variant
|
||||
''' Convenient function to replicate DateAdd() in Python scripts
|
||||
''' Args:
|
||||
''' Add: The unit to add
|
||||
''' Count: how many times to add (might be negative)
|
||||
''' DateArg: a date as a com.sun.star.util.DateTime UNO structure
|
||||
''' Returns:
|
||||
''' The new date as a string in iso format
|
||||
''' Example: (Python code)
|
||||
''' a = bas.DateAdd('d', 1, bas.Now()) ' Tomorrow
|
||||
|
||||
Dim vNewDate As Variant ' Return value
|
||||
Dim vDate As Date ' Alias of DateArg
|
||||
Const cstThisSub = "Basic.DateAdd"
|
||||
Const cstSubArgs = "add, count, datearg"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
vNewDate = ""
|
||||
|
||||
Check:
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Try:
|
||||
If VarType(DateArg) = V_OBJECT Then
|
||||
vDate = CDateFromUnoDateTime(DateArg)
|
||||
Else
|
||||
vDate = SF_Utils._CStrToDate(DateArg)
|
||||
End If
|
||||
vNewDate = DateAdd(Add, Count, vDate)
|
||||
|
||||
Finally:
|
||||
If VarType(vNewDate) = V_DATE Then PyDateAdd = CDateToUnoDateTime(vNewDate) Else PyDateAdd = vNewDate
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_PythonHelper.PyDateAdd
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function PyDateDiff(ByVal Add As Variant _
|
||||
, ByVal Date1 As Variant _
|
||||
, ByVal Date2 As Variant _
|
||||
, ByVal WeekStart As Variant _
|
||||
, ByVal YearStart As Variant _
|
||||
) As Long
|
||||
''' Convenient function to replicate DateDiff() in Python scripts
|
||||
''' Args:
|
||||
''' Add: The unit of the date interval
|
||||
''' Date1, Date2: the two dates to be compared
|
||||
''' WeekStart: the starting day of a week
|
||||
''' YearStart: the starting week of a year
|
||||
''' Returns:
|
||||
''' The number of intervals expressed in Adds
|
||||
''' Example: (Python code)
|
||||
''' a = bas.DateDiff('d', bas.DateAdd('d', 1, bas.Now()), bas.Now()) ' -1 day
|
||||
|
||||
Dim lDiff As Long ' Return value
|
||||
Dim vDate1 As Date ' Alias of Date1
|
||||
Dim vDate2 As Date ' Alias of Date2
|
||||
Const cstThisSub = "Basic.DateDiff"
|
||||
Const cstSubArgs = "add, date1, date2, [weekstart=1], [yearstart=1]"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
lDiff = 0
|
||||
|
||||
Check:
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Try:
|
||||
If VarType(Date1) = V_OBJECT Then
|
||||
vDate1 = CDateFromUnoDateTime(Date1)
|
||||
Else
|
||||
vDate1 = SF_Utils._CStrToDate(Date1)
|
||||
End If
|
||||
If VarType(Date2) = V_OBJECT Then
|
||||
vDate2 = CDateFromUnoDateTime(Date2)
|
||||
Else
|
||||
vDate2 = SF_Utils._CStrToDate(Date2)
|
||||
End If
|
||||
lDiff = DateDiff(Add, vDate1, vDate2, WeekStart, YearStart)
|
||||
|
||||
|
||||
Finally:
|
||||
PyDateDiff = lDiff
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_PythonHelper.PyDateDiff
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function PyDatePart(ByVal Add As Variant _
|
||||
, ByVal DateArg As Variant _
|
||||
, ByVal WeekStart As Variant _
|
||||
, ByVal YearStart As Variant _
|
||||
) As Long
|
||||
''' Convenient function to replicate DatePart() in Python scripts
|
||||
''' Args:
|
||||
''' Add: The unit of the date interval
|
||||
''' DateArg: The date from which to extract a part
|
||||
''' WeekStart: the starting day of a week
|
||||
''' YearStart: the starting week of a year
|
||||
''' Returns:
|
||||
''' The specified part of the date
|
||||
''' Example: (Python code)
|
||||
''' a = bas.DatePart('y', bas.Now()) ' day of year
|
||||
|
||||
Dim lPart As Long ' Return value
|
||||
Dim vDate As Date ' Alias of DateArg
|
||||
Const cstThisSub = "Basic.DatePart"
|
||||
Const cstSubArgs = "add, datearg, [weekstart=1], [yearstart=1]"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
lPart = 0
|
||||
|
||||
Check:
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Try:
|
||||
If VarType(DateArg) = V_OBJECT Then
|
||||
vDate = CDateFromUnoDateTime(DateArg)
|
||||
Else
|
||||
vDate = SF_Utils._CStrToDate(DateArg)
|
||||
End If
|
||||
lPart = DatePart(Add, vDate, WeekStart, YearStart)
|
||||
|
||||
|
||||
Finally:
|
||||
PyDatePart = lPart
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_PythonHelper.PyDatePart
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function PyDateValue(ByVal DateArg As Variant) As Variant
|
||||
''' Convenient function to replicate DateValue() in Python scripts
|
||||
''' Args:
|
||||
''' DateArg: a date as a string
|
||||
''' Returns:
|
||||
''' The converted date as a UNO DateTime structure
|
||||
''' Example: (Python code)
|
||||
''' a = bas.DateValue('2021-02-18')
|
||||
|
||||
Dim vDate As Variant ' Return value
|
||||
Const cstThisSub = "Basic.DateValue"
|
||||
Const cstSubArgs = "datearg"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
vDate = ""
|
||||
|
||||
Check:
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Try:
|
||||
vDate = DateValue(DateArg)
|
||||
|
||||
Finally:
|
||||
If VarType(vDate) = V_DATE Then PyDateValue = CDateToUnoDateTime(vDate) Else PyDateValue = vDate
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_PythonHelper.PyDateValue
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function PyFormat(ByVal Value As Variant _
|
||||
, ByVal Pattern As Variant _
|
||||
) As String
|
||||
''' Convenient function to replicate Format() in Python scripts
|
||||
''' Args:
|
||||
''' Value: a date or a number
|
||||
''' Pattern: the format to apply
|
||||
''' Returns:
|
||||
''' The formatted value
|
||||
''' Example: (Python code)
|
||||
''' MsgBox bas.Format(6328.2, '##,##0.00')
|
||||
|
||||
Dim sFormat As String ' Return value
|
||||
Dim vValue As Variant ' Alias of Value
|
||||
Const cstThisSub = "Basic.Format"
|
||||
Const cstSubArgs = "value, pattern"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
sFormat = ""
|
||||
|
||||
Check:
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Try:
|
||||
If VarType(Value) = V_OBJECT Then vValue = CDateFromUnoDateTime(Value) ELse vValue = Value
|
||||
If IsEmpty(Pattern) Or Len(Pattern) = 0 Then sFormat = Str(vValue) Else sFormat = Format(vValue, Pattern)
|
||||
|
||||
|
||||
Finally:
|
||||
PyFormat = sFormat
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_PythonHelper.PyFormat
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function PyGetGuiType() As Integer
|
||||
''' Convenient function to replicate GetGuiType() in Python scripts
|
||||
''' Args:
|
||||
''' Returns:
|
||||
''' The GetGuiType value
|
||||
''' Example: (Python code)
|
||||
''' MsgBox bas.GetGuiType()
|
||||
|
||||
Const cstThisSub = "Basic.GetGuiType"
|
||||
Const cstSubArgs = ""
|
||||
|
||||
Check:
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Try:
|
||||
PyGetGuiType = GetGuiType()
|
||||
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
End Function ' ScriptForge.SF_PythonHelper.PyGetGuiType
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function PyGetSystemTicks() As Long
|
||||
''' Convenient function to replicate GetSystemTicks() in Python scripts
|
||||
''' Args:
|
||||
''' Returns:
|
||||
''' The GetSystemTicks value
|
||||
''' Example: (Python code)
|
||||
''' MsgBox bas.GetSystemTicks()
|
||||
|
||||
Const cstThisSub = "Basic.GetSystemTicks"
|
||||
Const cstSubArgs = ""
|
||||
|
||||
Check:
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Try:
|
||||
PyGetSystemTicks = GetSystemTicks()
|
||||
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
End Function ' ScriptForge.SF_PythonHelper.PyGetSystemTicks
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function PyGlobalScope(ByVal Library As Variant) As Object
|
||||
''' Convenient function to replicate GlobalScope() in Python scripts
|
||||
''' Args:
|
||||
''' Library: "Basic" or "Dialog"
|
||||
''' Returns:
|
||||
''' The GlobalScope value
|
||||
''' Example: (Python code)
|
||||
''' MsgBox bas.GlobalScope.BasicLibraries()
|
||||
|
||||
Const cstThisSub = "Basic.GlobalScope.BasicLibraries" ' or DialogLibraries
|
||||
Const cstSubArgs = ""
|
||||
|
||||
Check:
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Try:
|
||||
Select Case Library
|
||||
Case "Basic"
|
||||
PyGlobalScope = GlobalScope.BasicLibraries()
|
||||
Case "Dialog"
|
||||
PyGlobalScope = GlobalScope.DialogLibraries()
|
||||
Case Else
|
||||
End Select
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
End Function ' ScriptForge.SF_PythonHelper.PyGlobalScope
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function PyInputBox(ByVal Msg As Variant _
|
||||
, ByVal Title As Variant _
|
||||
, ByVal Default As Variant _
|
||||
, Optional ByVal XPosTwips As Variant _
|
||||
, Optional ByVal YPosTwips As Variant _
|
||||
) As String
|
||||
''' Convenient function to replicate InputBox() in Python scripts
|
||||
''' Args:
|
||||
''' Msg: String expression displayed as the message in the dialog box
|
||||
''' Title: String expression displayed in the title bar of the dialog box
|
||||
''' Default: String expression displayed in the text box as default if no other input is given
|
||||
''' XPosTwips: Integer expression that specifies the horizontal position of the dialog
|
||||
''' YPosTwips: Integer expression that specifies the vertical position of the dialog
|
||||
''' If XPosTwips and YPosTwips are omitted, the dialog is centered on the screen
|
||||
''' The position is specified in twips.
|
||||
''' Returns:
|
||||
''' The entered value or "" if the user pressed the Cancel button
|
||||
''' Example: (Python code)
|
||||
''' a = bas.InputBox ('Please enter a phrase:', 'Dear User')
|
||||
|
||||
Dim sInput As String ' Return value
|
||||
Const cstThisSub = "Basic.InputBox"
|
||||
Const cstSubArgs = "msg, [title=''], [default=''], [xpostwips], [ypostwips]"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
sInput = ""
|
||||
|
||||
Check:
|
||||
If IsMissing(YPosTwips) Then YPosTwips = 1
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Try:
|
||||
If IsMissing(XPosTwips) Then
|
||||
sInput = InputBox(Msg, Title, Default)
|
||||
Else
|
||||
sInput = InputBox(Msg, Title, Default, XPosTwips, YPosTwips)
|
||||
End If
|
||||
|
||||
Finally:
|
||||
PyInputBox = sInput
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_PythonHelper.PyInputBox
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function PyMsgBox(ByVal Text As Variant _
|
||||
, ByVal DialogType As Variant _
|
||||
, ByVal DialogTitle As Variant _
|
||||
) As Integer
|
||||
''' Convenient function to replicate MsgBox() in Python scripts
|
||||
''' Args:
|
||||
''' Text: String expression displayed as a message in the dialog box
|
||||
''' DialogType: Any integer expression that defines the number and type of buttons or icons displayed
|
||||
''' DialogTitle: String expression displayed in the title bar of the dialog
|
||||
''' Returns:
|
||||
''' The pressed button
|
||||
''' Example: (Python code)
|
||||
''' a = bas.MsgBox ('Please press a button:', bas.MB_EXCLAMATION, 'Dear User')
|
||||
|
||||
Dim iMsg As Integer ' Return value
|
||||
Const cstThisSub = "Basic.MsgBox"
|
||||
Const cstSubArgs = "text, [dialogtype=0], [dialogtitle]"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
iMsg = -1
|
||||
|
||||
Check:
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Try:
|
||||
iMsg = MsgBox(Text, DialogType, DialogTitle)
|
||||
|
||||
Finally:
|
||||
PyMsgBox = iMsg
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_PythonHelper.PyMsgBox
|
||||
|
||||
REM ============================================================= PRIVATE METHODS
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function _PythonDispatcher(ByRef BasicObject As Variant _
|
||||
, ByVal CallType As Variant _
|
||||
, ByVal Script As Variant _
|
||||
, ParamArray Args() As Variant _
|
||||
) As Variant
|
||||
''' Called from Python only
|
||||
''' The method calls the method Script associated with the BasicObject class or module
|
||||
''' with the given arguments
|
||||
''' The invocation of the method can be a Property Get, Property Let or a usual call
|
||||
''' NB: arguments and return values must not be 2D arrays
|
||||
''' The implementation intends to be as AGNOSTIC as possible in terms of objects nature and methods called
|
||||
''' Args:
|
||||
''' BasicObject: a module or a class instance - May also be the reserved string: "SF_Services"
|
||||
''' CallType: one of the constants applicable to a CallByName statement + optional protocol flags
|
||||
''' Script: the name of the method or property
|
||||
''' Args: the arguments to pass to the method. Input arguments can contain symbolic constants for Null, Missing, etc.
|
||||
''' Returns:
|
||||
''' A 1D array:
|
||||
''' [0] The returned value - scalar, object or 1D array
|
||||
''' [1] The VarType() of the returned value
|
||||
''' Null, Empty and Nothing have different vartypes but return all None to Python
|
||||
''' Additionally, when array:
|
||||
''' [2] Number of dimensions in Basic
|
||||
''' Additionally, when Basic object:
|
||||
''' [2] Module (1), Class instance (2) or UNO (3)
|
||||
''' [3] The object's ObjectType
|
||||
''' [4] The object's service name
|
||||
''' [5] The object's name
|
||||
''' When an error occurs Python receives None as a scalar. This determines the occurrence of a failure
|
||||
|
||||
Dim vReturn As Variant ' The value returned by the invoked property or method
|
||||
Dim vReturnArray As Variant ' Return value
|
||||
Dim vBasicObject As Variant ' Alias of BasicObject to avoid "Object reference not set" error
|
||||
Dim iNbArgs As Integer ' Number of valid input arguments
|
||||
Dim vArg As Variant ' Alias for a single argument
|
||||
Dim vArgs() As Variant ' Alias for Args()
|
||||
Dim sScript As String ' Argument of ExecuteBasicScript()
|
||||
Dim vParams As Variant ' Array of arguments to pass to a ParamArray
|
||||
Dim sObjectType As String ' Alias of object.ObjectType
|
||||
Dim sServiceName As String ' Alias of BasicObject.ServiceName
|
||||
Dim bBasicClass As Boolean ' True when BasicObject is a class
|
||||
Dim sLibrary As String ' Library where the object belongs to
|
||||
Dim bUno As Boolean ' Return value is a UNO object
|
||||
Dim oObjDesc As Object ' _ObjectDescriptor type
|
||||
Dim iDims As Integer ' # of dims of vReturn
|
||||
Dim sess As Object : Set sess = ScriptForge.SF_Session
|
||||
Dim i As Long, j As Long
|
||||
|
||||
' Conventional special input or output values
|
||||
Const cstNoArgs = "+++NOARGS+++", cstSymEmpty = "+++EMPTY+++", cstSymNull = "+++NULL+++", cstSymMissing = "+++MISSING+++"
|
||||
|
||||
' https://support.office.com/en-us/article/CallByName-fonction-49ce9475-c315-4f13-8d35-e98cfe98729a
|
||||
' Determines the CallType
|
||||
Const vbGet = 2, vbLet = 4, vbMethod = 1, vbSet = 8
|
||||
' Protocol flags
|
||||
Const cstDateArg = 64 ' May contain a date argument
|
||||
Const cstDateRet = 128 ' Return value can be a date
|
||||
Const cstUno = 256 ' Return value can be a UNO object
|
||||
Const cstArgArray = 512 ' Any argument can be a 2D array
|
||||
Const cstRetArray = 1024 ' Return value can be an array
|
||||
Const cstObject = 2048 ' 1st argument is a Basic object when numeric
|
||||
Const cstHardCode = 4096 ' Method must not be executed with CallByName()
|
||||
' Object nature in returned array
|
||||
Const objMODULE = 1, objCLASS = 2, objUNO = 3
|
||||
|
||||
Check:
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
_PythonDispatcher = Null
|
||||
|
||||
' Ignore Null basic objects (Null = Null or Nothing)
|
||||
If IsNull(BasicObject) Or IsEmpty(BasicObject) Then GoTo Catch
|
||||
|
||||
' Reinterpret arguments one by one into vArgs, convert UNO date/times and conventional NoArgs/Empty/Null/Missing values
|
||||
iNbArgs = -1
|
||||
vArgs = Array()
|
||||
|
||||
If UBound(Args) >= 0 Then
|
||||
For i = 0 To UBound(Args)
|
||||
vArg = Args(i)
|
||||
' Are there arguments ?
|
||||
If i = 0 And VarType(vArg) = V_STRING Then
|
||||
If vArg = cstNoArgs Then Exit For
|
||||
End If
|
||||
' Is 1st argument a reference to a Basic object ?
|
||||
If i = 0 And (( CallType And cstObject ) = cstObject) And SF_Utils._VarTypeExt(vArg) = V_NUMERIC Then
|
||||
If vArg < 0 Or Not IsArray(_SF_.PythonStorage) Then GoTo Catch
|
||||
If vArg > UBound(_SF_.PythonStorage) Then GoTo Catch
|
||||
vArg = _SF_.PythonStorage(vArg)
|
||||
' Is argument a symbolic constant for Null, Empty, ... , or a date?
|
||||
ElseIf VarType(vArg) = V_STRING Then
|
||||
If Len(vArg) = 0 Then
|
||||
ElseIf vArg = cstSymEmpty Then
|
||||
vArg = Empty
|
||||
ElseIf vArg = cstSymNull Then
|
||||
vArg = Null
|
||||
ElseIf vArg = cstSymMissing Then
|
||||
Exit For ' Next arguments must be missing also
|
||||
End If
|
||||
ElseIf VarType(vArg) = V_OBJECT Then
|
||||
If ( CallType And cstDateArg ) = cstDateArg Then vArg = CDateFromUnoDateTime(vArg)
|
||||
End If
|
||||
iNbArgs = iNbArgs + 1
|
||||
|
||||
ReDim Preserve vArgs(iNbArgs)
|
||||
vArgs(iNbArgs) = vArg
|
||||
Next i
|
||||
End If
|
||||
|
||||
Try:
|
||||
' Dispatching strategy: based on next constraints
|
||||
' (1) Bug https://bugs.documentfoundation.org/show_bug.cgi?id=138155
|
||||
' The CallByName function fails when returning an array
|
||||
' (2) Python has tuples and tuple of tuples, not 2D arrays
|
||||
' (3) Passing 2D arrays through a script provider always transform it into a sequence of sequences
|
||||
' (4) The CallByName function takes exclusive control on the targeted object up to its exit
|
||||
' 1. Methods in usual modules are called by ExecuteBasicScript() except if they use a ParamArray
|
||||
' 2. Properties in any service are got and set with obj.GetProperty/SetProperty(...)
|
||||
' 3. Methods in class modules are invoked with CallByName
|
||||
' 4. Methods in class modules using a 2D array or returning arrays, or methods using ParamArray,
|
||||
''' are hardcoded as exceptions or are not implemented
|
||||
' 5. Due to constraint (4), a predefined list of method calls must be hardcoded to avoid blocking use of CallByName
|
||||
' The concerned methods are flagged with cstHardCode
|
||||
|
||||
With _SF_
|
||||
' Initialize Python persistent storage at 1st call
|
||||
If IsEmpty(.PythonStorage) Then ._InitPythonStorage()
|
||||
' Reset any error
|
||||
._Stackreset()
|
||||
' Set Python trigger to manage signatures in error messages
|
||||
.TriggeredByPython = True
|
||||
End With
|
||||
|
||||
Select case VarType(BasicObject)
|
||||
Case V_STRING
|
||||
' Special entry for CreateScriptService()
|
||||
vBasicObject = BasicObject
|
||||
If vBasicObject = "SF_Services" Then
|
||||
If UBound(vArgs) = 0 Then vParams = Array() Else vParams = SF_Array.Slice(vArgs, 1)
|
||||
Select Case UBound(vParams)
|
||||
Case -1 : vReturn = SF_Services.CreateScriptService(vArgs(0))
|
||||
Case 0 : vReturn = SF_Services.CreateScriptService(vArgs(0), vParams(0))
|
||||
Case 1 : vReturn = SF_Services.CreateScriptService(vArgs(0), vParams(0), vParams(1))
|
||||
Case 2 : vReturn = SF_Services.CreateScriptService(vArgs(0), vParams(0), vParams(1), vParams(2))
|
||||
Case 3 : vReturn = SF_Services.CreateScriptService(vArgs(0), vParams(0), vParams(1), vParams(2), vParams(3))
|
||||
Case 4 : vReturn = SF_Services.CreateScriptService(vArgs(0), vParams(0), vParams(1), vParams(2), vParams(3), vParams(4))
|
||||
End Select
|
||||
End If
|
||||
If VarType(vReturn) = V_OBJECT And Not IsNull(vReturn) Then
|
||||
vBasicObject = vReturn
|
||||
sObjectType = vBasicObject.ObjectType
|
||||
bBasicClass = ( Left(sObjectType, 3) <> "SF_" )
|
||||
End If
|
||||
|
||||
' Implement dispatching strategy
|
||||
Case V_INTEGER
|
||||
If BasicObject < 0 Or Not IsArray(_SF_.PythonStorage) Then GoTo Catch
|
||||
If BasicObject > UBound(_SF_.PythonStorage) Then GoTo Catch
|
||||
vBasicObject = _SF_.PythonStorage(BasicObject)
|
||||
sObjectType = vBasicObject.ObjectType
|
||||
sServiceName = vBasicObject.ServiceName
|
||||
|
||||
' Basic modules have type = "SF_*"
|
||||
bBasicClass = ( Left(sObjectType, 3) <> "SF_" )
|
||||
sLibrary = Split(sServiceName, ".")(0)
|
||||
|
||||
' Methods in standard modules returning/passing a date are hardcoded as exceptions
|
||||
If Not bBasicClass And ((CallType And vbMethod) = vbMethod) _
|
||||
And (((CallType And cstDateRet) = cstDateRet) Or ((CallType And cstDateArg) = cstDateArg)) Then
|
||||
Select Case sServiceName
|
||||
Case "ScriptForge.FileSystem"
|
||||
If Script = "GetFileModified" Then vReturn = SF_FileSystem.GetFileModified(vArgs(0))
|
||||
Case "ScriptForge.Region"
|
||||
Select Case Script
|
||||
Case "DSTOffset" : vReturn = SF_Region.DSTOffset(vArgs(0), vArgs(1), vArgs(2))
|
||||
Case "LocalDateTime" : vReturn = SF_Region.LocalDateTime(vArgs(0), vArgs(1), vArgs(2))
|
||||
Case "UTCDateTime" : vReturn = SF_Region.UTCDateTime(vArgs(0), vArgs(1), vArgs(2))
|
||||
Case "UTCNow" : vReturn = SF_Region.UTCNow(vArgs(0), vArgs(1))
|
||||
Case Else
|
||||
End Select
|
||||
End Select
|
||||
|
||||
' Methods in usual modules using a 2D array or returning arrays are hardcoded as exceptions
|
||||
ElseIf Not bBasicClass And _
|
||||
(((CallType And vbMethod) + (CallType And cstArgArray)) = vbMethod + cstArgArray Or _
|
||||
((CallType And vbMethod) + (CallType And cstRetArray)) = vbMethod + cstRetArray) Then
|
||||
' Not service related
|
||||
If Script = "Methods" Then
|
||||
vReturn = vBasicObject.Methods()
|
||||
ElseIf Script = "Properties" Then
|
||||
vReturn = vBasicObject.Properties()
|
||||
Else
|
||||
Select Case sServiceName
|
||||
Case "ScriptForge.Array"
|
||||
If Script = "ImportFromCSVFile" Then vReturn = SF_Array.ImportFromCSVFile(vArgs(0), vArgs(1), vArgs(2), True)
|
||||
End Select
|
||||
End If
|
||||
|
||||
' Methods in usual modules are called by ExecuteBasicScript() except if they use a ParamArray
|
||||
ElseIf Not bBasicClass And (CallType And vbMethod) = vbMethod Then
|
||||
sScript = sLibrary & "." & sObjectType & "." & Script
|
||||
' Force validation in targeted function, not in ExecuteBasicScript()
|
||||
_SF_.StackLevel = -1
|
||||
Select Case UBound(vArgs)
|
||||
Case -1 : vReturn = sess.ExecuteBasicScript(, sScript)
|
||||
Case 0 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0))
|
||||
Case 1 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0), vArgs(1))
|
||||
Case 2 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0), vArgs(1), vArgs(2))
|
||||
Case 3 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0), vArgs(1), vArgs(2), vArgs(3))
|
||||
Case 4 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4))
|
||||
Case 5 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5))
|
||||
Case 6 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6))
|
||||
Case 7 : vReturn = sess.ExecuteBasicScript(, sScript, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7))
|
||||
End Select
|
||||
_SF_.StackLevel = 0
|
||||
|
||||
' Properties in any service are got and set with obj.GetProperty/SetProperty(...)
|
||||
ElseIf (CallType And vbGet) = vbGet Then ' In some cases (Calc ...) GetProperty may have an argument
|
||||
If UBound(vArgs) < 0 Then vReturn = vBasicObject.GetProperty(Script) Else vReturn = vBasicObject.GetProperty(Script, vArgs(0))
|
||||
ElseIf (CallType And vbLet) = vbLet Then
|
||||
vReturn = vBasicObject.SetProperty(Script, vArgs(0))
|
||||
|
||||
' Methods in class modules using a 2D array or returning arrays are hardcoded as exceptions. Bug #138155
|
||||
ElseIf ((CallType And vbMethod) + (CallType And cstArgArray)) = vbMethod + cstArgArray Or _
|
||||
((CallType And vbMethod) + (CallType And cstRetArray)) = vbMethod + cstRetArray Then
|
||||
If Script = "Methods" Then
|
||||
vReturn = vBasicObject.Methods()
|
||||
ElseIf Script = "Properties" Then
|
||||
vReturn = vBasicObject.Properties()
|
||||
Else
|
||||
Select Case sServiceName
|
||||
Case "SFDatabases.Database"
|
||||
If Script = "GetRows" Then vReturn = vBasicObject.GetRows(vArgs(0), vArgs(1), vArgs(2), vArgs(3))
|
||||
Case "SFDialogs.Dialog"
|
||||
If Script = "Controls" Then vReturn = vBasicObject.Controls(vArgs(0))
|
||||
Case "SFDialogs.DialogControl"
|
||||
If Script = "SetTableData" Then vReturn = vBasicObject.SetTableData(vArgs(0), vArgs(1), vArgs(2))
|
||||
Case "SFDocuments.Document"
|
||||
If Script = "Forms" Then vReturn = vBasicObject.Forms(vArgs(0))
|
||||
Case "SFDocuments.Base"
|
||||
Select Case Script
|
||||
Case "FormDocuments" : vReturn = vBasicObject.FormDocuments()
|
||||
Case "Forms" : vReturn = vBasicObject.Forms(vArgs(0), vArgs(1))
|
||||
End Select
|
||||
Case "SFDocuments.Calc"
|
||||
Select Case Script
|
||||
Case "Charts" : vReturn = vBasicObject.Charts(vArgs(0), vArgs(1))
|
||||
Case "Forms" : vReturn = vBasicObject.Forms(vArgs(0), vArgs(1))
|
||||
Case "GetFormula" : vReturn = vBasicObject.GetFormula(vArgs(0))
|
||||
Case "GetValue" : vReturn = vBasicObject.GetValue(vArgs(0))
|
||||
Case "SetArray" : vReturn = vBasicObject.SetArray(vArgs(0), vArgs(1))
|
||||
Case "SetFormula" : vReturn = vBasicObject.SetFormula(vArgs(0), vArgs(1))
|
||||
Case "SetValue" : vReturn = vBasicObject.SetValue(vArgs(0), vArgs(1))
|
||||
End Select
|
||||
Case "SFDocuments.Form"
|
||||
Select Case Script
|
||||
Case "Controls" : vReturn = vBasicObject.Controls(vArgs(0))
|
||||
Case "Subforms" : vReturn = vBasicObject.Subforms(vArgs(0))
|
||||
End Select
|
||||
Case "SFDocuments.FormControl"
|
||||
If Script = "Controls" Then vReturn = vBasicObject.Controls(vArgs(0))
|
||||
End Select
|
||||
End If
|
||||
|
||||
' Methods in class modules may better not be executed with CallByName()
|
||||
ElseIf bBasicClass And ((CallType And vbMethod) + (CallType And cstHardCode)) = vbMethod + cstHardCode Then
|
||||
Select Case sServiceName
|
||||
Case "SFDialogs.Dialog"
|
||||
Select Case Script
|
||||
Case "Activate" : vReturn = vBasicObject.Activate()
|
||||
Case "Center"
|
||||
If UBound(vArgs) < 0 Then vReturn = vBasicObject.Center() Else vReturn = vBasicObject.Center(vArgs(0))
|
||||
Case "EndExecute" : vReturn = vBasicObject.EndExecute(vArgs(0))
|
||||
Case "Execute" : vReturn = vBasicObject.Execute(vArgs(0))
|
||||
Case "Resize" : vReturn = vBasicObject.Resize(vArgs(0), vArgs(1), vArgs(2), vArgs(3))
|
||||
End Select
|
||||
End Select
|
||||
|
||||
' Methods in class modules are invoked with CallByName
|
||||
ElseIf bBasicClass And ((CallType And vbMethod) = vbMethod) Then
|
||||
Select Case UBound(vArgs)
|
||||
' Dirty alternatives to process usual and ParamArray cases
|
||||
' But, up to ... how many ?
|
||||
' - The OFFSETADDRESSERROR has 12 arguments
|
||||
' - The ".uno:DataSort" command may have 14 property name-value pairs
|
||||
Case -1 : vReturn = CallByName(vBasicObject, Script, vbMethod)
|
||||
Case 0 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0))
|
||||
Case 1 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1))
|
||||
Case 2 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2))
|
||||
Case 3 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3))
|
||||
Case 4 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4))
|
||||
Case 5 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5))
|
||||
Case 6 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6))
|
||||
Case 7 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7))
|
||||
Case 8 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
||||
, vArgs(8))
|
||||
Case 9 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
||||
, vArgs(8), vArgs(9))
|
||||
Case 10 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
||||
, vArgs(8), vArgs(9), vArgs(10))
|
||||
Case 11 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
||||
, vArgs(8), vArgs(9), vArgs(10), vArgs(11))
|
||||
Case 12, 13 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
||||
, vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12))
|
||||
Case 14, 15 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
||||
, vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14))
|
||||
Case 16, 17 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
||||
, vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14), vArgs(15), vArgs(16))
|
||||
Case 18, 19 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
||||
, vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14), vArgs(15), vArgs(16), vArgs(17), vArgs(18))
|
||||
Case 20, 21 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
||||
, vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14), vArgs(15), vArgs(16), vArgs(17), vArgs(18) _
|
||||
, vArgs(19), vArgs(20))
|
||||
Case 22, 23 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
||||
, vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14), vArgs(15), vArgs(16), vArgs(17), vArgs(18) _
|
||||
, vArgs(19), vArgs(20), vArgs(21), vArgs(22))
|
||||
Case 24, 25 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
||||
, vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14), vArgs(15), vArgs(16), vArgs(17), vArgs(18) _
|
||||
, vArgs(19), vArgs(20), vArgs(21), vArgs(22), vArgs(23), vArgs(24))
|
||||
Case 26, 27 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
||||
, vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14), vArgs(15), vArgs(16), vArgs(17), vArgs(18) _
|
||||
, vArgs(19), vArgs(20), vArgs(21), vArgs(22), vArgs(23), vArgs(24), vArgs(25), vArgs(26))
|
||||
Case >= 28 : vReturn = CallByName(vBasicObject, Script, vbMethod, vArgs(0), vArgs(1), vArgs(2), vArgs(3), vArgs(4), vArgs(5), vArgs(6), vArgs(7) _
|
||||
, vArgs(8), vArgs(9), vArgs(10), vArgs(11), vArgs(12), vArgs(13), vArgs(14), vArgs(15), vArgs(16), vArgs(17), vArgs(18) _
|
||||
, vArgs(19), vArgs(20), vArgs(21), vArgs(22), vArgs(23), vArgs(24), vArgs(25), vArgs(26), vArgs(27), vArgs(28))
|
||||
End Select
|
||||
End If
|
||||
|
||||
' Post processing
|
||||
If Script = "Dispose" Then
|
||||
' Special case: Dispose() must update the cache for class objects created in Python scripts
|
||||
Set _SF_.PythonStorage(BasicObject) = Nothing
|
||||
End If
|
||||
Case Else
|
||||
End Select
|
||||
|
||||
' Format the returned array
|
||||
vReturnArray = Array()
|
||||
' Distinguish: Basic object
|
||||
' UNO object
|
||||
' Array
|
||||
' Scalar
|
||||
If IsArray(vReturn) Then
|
||||
ReDim vReturnArray(0 To 2)
|
||||
iDims = SF_Array.CountDims(vReturn)
|
||||
' Replace dates by UNO format
|
||||
If iDims = 1 Then
|
||||
For i = LBound(vReturn) To UBound(vReturn)
|
||||
If VarType(vReturn(i)) = V_DATE Then vReturn(i) = CDateToUnoDateTime(vReturn(i))
|
||||
Next i
|
||||
ElseIf iDims = 2 Then
|
||||
For i = LBound(vReturn, 1) To UBound(vReturn, 1)
|
||||
For j = LBound(vReturn, 2) To UBound(vReturn, 2)
|
||||
If VarType(vReturn(i, j)) = V_DATE Then vReturn(i, j) = CDateToUnoDateTime(vReturn(i, j))
|
||||
Next j
|
||||
Next i
|
||||
End If
|
||||
vReturnArray(0) = vReturn ' 2D arrays are flattened by the script provider when returning to Python
|
||||
vReturnArray(1) = VarType(vReturn)
|
||||
vReturnArray(2) = iDims
|
||||
ElseIf VarType(vReturn) = V_OBJECT And Not IsNull(vReturn) Then
|
||||
' Uno or not Uno ?
|
||||
bUno = False
|
||||
If (CallType And cstUno) = cstUno Then ' UNO considered only when pre-announced in CallType
|
||||
Set oObjDesc = SF_Utils._VarTypeObj(vReturn)
|
||||
bUno = ( oObjDesc.iVarType = V_UNOOBJECT )
|
||||
End If
|
||||
If bUno Then
|
||||
ReDim vReturnArray(0 To 2)
|
||||
Set vReturnArray(0) = vReturn
|
||||
Else
|
||||
ReDim vReturnArray(0 To 5)
|
||||
vReturnArray(0) = _SF_._AddToPythonSTorage(vReturn)
|
||||
End If
|
||||
vReturnArray(1) = V_OBJECT
|
||||
vReturnArray(2) = Iif(bUno, objUNO, Iif(bBasicClass, objCLASS, objMODULE))
|
||||
If Not bUno Then
|
||||
vReturnArray(3) = vReturn.ObjectType
|
||||
vReturnArray(4) = vReturn.ServiceName
|
||||
vReturnArray(5) = ""
|
||||
If vReturn.ObjectType <> "SF_CalcReference" Then ' Calc references are implemented as a Type ... End Type data structure
|
||||
If SF_Array.Contains(vReturn.Properties(), "Name", SortOrder := "ASC") Then vReturnArray(5) = vReturn.Name
|
||||
End If
|
||||
End If
|
||||
Else ' Scalar or Nothing
|
||||
ReDim vReturnArray(0 To 1)
|
||||
If VarType(vReturn) = V_DATE Then vReturnArray(0) = CDateToUnoDateTime(vReturn) Else vReturnArray(0) = vReturn
|
||||
vReturnArray(1) = VarType(vReturn)
|
||||
End If
|
||||
|
||||
_PythonDispatcher = vReturnArray
|
||||
|
||||
Finally:
|
||||
_SF_.TriggeredByPython = False ' Reset normal state
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_PythonHelper._PythonDispatcher
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Function _Repr() As String
|
||||
''' Convert the Basic instance to a readable string, typically for debugging purposes (DebugPrint ...)
|
||||
''' Args:
|
||||
''' Return:
|
||||
''' "[PythonHelper]"
|
||||
|
||||
_Repr = "[PythonHelper]"
|
||||
|
||||
End Function ' ScriptForge.SF_PythonHelper._Repr
|
||||
|
||||
REM ================================================= END OF SCRIPTFORGE.SF_PythonHelper
|
||||
</script:module>
|
||||
@@ -0,0 +1,861 @@
|
||||
<?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_Region" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
|
||||
REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
|
||||
REM === Full documentation is available on https://help.libreoffice.org/ ===
|
||||
REM =======================================================================================================================
|
||||
|
||||
Option Compatible
|
||||
Option Explicit
|
||||
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
''' SF_Region
|
||||
''' =========
|
||||
''' Singleton class implementing the "ScriptForge.Region" service
|
||||
''' Implemented as a usual Basic module
|
||||
'''
|
||||
''' A collection of functions about languages, countries and timezones
|
||||
''' - Locales
|
||||
''' - Currencies
|
||||
''' - Numbers and dates formatting
|
||||
''' - Calendars
|
||||
''' - Timezones conversions
|
||||
''' - Numbers transformed to text
|
||||
'''
|
||||
''' Definitions:
|
||||
''' Locale or Region
|
||||
''' A combination of a language (2 or 3 lower case characters) and a country (2 upper case characters)
|
||||
''' Most properties and methods require a locale as argument.
|
||||
''' Some of them accept either the complete locale or only the language or country parts.
|
||||
''' When absent, the considered locale is the locale used in the LibreOffice user interface.
|
||||
''' (see the SF_Platform.OfficeLocale property)
|
||||
''' Timezone
|
||||
''' Specified as "Region/City" name like "Europe/Berlin", or a custom time zone ID such as "UTC" or "GMT-8:00".
|
||||
''' The time offset between the timezone and the Greenwich Meridian Time (GMT) is expressed in minutes.
|
||||
''' The Daylight Saving Time (DST) is an additional offset.
|
||||
''' Both offsets can be positive or negative.
|
||||
''' More info on
|
||||
''' https://timezonedb.com/time-zones
|
||||
''' https://en.wikipedia.org/wiki/Time_zone
|
||||
'''
|
||||
''' Service invocation example:
|
||||
''' Dim regio As Object
|
||||
''' Set regio = CreateScriptService("Region")
|
||||
'''
|
||||
''' Detailed user documentation:
|
||||
''' https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03/sf_region.html?DbPAR=BASIC
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
REM ================================================================== EXCEPTIONS
|
||||
|
||||
REM ============================================================= PRIVATE MEMBERS
|
||||
|
||||
Private UserLocale As String ' platform.OfficeLocale
|
||||
|
||||
' Reference tables
|
||||
Private LocaleData As Variant ' com.sun.star.i18n.LocaleData
|
||||
Private LocaleNames As Variant ' Array of all available "la-CO" strings
|
||||
|
||||
Private UserIndex As Integer ' Index of UserLocale in reference tables
|
||||
|
||||
REM ============================================================ MODULE CONSTANTS
|
||||
|
||||
REM ===================================================== CONSTRUCTOR/DESTRUCTOR
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Dispose() As Variant
|
||||
Set Dispose = Nothing
|
||||
End Function ' ScriptForge.SF_Region Explicit destructor
|
||||
|
||||
REM ================================================================== PROPERTIES
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get Country(Optional ByVal Region As Variant) As String
|
||||
''' Returns the english country name applicable in the given region.
|
||||
''' The region expressed either as a
|
||||
''' - locale combining language-COUNTRY (la-CO)
|
||||
''' - country only (CO)
|
||||
''' Example:
|
||||
''' MsgBox Regio.Country("IT") ' Italy
|
||||
Country = _PropertyGet("Country", Region)
|
||||
End Property ' ScriptForge.SF_Region.Country (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get Currency(Optional ByVal Region As Variant) As String
|
||||
''' Returns the currency applicable in the given region.
|
||||
''' The region is expressed either as a
|
||||
''' - locale combining language-COUNTRY (la-CO)
|
||||
''' - country only (CO)
|
||||
''' Example:
|
||||
''' MsgBox Regio.Currency("IT") ' EUR
|
||||
Currency = _PropertyGet("Currency", Region)
|
||||
End Property ' ScriptForge.SF_Region.Currency (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function DatePatterns(Optional ByVal Region As Variant) As Variant ' Function better than Property when return value is an array
|
||||
''' Returns list of date acceptance patterns for the given region.
|
||||
''' Patterns with input combinations that are accepted as incomplete date input, such as M/D or D.M
|
||||
''' The region is expressed as a locale combining language-COUNTRY (la-CO)
|
||||
''' The list is zero-based.
|
||||
''' Example:
|
||||
''' MsgBox Join(Regio.DatePatterns("it-IT"), ",") ' D/M/Y,D/M
|
||||
DatePatterns = _PropertyGet("DatePatterns", Region)
|
||||
End Function ' ScriptForge.SF_Region.DatePatterns (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get DateSeparator(Optional ByVal Region As Variant) As String
|
||||
''' Returns the separator used in dates applicable in the given region.
|
||||
''' The region is expressed as a locale combining language-COUNTRY (la-CO)
|
||||
''' Example:
|
||||
''' MsgBox Regio.DateSeparator("it-IT") ' /
|
||||
DateSeparator = _PropertyGet("DateSeparator", Region)
|
||||
End Property ' ScriptForge.SF_Region.DateSeparator (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function DayAbbrevNames(Optional ByVal Region As Variant) As Variant ' Function better than Property when return value is an array
|
||||
''' Returns list of abbreviated names of weekdays applicable in the given region.
|
||||
''' The region expressed as a
|
||||
''' - locale combining language-COUNTRY (la-CO)
|
||||
''' - language only (la)
|
||||
''' The list is zero-based. The 1st in the list [0] is the Monday.
|
||||
''' Example:
|
||||
''' MsgBox Join(Regio.DayAbbrevNames("it-IT"), ",") ' lun,mar,mer,gio,ven,sab,dom
|
||||
DayAbbrevNames = _PropertyGet("DayAbbrevNames", Region)
|
||||
End Function ' ScriptForge.SF_Region.DayAbbrevNames (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function DayNames(Optional ByVal Region As Variant) As Variant ' Function better than Property when return value is an array
|
||||
''' Returns list of names of weekdays applicable in the given region.
|
||||
''' The region expressed as a
|
||||
''' - locale combining language-COUNTRY (la-CO)
|
||||
''' - language only (la)
|
||||
''' The list is zero-based. The 1st in the list [0] is the Monday.
|
||||
''' Example:
|
||||
''' MsgBox Join(Regio.DayNames("it-IT"), ",") ' lunedì,martedì,mercoledì,giovedì,venerdì,sabato,domenica
|
||||
DayNames = _PropertyGet("DayNames", Region)
|
||||
End Function ' ScriptForge.SF_Region.DayNames (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function DayNarrowNames(Optional ByVal Region As Variant) As Variant ' Function better than Property when return value is an array
|
||||
''' Returns list of initials of weekdays applicable in the given region.
|
||||
''' The region expressed as a
|
||||
''' - locale combining language-COUNTRY (la-CO)
|
||||
''' - language only (la)
|
||||
''' The list is zero-based. The 1st in the list [0] is the Monday.
|
||||
''' Example:
|
||||
''' MsgBox Join(Regio.DayNarrowNames("it-IT"), ",") ' l,m,m,g,v,s,d
|
||||
DayNarrowNames = _PropertyGet("DayNarrowNames", Region)
|
||||
End Function ' ScriptForge.SF_Region.DayNarrowNames (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get DecimalPoint(Optional ByVal Region As Variant) As String
|
||||
''' Returns the decimal separator used in numbers applicable in the given region.
|
||||
''' The region is expressed as a locale combining language-COUNTRY (la-CO)
|
||||
''' Example:
|
||||
''' MsgBox Regio.DecimalPoint("it-IT") ' .
|
||||
DecimalPoint = _PropertyGet("DecimalPoint", Region)
|
||||
End Property ' ScriptForge.SF_Region.DecimalPoint (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get Language(Optional ByVal Region As Variant) As String
|
||||
''' Returns the english Language name applicable in the given region.
|
||||
''' The region expressed as a
|
||||
''' - locale combining language-COUNTRY (la-CO)
|
||||
''' - language only (la)
|
||||
''' Example:
|
||||
''' MsgBox Regio.Language("it-IT") ' Italian
|
||||
Language = _PropertyGet("Language", Region)
|
||||
End Property ' ScriptForge.SF_Region.Language (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get ListSeparator(Optional ByVal Region As Variant) As String
|
||||
''' Returns the separator used in lists applicable in the given region.
|
||||
''' The region is expressed as a locale combining language-COUNTRY (la-CO)
|
||||
''' Example:
|
||||
''' MsgBox Regio.ListSeparator("it-IT") ' ;
|
||||
ListSeparator = _PropertyGet("ListSeparator", Region)
|
||||
End Property ' ScriptForge.SF_Region.ListSeparator (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function MonthAbbrevNames(Optional ByVal Region As Variant) As Variant ' Function better than Property when return value is an array
|
||||
''' Returns list of abbreviated names of months applicable in the given region.
|
||||
''' The region expressed as a
|
||||
''' - locale combining language-COUNTRY (la-CO)
|
||||
''' - language only (la)
|
||||
''' The list is zero-based.
|
||||
''' Example:
|
||||
''' MsgBox Join(Regio.MonthAbbrevNames("it-IT"), ",") ' gen,feb,mar,apr,mag,giu,lug,ago,set,ott,nov,dic
|
||||
MonthAbbrevNames = _PropertyGet("MonthAbbrevNames", Region)
|
||||
End Function ' ScriptForge.SF_Region.MonthAbbrevNames (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function MonthNames(Optional ByVal Region As Variant) As Variant ' Function better than Property when return value is an array
|
||||
''' Returns list of names of months applicable in the given region.
|
||||
''' The region expressed as a
|
||||
''' - locale combining language-COUNTRY (la-CO)
|
||||
''' - language only (la)
|
||||
''' The list is zero-based.
|
||||
''' Example:
|
||||
''' MsgBox Join(Regio.MonthNames("it-IT"), ",") ' gennaio,febbraio,marzo,aprile,maggio,giugno,luglio,agosto,settembre,ottobre,novembre,dicembre
|
||||
MonthNames = _PropertyGet("MonthNames", Region)
|
||||
End Function ' ScriptForge.SF_Region.MonthNames (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function MonthNarrowNames(Optional ByVal Region As Variant) As Variant ' Function better than Property when return value is an array
|
||||
''' Returns list of initials of months applicable in the given region.
|
||||
''' The region expressed as a
|
||||
''' - locale combining language-COUNTRY (la-CO)
|
||||
''' - language only (la)
|
||||
''' The list is zero-based.
|
||||
''' Example:
|
||||
''' MsgBox Join(Regio.MonthNarrowNames("it-IT"), ",") ' g,f,m,a,m,g,l,a,s,o,n,d
|
||||
MonthNarrowNames = _PropertyGet("MonthNarrowNames", Region)
|
||||
End Function ' ScriptForge.SF_Region.MonthNarrowNames (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get ObjectType As String
|
||||
''' Only to enable object representation
|
||||
ObjectType = "SF_Region"
|
||||
End Property ' ScriptForge.SF_Region.ObjectType
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get ServiceName As String
|
||||
''' Internal use
|
||||
ServiceName = "ScriptForge.Region"
|
||||
End Property ' ScriptForge.SF_Region.ServiceName
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get ThousandSeparator(Optional ByVal Region As Variant) As String
|
||||
''' Returns the thousands separator used in numbers applicable in the given region.
|
||||
''' The region is expressed as a locale combining language-COUNTRY (la-CO)
|
||||
''' Example:
|
||||
''' MsgBox Regio.ThousandSeparator("it-IT") ' .
|
||||
ThousandSeparator = _PropertyGet("ThousandSeparator", Region)
|
||||
End Property ' ScriptForge.SF_Region.ThousandSeparator (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get TimeSeparator(Optional ByVal Region As Variant) As String
|
||||
''' Returns the separator used to format times applicable in the given region.
|
||||
''' The region is expressed as a locale combining language-COUNTRY (la-CO)
|
||||
''' Example:
|
||||
''' MsgBox Regio.TimeSeparator("it-IT") ' :
|
||||
TimeSeparator = _PropertyGet("TimeSeparator", Region)
|
||||
End Property ' ScriptForge.SF_Region.TimeSeparator (get)
|
||||
|
||||
REM ===================================================================== METHODS
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function DSTOffset(Optional ByVal LocalDateTime As Variant _
|
||||
, Optional ByVal TimeZone As Variant _
|
||||
, Optional ByVal Locale As Variant _
|
||||
) As Integer
|
||||
''' Computes the additional offset due to daylight saving ("summer time")
|
||||
''' Args
|
||||
''' LocalDateTime: local date and time as a Date. DST offset varies during the year.
|
||||
''' TimeZone: specified as "Region/City" name like "Europe/Berlin", or a custom time zone ID such as "UTC" or "GMT-8:00"
|
||||
''' Locale: expressed as a locale combining language-COUNTRY (la-CO), or COUNTRY alone (CO)
|
||||
''' Return:
|
||||
''' The offset in minutes
|
||||
''' Examples:
|
||||
''' regio.DSTOffset(DateSerial(2022, 8, 20) + TimeSerial(16, 58, 17), "Europe/Brussels", "fr-BE") ' 60
|
||||
|
||||
Dim iDSTOffset As Integer ' Return value
|
||||
Dim oLocale As Object ' com.sun.star.lang.Locale
|
||||
Dim oCalendarImpl As Object ' com.sun.star.i18n.CalendarImpl
|
||||
Const cstThisSub = "Region.DSTOffset"
|
||||
Const cstSubArgs = "LocalDateTime, TimeZone, [Locale=""""]"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
iDSTOffset = 0
|
||||
|
||||
Check:
|
||||
If IsMissing(Locale) Or IsEmpty(Locale) Then Locale = ""
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(LocalDateTime, "LocalDateTime", V_DATE) Then GoTo Finally
|
||||
If Not SF_Utils._Validate(TimeZone, "TimeZone", V_STRING) Then GoTo Finally
|
||||
If Not SF_Utils._Validate(Locale, "Locale", V_STRING) Then GoTo Finally
|
||||
End If
|
||||
|
||||
Set oLocale = SF_Region._GetLocale(Locale, pbCountry := True)
|
||||
If IsNull(oLocale) Then GoTo Finally
|
||||
|
||||
Try:
|
||||
Set oCalendarImpl = SF_Utils._GetUNOService("CalendarImpl")
|
||||
With oCalendarImpl
|
||||
.loadDefaultCalendarTZ(oLocale, TimeZone)
|
||||
.setLocalDateTime(LocaldateTime)
|
||||
iDSTOffset = .getValue(com.sun.star.i18n.CalendarFieldIndex.DST_OFFSET)
|
||||
End With
|
||||
|
||||
Finally:
|
||||
DSTOffset = iDSTOffset
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Region.DSTOffset
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function GetProperty(Optional ByVal PropertyName As Variant _
|
||||
, Optional Region As Variant _
|
||||
) As Variant
|
||||
''' Return the actual value of the given property
|
||||
''' Args:
|
||||
''' PropertyName: the name of the property as a string
|
||||
''' Region: the language-COUNTRY combination (la-CO) or the country (CO- or the language (la)
|
||||
''' Returns:
|
||||
''' The actual value of the property
|
||||
''' Exceptions:
|
||||
''' ARGUMENTERROR The property does not exist
|
||||
|
||||
Const cstThisSub = "Region.GetProperty"
|
||||
Const cstSubArgs = ""
|
||||
|
||||
If ScriptForge.SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
GetProperty = Null
|
||||
|
||||
Check:
|
||||
If IsMissing(Region) Or IsEmpty(Region) Then Region = ""
|
||||
If ScriptForge.SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not ScriptForge.SF_Utils._Validate(PropertyName, "PropertyName", V_STRING, Properties()) Then GoTo Catch
|
||||
If Not ScriptForge.SF_Utils._Validate(Region, "Region", V_STRING) Then GoTo Catch
|
||||
End If
|
||||
|
||||
Try:
|
||||
If Len(Region) = 0 Then
|
||||
GetProperty = _PropertyGet(PropertyName)
|
||||
Else
|
||||
GetProperty = _PropertyGet(PropertyName, Region)
|
||||
End If
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Region.GetProperty
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function LocalDateTime(Optional ByVal UTCDateTime As Variant _
|
||||
, Optional ByVal TimeZone As Variant _
|
||||
, Optional ByVal Locale As Variant _
|
||||
) As Date
|
||||
''' Computes the local date and time from a UTC date and time
|
||||
''' Args
|
||||
''' UTCDateTime: the universal date and time to be converted to local time
|
||||
''' TimeZone: specified as "Region/City" name like "Europe/Berlin", or a custom time zone ID such as "UTC" or "GMT-8:00"
|
||||
''' Locale: expressed as a locale combining language-COUNTRY (la-CO), or COUNTRY alone (CO)
|
||||
''' Return:
|
||||
''' The local time converted from the corresponding UTC date and time as a Date
|
||||
''' If the returned value is before 1900, it is likely that the Locale is not recognized
|
||||
''' If the returned value matches the local time, it is likely that the timezone is not recognized
|
||||
''' Examples:
|
||||
''' regio.LocalDateTime(DateSerial(2022, 3, 20) + TimeSerial(16, 58, 17), "Europe/Brussels", "fr-BE")
|
||||
''' ' 2022-03-20 17:58:17
|
||||
|
||||
Dim dLocalDateTime As Double ' Return value
|
||||
Dim oLocale As Object ' com.sun.star.lang.Locale
|
||||
Dim oCalendarImpl As Object ' com.sun.star.i18n.CalendarImpl
|
||||
Const cstThisSub = "Region.LocalDateTime"
|
||||
Const cstSubArgs = "UTCDateTime, TimeZone, [Locale=""""]"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
dLocalDateTime = -1
|
||||
|
||||
Check:
|
||||
If IsMissing(Locale) Or IsEmpty(Locale) Then Locale = ""
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(LocalDateTime, "LocalDateTime", V_DATE) Then GoTo Finally
|
||||
If Not SF_Utils._Validate(TimeZone, "TimeZone", V_STRING) Then GoTo Finally
|
||||
If Not SF_Utils._Validate(Locale, "Locale", V_STRING) Then GoTo Finally
|
||||
End If
|
||||
|
||||
Set oLocale = SF_Region._GetLocale(Locale, pbCountry := True)
|
||||
If IsNull(oLocale) Then GoTo Finally
|
||||
|
||||
Try:
|
||||
Set oCalendarImpl = SF_Utils._GetUNOService("CalendarImpl")
|
||||
With oCalendarImpl
|
||||
.loadDefaultCalendarTZ(oLocale, TimeZone)
|
||||
.setDateTime(UTCDateTime)
|
||||
dLocalDateTime = .getLocalDateTime()
|
||||
End With
|
||||
|
||||
Finally:
|
||||
LocalDateTime = CDate(dLocalDateTime)
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Region.LocalDateTime
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Methods() As Variant
|
||||
''' Return the list of public methods of the Region class as an array
|
||||
|
||||
Methods = Array( _
|
||||
"DSTOffset" _
|
||||
, "LocalDateTime" _
|
||||
, "Number2Text" _
|
||||
, "TimeZoneOffset" _
|
||||
, "UTCDateTime" _
|
||||
, "UTCNow" _
|
||||
)
|
||||
|
||||
End Function ' ScriptForge.SF_Region.Methods
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Number2Text(Optional ByVal Number As Variant _
|
||||
, Optional ByVal Locale As Variant _
|
||||
) As String
|
||||
''' Convert numbers and money amounts in many languages into words
|
||||
''' Args
|
||||
''' Number: the number to spell out
|
||||
''' Accepted types: strings or numeric values (integer or real numbers)
|
||||
''' When a string, a variety of prefixes is supported
|
||||
''' The string "help" provides helpful tips about allowed prefixes by language
|
||||
''' Example for french
|
||||
''' un, deux, trois
|
||||
''' feminine: une, deux, trois
|
||||
''' masculine: un, deux, trois
|
||||
''' ordinal: premier, deuxième, troisième
|
||||
''' ordinal-feminine: première, deuxième, troisième
|
||||
''' ordinal-masculine: premier, deuxième, troisième
|
||||
''' informal: onze-cents, douze-cents, treize-cents
|
||||
''' Numbers may be prefixed by ISO currency codes (EUR, USD, ...)
|
||||
''' Locale: expressed as a locale combining language-COUNTRY (la-CO), or language alone (la)
|
||||
''' The list of supported languages can be found on
|
||||
''' https://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1linguistic2_1_1XNumberText.html
|
||||
''' Return:
|
||||
''' The number or amount transformed in words
|
||||
''' Examples:
|
||||
''' regio.Number2Text("help", "fr") ' See above
|
||||
''' regio.Number2Text("79,93", "fr-BE") ' septante-neuf virgule nonante-trois
|
||||
''' regio.Number2Text(Pi(), "pt-BR") ' três vírgula um quatro um cinco nove dois seis cinco três cinco oito nove sete nove
|
||||
''' regio.Number2Text("EUR 1234.56", "it") ' milleduecentotrentaquattro euro cinquantasei centesimi
|
||||
|
||||
Dim sNumber2Text As String ' Return value
|
||||
Dim oLocale As Object ' com.sun.star.lang.Locale
|
||||
Dim oNumber2Text As Object ' com.sun.star.linguistic2.NumberText
|
||||
Const cstThisSub = "Region.Number2Text"
|
||||
Const cstSubArgs = "Number, [Locale=""""]"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
sNumber2Text = ""
|
||||
|
||||
Check:
|
||||
If IsMissing(Locale) Or IsEmpty(Locale) Then Locale = ""
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(Number, "Number", Array(V_STRING, V_NUMERIC)) Then GoTo Finally
|
||||
If Not SF_Utils._Validate(Locale, "Locale", V_STRING) Then GoTo Finally
|
||||
End If
|
||||
|
||||
Set oLocale = SF_Region._GetLocale(Locale, pbLanguage := True)
|
||||
If IsNull(oLocale) Then GoTo Finally
|
||||
|
||||
Try:
|
||||
Set oNumber2Text = SF_Utils._GetUNOService("Number2Text")
|
||||
sNumber2Text = oNumber2Text.getNumberText(Number, oLocale)
|
||||
|
||||
Finally:
|
||||
Number2Text = sNumber2Text
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Region.Number2Text
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Properties() As Variant
|
||||
''' Return the list or properties of the Region class as an array
|
||||
|
||||
Properties = Array( _
|
||||
"Country" _
|
||||
, "Currency" _
|
||||
, "DatePatterns" _
|
||||
, "DateSeparator" _
|
||||
, "DayAbbrevNames" _
|
||||
, "DayNames" _
|
||||
, "DayNarrowNames" _
|
||||
, "DecimalPoint" _
|
||||
, "Language" _
|
||||
, "ListSeparator" _
|
||||
, "MonthAbbrevNames" _
|
||||
, "MonthNames" _
|
||||
, "MonthNarrowNames" _
|
||||
, "ThousandSeparator" _
|
||||
, "TimeSeparator" _
|
||||
)
|
||||
|
||||
End Function ' ScriptForge.SF_Region.Properties
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function TimeZoneOffset(Optional ByVal TimeZone As Variant _
|
||||
, Optional ByVal Locale As Variant _
|
||||
) As Integer
|
||||
''' Computes the offset between GMT and the given timezone and locale
|
||||
''' Args
|
||||
''' TimeZone: specified as "Region/City" name like "Europe/Berlin", or a custom time zone ID such as "UTC" or "GMT-8:00"
|
||||
''' Locale: expressed as a locale combining language-COUNTRY (la-CO), or COUNTRY alone (CO)
|
||||
''' Return:
|
||||
''' The offset in minutes
|
||||
''' Examples:
|
||||
''' regio.TimeZoneOffset("Europe/Brussels", "fr-BE") ' 60
|
||||
|
||||
Dim iTimeZoneOffset As Integer ' Return value
|
||||
Dim oLocale As Object ' com.sun.star.lang.Locale
|
||||
Dim oCalendarImpl As Object ' com.sun.star.i18n.CalendarImpl
|
||||
Const cstThisSub = "Region.TimeZoneOffset"
|
||||
Const cstSubArgs = "TimeZone, [Locale=""""]"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
iTimeZoneOffset = 0
|
||||
|
||||
Check:
|
||||
If IsMissing(Locale) Or IsEmpty(Locale) Then Locale = ""
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(TimeZone, "TimeZone", V_STRING) Then GoTo Finally
|
||||
If Not SF_Utils._Validate(Locale, "Locale", V_STRING) Then GoTo Finally
|
||||
End If
|
||||
|
||||
Set oLocale = SF_Region._GetLocale(Locale, pbCountry := True)
|
||||
If IsNull(oLocale) Then GoTo Finally
|
||||
|
||||
Try:
|
||||
Set oCalendarImpl = SF_Utils._GetUNOService("CalendarImpl")
|
||||
With oCalendarImpl
|
||||
.loadDefaultCalendarTZ(oLocale, TimeZone)
|
||||
iTimeZoneOffset = .getValue(com.sun.star.i18n.CalendarFieldIndex.ZONE_OFFSET)
|
||||
End With
|
||||
|
||||
Finally:
|
||||
TimeZoneOffset = iTimeZoneOffset
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Region.TimeZoneOffset
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function UTCDateTime(Optional ByVal LocalDateTime As Variant _
|
||||
, Optional ByVal TimeZone As Variant _
|
||||
, Optional ByVal Locale As Variant _
|
||||
) As Date
|
||||
''' Computes the UTC date and time of a given local date and time
|
||||
''' Args
|
||||
''' LocalDateTime: the date and time measured in a given timezone
|
||||
''' TimeZone: specified as "Region/City" name like "Europe/Berlin", or a custom time zone ID such as "UTC" or "GMT-8:00"
|
||||
''' Locale: expressed as a locale combining language-COUNTRY (la-CO), or COUNTRY alone (CO)
|
||||
''' Return:
|
||||
''' The local time converted to the corresponding UTC date and time as a Date
|
||||
''' If the returned value is before 1900, it is likely that the Locale is not recognized
|
||||
''' If the returned value matches the local time, it is likely that the the timezone is not recognized
|
||||
''' Examples:
|
||||
''' regio.UTCDateTime(DateSerial(2022, 3, 20) + TimeSerial(17, 58, 17), "Europe/Brussels", "fr-BE")
|
||||
''' ' 2022-03-20 16:58:17
|
||||
|
||||
Dim dUTCDateTime As Double ' Return value
|
||||
Dim oLocale As Object ' com.sun.star.lang.Locale
|
||||
Dim oCalendarImpl As Object ' com.sun.star.i18n.CalendarImpl
|
||||
Const cstThisSub = "Region.UTCDateTime"
|
||||
Const cstSubArgs = "LocalDateTime, TimeZone, [Locale=""""]"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
dUTCDateTime = -1
|
||||
|
||||
Check:
|
||||
If IsMissing(Locale) Or IsEmpty(Locale) Then Locale = ""
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(LocalDateTime, "LocalDateTime", V_DATE) Then GoTo Finally
|
||||
If Not SF_Utils._Validate(TimeZone, "TimeZone", V_STRING) Then GoTo Finally
|
||||
If Not SF_Utils._Validate(Locale, "Locale", V_STRING) Then GoTo Finally
|
||||
End If
|
||||
|
||||
Set oLocale = SF_Region._GetLocale(Locale, pbCountry := True)
|
||||
If IsNull(oLocale) Then GoTo Finally
|
||||
|
||||
Try:
|
||||
Set oCalendarImpl = SF_Utils._GetUNOService("CalendarImpl")
|
||||
With oCalendarImpl
|
||||
.loadDefaultCalendarTZ(oLocale, TimeZone)
|
||||
.setLocalDateTime(LocalDateTime)
|
||||
dUTCDateTime = .getDateTime()
|
||||
End With
|
||||
|
||||
Finally:
|
||||
UTCDateTime = CDate(dUTCDateTime)
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Region.UTCDateTime
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function UTCNow(Optional ByVal TimeZone As Variant _
|
||||
, Optional ByVal Locale As Variant _
|
||||
) As Date
|
||||
''' Computes the actual UTC date and time
|
||||
''' Args
|
||||
''' TimeZone: specified as "Region/City" name like "Europe/Berlin", or a custom time zone ID such as "UTC" or "GMT-8:00"
|
||||
''' Locale: expressed as a locale combining language-COUNTRY (la-CO), or COUNTRY alone (CO)
|
||||
''' Return:
|
||||
''' The actual UTC date and time as a Date
|
||||
''' If the returned value is before 1900, it is likely that the Locale is not recognized
|
||||
''' If the returned value matches the local time, it is likely that the the timezone is not recognized
|
||||
''' Examples:
|
||||
''' regio.UTCNow("Europe/Brussels", "fr-BE") ' 2022-03-20 16:58:17
|
||||
|
||||
Dim dUTCNow As Double ' Return value
|
||||
Dim oLocale As Object ' com.sun.star.lang.Locale
|
||||
Dim oCalendarImpl As Object ' com.sun.star.i18n.CalendarImpl
|
||||
Const cstThisSub = "Region.UTCNow"
|
||||
Const cstSubArgs = "TimeZone, [Locale=""""]"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
dUTCNow = -1
|
||||
|
||||
Check:
|
||||
If IsMissing(Locale) Or IsEmpty(Locale) Then Locale = ""
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(TimeZone, "TimeZone", V_STRING) Then GoTo Finally
|
||||
If Not SF_Utils._Validate(Locale, "Locale", V_STRING) Then GoTo Finally
|
||||
End If
|
||||
|
||||
Set oLocale = SF_Region._GetLocale(Locale, pbCountry := True)
|
||||
If IsNull(oLocale) Then GoTo Finally
|
||||
|
||||
Try:
|
||||
Set oCalendarImpl = SF_Utils._GetUNOService("CalendarImpl")
|
||||
With oCalendarImpl
|
||||
.loadDefaultCalendarTZ(oLocale, TimeZone)
|
||||
.setLocalDateTime(Now())
|
||||
dUTCNow = .getDateTime()
|
||||
End With
|
||||
|
||||
Finally:
|
||||
UTCNow = CDate(dUTCNow)
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Region.UTCNow
|
||||
|
||||
REM =========================================================== PRIVATE FUNCTIONS
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Function _GetLocale(ByVal psLocale As String _
|
||||
, Optional ByVal pbCountry As Variant _
|
||||
, Optional ByVal pbLanguage As Variant _
|
||||
) As Object
|
||||
''' Convert a locale given as a string to a com.sun.star.lang.Locale object
|
||||
''' Args:
|
||||
''' psLocale: the input string, as "la-CO", "la" or "CO"
|
||||
''' pbCountry: True when "CO" only is admitted
|
||||
''' pbLanguage: True when "la" only is admitted
|
||||
''' At most one out of pbLanguage or pbCountry may be True
|
||||
''' Returns:
|
||||
''' com.sun.star.lang.Locale
|
||||
|
||||
Dim sLocale As String ' "la-CO"
|
||||
Dim iLocale As Integer ' Index in reference tables
|
||||
Dim oLocale As Object ' Return value com.sun.star.lang.Locale
|
||||
Dim i As Integer
|
||||
|
||||
If IsMissing(pbCountry) Or IsEmpty(pbCountry) Then pbCountry = False
|
||||
If IsMissing(pbLanguage) Or IsEmpty(pbLanguage) Then pbLanguage = False
|
||||
|
||||
_LoadAllLocales() ' Initialize locale reference tables
|
||||
|
||||
Check:
|
||||
' The argument may be a language "la", a country "CO" or a Locale "la-CO"
|
||||
' Scan the reference tables to find a valid locale as a com.sun.star.lang.Locale
|
||||
Set oLocale = Nothing : sLocale = "" : iLocale = -1
|
||||
If Len(psLocale) = 0 Then ' Default value is the office com.sun.star.i18n.Locale
|
||||
sLocale = UserLocale
|
||||
iLocale = UserIndex
|
||||
ElseIf InStr(psLocale, "-") = 0 Then ' Language only or country only
|
||||
Select Case True
|
||||
Case pbLanguage
|
||||
' Find any locale having the argument as language
|
||||
For i = 0 To UBound(LocaleNames)
|
||||
' A language is presumed 2 or 3 characters long
|
||||
If Split(LocaleNames(i), "-")(0) = LCase(psLocale) Then
|
||||
sLocale = LocaleNames(i)
|
||||
iLocale = i
|
||||
Exit For
|
||||
End If
|
||||
Next i
|
||||
Case pbCountry
|
||||
' Find any locale having the argument as country
|
||||
For i = 0 To UBound(LocaleNames)
|
||||
' A country is presumed exactly 2 characters long
|
||||
If Right(LocaleNames(i), 2) = UCase(psLocale) Then
|
||||
sLocale = LocaleNames(i)
|
||||
iLocale = i
|
||||
Exit For
|
||||
End If
|
||||
Next i
|
||||
Case Else
|
||||
End Select
|
||||
Else ' A full locale is given
|
||||
iLocale = SF_Array.IndexOf(LocaleNames, psLocale, CaseSensitive := False)
|
||||
If iLocale >= 0 Then sLocale = LocaleNames(iLocale)
|
||||
End If
|
||||
|
||||
Try:
|
||||
' Build error message when relevant
|
||||
If iLocale < 0 Then
|
||||
If Not SF_Utils._Validate(psLocale, "Locale", V_STRING, LocaleNames) Then GoTo Finally
|
||||
Else
|
||||
Set oLocale = CreateUnoStruct("com.sun.star.lang.Locale")
|
||||
oLocale.Language = Split(sLocale, "-")(0) ' A language is 2 or 3 characters long
|
||||
oLocale.Country = Right(sLocale, 2)
|
||||
End If
|
||||
|
||||
Finally:
|
||||
Set _GetLocale = oLocale
|
||||
Exit Function
|
||||
End Function ' ScriptForge.SF_Region._GetLocale
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Sub _LoadAllLocales()
|
||||
''' Initialize the LocaleNames array = the list of all available locales in the LibreOffice installation
|
||||
|
||||
Dim oOffice As Object ' com.sun.star.lang.Locale
|
||||
Dim vLocales As Variant ' Array of com.sun.star.lang.Locale
|
||||
Dim iTop As Integer ' Upper bound of LocaleNames
|
||||
Dim i As Integer
|
||||
|
||||
Try:
|
||||
' Office locale
|
||||
If Len(UserLocale) = 0 Then
|
||||
Set oOffice = SF_Utils._GetUNOService("OfficeLocale")
|
||||
UserLocale = oOffice.Language & "-" & oOffice.Country
|
||||
End If
|
||||
|
||||
' LocaleData, localeNames and UserIndex
|
||||
If IsEmpty(LocaleData) Or IsNull(LocaleData) Or Not IsArray(LocaleNames) Then
|
||||
LocaleData = SF_Utils._GetUNOService("LocaleData")
|
||||
vLocales = LocaleData.getAllInstalledLocaleNames()
|
||||
LocaleNames = Array()
|
||||
iTop = UBound(vLocales)
|
||||
ReDim LocaleNames(0 To iTop)
|
||||
For i = 0 To iTop
|
||||
LocaleNames(i) = vLocales(i).Language & "-" & vLocales(i).Country
|
||||
If LocaleNames(i) = UserLocale Then UserIndex = i
|
||||
Next i
|
||||
End If
|
||||
|
||||
End Sub ' ScriptForge.SF_Region._LoadAllLocales
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Function _PropertyGet(Optional ByVal psProperty As String _
|
||||
, Optional ByVal pvLocale As Variant) As Variant
|
||||
''' Return the value of the named property
|
||||
''' Args:
|
||||
''' psProperty: the name of the property
|
||||
''' pvLocale: a locale in the form language-COUNTRY (la-CO) or language only, or country only
|
||||
''' When language or country only, any locale matching either the language or the country is selected
|
||||
|
||||
Dim oLocale As Object ' com.sun.star.lang.Locale
|
||||
Dim vCurrencies As Variant ' Array of com.sun.star.i18n.Currency
|
||||
Dim oCurrency As Object ' com.sun.star.i18n.Currency
|
||||
Dim oLanguageCountryInfo As Object ' com.sun.star.i18n.LanguageCountryInfo
|
||||
Dim oLocaleDataItem2 As Object ' com.sun.star.i18n.LocaleDataItem2
|
||||
Dim oCalendarImpl As Object ' com.sun.star.i18n.CalendarImpl
|
||||
Dim oCalItem As Object ' com.sun.star.i18n.CalendarItem2
|
||||
Dim vCalItems() As Variant ' Array of days/months
|
||||
Dim i As Integer, j As Integer
|
||||
|
||||
Dim cstThisSub As String
|
||||
Const cstSubArgs = ""
|
||||
|
||||
cstThisSub = "Region.Get" & psProperty
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Check:
|
||||
If IsMissing(pvLocale) Or IsEmpty(pvLocale) Then pvLocale = ""
|
||||
If Not SF_Utils._Validate(pvLocale, "Locale", V_STRING) Then GoTo Finally
|
||||
|
||||
Select Case psProperty
|
||||
Case "Currency", "Country"
|
||||
Set oLocale = SF_Region._GetLocale(pvLocale, pbCountry := True) ' Country only is admitted
|
||||
Case "Language", "DayNames", "DayAbbrevNames", "DayNarrowNames" _
|
||||
, "MonthNames", "MonthAbbrevNames", "MonthNarrowNames"
|
||||
Set oLocale = SF_Region._GetLocale(pvLocale, pbLanguage := True) ' Language only is admitted
|
||||
Case Else
|
||||
Set oLocale = SF_Region._GetLocale(pvLocale)
|
||||
End Select
|
||||
If IsNull(oLocale) Then GoTo Finally
|
||||
|
||||
Try:
|
||||
Select Case psProperty
|
||||
Case "Country", "Language"
|
||||
Set oLanguageCountryInfo = LocaleData.getLanguageCountryInfo(oLocale)
|
||||
With oLanguageCountryInfo
|
||||
If psProperty = "Country" Then _PropertyGet = .CountryDefaultName Else _PropertyGet = .LanguageDefaultName
|
||||
End With
|
||||
Case "Currency"
|
||||
vCurrencies = LocaleData.getAllCurrencies(oLocale)
|
||||
_PropertyGet = ""
|
||||
For Each oCurrency In vCurrencies
|
||||
If oCurrency.Default Then
|
||||
_PropertyGet = oCurrency.BankSymbol
|
||||
Exit For
|
||||
End If
|
||||
Next oCurrency
|
||||
Case "DatePatterns"
|
||||
_PropertyGet = LocaleData.getDateAcceptancePatterns(oLocale)
|
||||
Case "DateSeparator", "DecimalPoint", "ListSeparator", "ThousandSeparator", "TimeSeparator"
|
||||
Set oLocaleDataItem2 = LocaleData.getLocaleItem2(oLocale)
|
||||
With oLocaleDataItem2
|
||||
Select Case psProperty
|
||||
Case "DateSeparator" : _PropertyGet = .dateSeparator
|
||||
Case "DecimalPoint" : _PropertyGet = .decimalSeparator
|
||||
Case "ListSeparator" : _PropertyGet = .listSeparator
|
||||
Case "ThousandSeparator" : _PropertyGet = .thousandSeparator
|
||||
Case "TimeSeparator" : _PropertyGet = .timeSeparator
|
||||
End Select
|
||||
End With
|
||||
Case "DayAbbrevNames", "DayNames", "DayNarrowNames"
|
||||
Set oCalendarImpl = SF_Utils._GetUNOService("CalendarImpl")
|
||||
With oCalendarImpl
|
||||
.loadDefaultCalendar(oLocale)
|
||||
vCalItems = Array() : ReDim vCalItems(0 To 6)
|
||||
For i = 0 To UBound(.Days2)
|
||||
Set oCalItem = .Days2(i)
|
||||
j = Iif(i = 0, 6, i - 1)
|
||||
Select Case psProperty
|
||||
Case "DayNames" : vCalItems(j) = oCalItem.FullName
|
||||
Case "DayAbbrevNames" : vCalItems(j) = oCalItem.AbbrevName
|
||||
Case "DayNarrowNames" : vCalItems(j) = oCalItem.NarrowName
|
||||
End Select
|
||||
Next i
|
||||
_PropertyGet = vCalItems
|
||||
End With
|
||||
Case "MonthAbbrevNames", "MonthNames", "MonthNarrowNames"
|
||||
Set oCalendarImpl = SF_Utils._GetUNOService("CalendarImpl")
|
||||
With oCalendarImpl
|
||||
.loadDefaultCalendar(oLocale)
|
||||
vCalItems = Array() : ReDim vCalItems(0 To 11)
|
||||
For i = 0 To UBound(.Months2)
|
||||
Set oCalItem = .Months2(i)
|
||||
Select Case psProperty
|
||||
Case "MonthNames" : vCalItems(i) = oCalItem.FullName
|
||||
Case "MonthAbbrevNames" : vCalItems(i) = oCalItem.AbbrevName
|
||||
Case "MonthNarrowNames" : vCalItems(i) = oCalItem.NarrowName
|
||||
End Select
|
||||
Next i
|
||||
_PropertyGet = vCalItems
|
||||
End With
|
||||
Case Else
|
||||
_PropertyGet = ""
|
||||
End Select
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
End Function ' ScriptForge.SF_Region._PropertyGet
|
||||
|
||||
REM ================================================ END OF SCRIPTFORGE.SF_REGION
|
||||
</script:module>
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,639 @@
|
||||
<?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_Services" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
|
||||
REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
|
||||
REM === Full documentation is available on https://help.libreoffice.org/ ===
|
||||
REM =======================================================================================================================
|
||||
|
||||
Option Compatible
|
||||
Option Explicit
|
||||
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
''' SF_Services
|
||||
''' ===========
|
||||
''' Singleton class implementing the "ScriptForge.Services" service
|
||||
''' Implemented as a usual Basic module
|
||||
''' The ScriptForge framework includes
|
||||
''' the current ScriptForge library
|
||||
''' a number of "associated" libraries
|
||||
''' any user/contributor extension wanting to fit into the framework
|
||||
''' The methods in this module constitute the kernel of the ScriptForge framework
|
||||
''' - RegisterScriptServices
|
||||
''' Register for a library the list of services it implements
|
||||
''' Each library in the framework must implement its own RegisterScriptServices method
|
||||
''' This method consists in a series of invocations of next 2 methods
|
||||
''' - RegisterService
|
||||
''' Register a single service
|
||||
''' - RegisterEventManager
|
||||
''' Register a single event manager
|
||||
''' - CreateScriptService
|
||||
''' Called by user scripts to get an object giving access to a service or to the event manager
|
||||
'''
|
||||
''' Detailed user documentation:
|
||||
''' https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03/sf_services.html?DbPAR=BASIC
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
REM ================================================================== EXCEPTIONS
|
||||
|
||||
Const UNKNOWNSERVICEERROR = "UNKNOWNSERVICEERROR" ' Service not found within the registered services of the given library
|
||||
Const SERVICESNOTLOADEDERROR = "SERVICESNOTLOADEDERROR" ' Failure during the registering of the services of the given library
|
||||
Const UNKNOWNFILEERROR = "UNKNOWNFILEERROR" ' Source file does not exist
|
||||
|
||||
REM ============================================================== PUBLIC MEMBERS
|
||||
|
||||
' Defines an entry in in the services dictionary
|
||||
Type _Service
|
||||
ServiceName As String
|
||||
ServiceType As Integer
|
||||
' 0 Undefined
|
||||
' 1 Basic module
|
||||
' 2 Method reference as a string
|
||||
ServiceReference As Object
|
||||
ServiceMethod As String
|
||||
EventManager As Boolean ' True if registered item is an event manager
|
||||
End Type
|
||||
|
||||
Private vServicesArray As Variant ' List of services registered by a library
|
||||
|
||||
REM ============================================================== PUBLIC METHODS
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function CreateScriptService(Optional ByRef Service As Variant _
|
||||
, ParamArray pvArgs As Variant _
|
||||
) As Variant
|
||||
''' Create access to the services of a library for the benefit of a user script
|
||||
''' A service is to understand either:
|
||||
''' as a set of methods gathered in a Basic standard module
|
||||
''' or a set of methods and properties gathered in a Basic class module
|
||||
''' Args:
|
||||
''' Service: the name of the service in 2 parts "library.service"
|
||||
''' The library is a Basic library that must exist in the GlobalScope
|
||||
''' (default = "ScriptForge")
|
||||
''' The service is one of the services registered by the library
|
||||
''' thru the RegisterScriptServices() routine
|
||||
''' pvArgs: a set of arguments passed to the constructor of the service
|
||||
''' This is only possible if the service refers to a Basic class module
|
||||
''' Returns
|
||||
''' The object containing either the reference of the Basic module
|
||||
''' or of the Basic class instance
|
||||
''' Both are Basic objects
|
||||
''' Returns Nothing if an error occurred.
|
||||
''' ==>> NOTE: The error can be within the user script creating the new class instance
|
||||
''' Exceptions:
|
||||
''' SERVICESNOTLOADEDERROR RegisterScriptService probable failure
|
||||
''' UNKNOWNSERVICEERROR Service not found
|
||||
''' Examples
|
||||
''' CreateScriptService("Array")
|
||||
''' => Refers to ScriptForge.Array or SF_Array
|
||||
''' CreateScriptService("ScriptForge.Dictionary")
|
||||
''' => Returns a new empty dictionary; "ScriptForge." is optional
|
||||
''' CreateScriptService("SFDocuments.Calc")
|
||||
''' => Refers to the Calc service, implemented in the SFDocuments library
|
||||
''' CreateScriptService("Dialog", dlgName)
|
||||
''' => Returns a Dialog instance referring to the dlgName dialog
|
||||
''' CreateScriptService("SFDocuments.Event", oEvent)
|
||||
''' => Refers to the Document service instance, implemented in the SFDocuments library, having triggered the event
|
||||
|
||||
Dim vScriptService As Variant ' Return value
|
||||
Dim vServiceItem As Variant ' A single service (see _Service type definition)
|
||||
Dim vServicesList As Variant ' Output of RegisterScriptServices
|
||||
Dim vSplit As Variant ' Array to split argument in
|
||||
Dim sLibrary As String ' Library part of the argument
|
||||
Dim sService As String ' Service part of the argument
|
||||
Dim vLibrary As Variant ' Dictionary of libraries
|
||||
Dim vService As Variant ' An individual service object
|
||||
Const cstThisSub = "SF_Services.CreateScriptService"
|
||||
Const cstSubArgs = "Service, arg0[, arg1] ..."
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
Set vScriptService = Nothing
|
||||
|
||||
Check:
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(Service, "Service", V_STRING) Then GoTo Catch
|
||||
If Len(Service) = 0 Then GoTo CatchNotFound
|
||||
End If
|
||||
|
||||
Try:
|
||||
' Initialize the list of services when CreateScriptService called for the very 1st time
|
||||
If IsEmpty(_SF_.ServicesList) Then _SF_.ServicesList = SF_Services._NewDictionary()
|
||||
|
||||
' Simple parsing of argument
|
||||
vSplit = Split(Service, ".")
|
||||
If UBound(vSplit) > 1 Then GoTo CatchNotFound
|
||||
If UBound(vSplit) = 0 Then
|
||||
sLibrary = "ScriptForge" ' Yes, the default value !
|
||||
sService = vSplit(0)
|
||||
' Accept other default values for associated libraries
|
||||
Select Case LCase(sService)
|
||||
Case "document", "calc", "writer", "base", "documentevent", "formevent"
|
||||
sLibrary = "SFDocuments"
|
||||
Case "dialog", "dialogevent" : sLibrary = "SFDialogs"
|
||||
Case "database", "datasheet" : sLibrary = "SFDatabases"
|
||||
Case "unittest" : sLibrary = "SFUnitTests"
|
||||
Case "menu", "popupmenu" : sLibrary = "SFWidgets"
|
||||
Case Else
|
||||
End Select
|
||||
Else
|
||||
sLibrary = vSplit(0)
|
||||
sService = vSplit(1)
|
||||
End If
|
||||
|
||||
With _SF_.ServicesList
|
||||
|
||||
' Load the set of services from the library, if not yet done
|
||||
If Not .Exists(sLibrary) Then
|
||||
If Not SF_Services._LoadLibraryServices(sLibrary) Then GoTo CatchNotLoaded
|
||||
End If
|
||||
|
||||
' Find and return the requested service
|
||||
vServicesList = .Item(sLibrary)
|
||||
If Not vServicesList.Exists(sService) Then GoTo CatchNotFound
|
||||
vServiceItem = vServicesList.Item(sService)
|
||||
Select Case vServiceItem.ServiceType
|
||||
Case 1 ' Basic module
|
||||
vScriptService = vServiceItem.ServiceReference
|
||||
Case 2 ' Method to call
|
||||
If sLibrary = "ScriptForge" Then ' Direct call
|
||||
Select Case UCase(sService)
|
||||
Case "DICTIONARY" : vScriptService = SF_Services._NewDictionary()
|
||||
Case "L10N" : vScriptService = SF_Services._NewL10N(pvArgs)
|
||||
Case "TIMER" : vScriptService = SF_Services._NewTimer(pvArgs)
|
||||
Case Else
|
||||
End Select
|
||||
Else ' Call via script provider
|
||||
Set vService = SF_Session._GetScript("Basic", SF_Session.SCRIPTISAPPLICATION, vServiceItem.ServiceMethod)
|
||||
vScriptService = vService.Invoke(Array(pvArgs()), Array(), Array())
|
||||
End If
|
||||
Case Else
|
||||
End Select
|
||||
|
||||
End With
|
||||
|
||||
Finally:
|
||||
CreateScriptService = vScriptService
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
CatchNotFound:
|
||||
SF_Exception.RaiseFatal(UNKNOWNSERVICEERROR, "Service", Service, sLibrary, sService)
|
||||
GoTo Finally
|
||||
CatchNotLoaded:
|
||||
SF_Exception.RaiseFatal(SERVICESNOTLOADEDERROR, "Service", Service, sLibrary)
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Services.CreateScriptService
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function RegisterEventManager(Optional ByVal ServiceName As Variant _
|
||||
, Optional ByRef ServiceReference As Variant _
|
||||
) As Boolean
|
||||
''' Register into ScriptForge a new event entry for the library
|
||||
''' from which this method is called
|
||||
''' MUST BE CALLED ONLY from a specific RegisterScriptServices() method
|
||||
''' Usually the method should be called only once by library
|
||||
''' Args:
|
||||
''' ServiceName: the name of the service as a string. It the service exists
|
||||
''' already for the library the method overwrites the existing entry
|
||||
''' ServiceReference: the function which will identify the source of the triggered event
|
||||
''' something like: "libraryname.modulename.function"
|
||||
''' Returns:
|
||||
''' True if successful
|
||||
''' Example:
|
||||
''' ' Code snippet stored in a module contained in the SFDocuments library
|
||||
''' Sub RegisterScriptServices()
|
||||
''' ' Register the events manager of the library
|
||||
''' RegisterEventManager("DocumentEvent", "SFDocuments.SF_Register._EventManager")
|
||||
''' End Sub
|
||||
''' ' Code snippet stored in a user script
|
||||
''' Sub Trigger(poEvent As Object) ' Triggered by a DOCUMENTEVENT event
|
||||
''' Dim myDoc As Object
|
||||
''' ' To get the document concerned by the event:
|
||||
''' Set myDoc = CreateScriptService("SFDocuments.DocumentEvent", poEvent)
|
||||
''' End Sub
|
||||
|
||||
Dim bRegister As Boolean ' Return value
|
||||
Const cstThisSub = "SF_Services.RegisterEventManager"
|
||||
Const cstSubArgs = "ServiceName, ServiceReference"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
bRegister = False
|
||||
|
||||
Check:
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(ServiceName, "ServiceName", V_STRING) Then GoTo Finally
|
||||
If Not SF_Utils._Validate(ServiceReference, "ServiceReference",V_STRING) Then GoTo Finally
|
||||
End If
|
||||
|
||||
Try:
|
||||
bRegister = _AddToServicesArray(ServiceName, ServiceReference, True)
|
||||
|
||||
Finally:
|
||||
RegisterEventManager = bRegister
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Services.RegisterEventManager
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function RegisterService(Optional ByVal ServiceName As Variant _
|
||||
, Optional ByRef ServiceReference As Variant _
|
||||
) As Boolean
|
||||
''' Register into ScriptForge a new service entry for the library
|
||||
''' from which this method is called
|
||||
''' MUST BE CALLED ONLY from a specific RegisterScriptServices() method
|
||||
''' Args:
|
||||
''' ServiceName: the name of the service as a string. It the service exists
|
||||
''' already for the library the method overwrites the existing entry
|
||||
''' ServiceReference: either
|
||||
''' - the Basic module that implements the methods of the service
|
||||
''' something like: GlobalScope.Library.Module
|
||||
''' - an instance of the class implementing the methods and properties of the service
|
||||
''' something like: "libraryname.modulename.function"
|
||||
''' Returns:
|
||||
''' True if successful
|
||||
|
||||
Dim bRegister As Boolean ' Return value
|
||||
Const cstThisSub = "SF_Services.RegisterService"
|
||||
Const cstSubArgs = "ServiceName, ServiceReference"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
bRegister = False
|
||||
|
||||
Check:
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(ServiceName, "ServiceName", V_STRING) Then GoTo Finally
|
||||
If Not SF_Utils._Validate(ServiceReference, "ServiceReference", Array(V_STRING, V_OBJECT)) Then GoTo Finally
|
||||
End If
|
||||
|
||||
Try:
|
||||
bRegister = _AddToServicesArray(ServiceName, ServiceReference, False)
|
||||
|
||||
Finally:
|
||||
RegisterService = bRegister
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Services.RegisterService
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Sub RegisterScriptServices() As Variant
|
||||
''' Register into ScriptForge the list of the services implemented by the current library
|
||||
''' Each library pertaining to the framework must implement its own version of this method
|
||||
''' This method may be stored in any standard (i.e. not class-) module
|
||||
'''
|
||||
''' Each individual service is registered by calling the RegisterService() method
|
||||
'''
|
||||
''' The current version is given as an example
|
||||
'''
|
||||
With GlobalScope.ScriptForge.SF_Services
|
||||
.RegisterService("Array", GlobalScope.ScriptForge.SF_Array) ' Reference to the Basic module
|
||||
.RegisterService("Dictionary", "ScriptForge.SF_Services._NewDictionary") ' Reference to the function initializing the service
|
||||
.RegisterService("Exception", GlobalScope.ScriptForge.SF_Exception)
|
||||
.RegisterService("FileSystem", GlobalScope.ScriptForge.SF_FileSystem)
|
||||
.RegisterService("L10N", "ScriptForge.SF_Services._NewL10N")
|
||||
.RegisterService("Platform", GlobalScope.ScriptForge.SF_Platform)
|
||||
.RegisterService("Region", GlobalScope.ScriptForge.SF_Region)
|
||||
.RegisterService("Session", GlobalScope.ScriptForge.SF_Session)
|
||||
.RegisterService("String", GlobalScope.ScriptForge.SF_String)
|
||||
.RegisterService("Timer", "ScriptForge.SF_Services._NewTimer")
|
||||
.RegisterService("UI", GlobalScope.ScriptForge.SF_UI)
|
||||
'TODO
|
||||
End With
|
||||
|
||||
End Sub ' ScriptForge.SF_Services.RegisterScriptServices
|
||||
|
||||
REM =========================================================== PRIVATE FUNCTIONS
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Function _AddToServicesArray(ByVal psServiceName As String _
|
||||
, ByRef pvServiceReference As Variant _
|
||||
, ByVal pbEvent As Boolean _
|
||||
) As Boolean
|
||||
''' Add the arguments as an additional row in vServicesArray (Public variable)
|
||||
''' Called from RegisterService and RegisterEvent methods
|
||||
|
||||
Dim bRegister As Boolean ' Return value
|
||||
Dim lMax As Long ' Number of rows in vServicesArray
|
||||
|
||||
bRegister = False
|
||||
|
||||
Check:
|
||||
' Ignore when method is not called from RegisterScriptServices()
|
||||
If IsEmpty(vServicesArray) Or IsNull(vServicesArray) Or Not IsArray(vServicesArray) Then GoTo Finally
|
||||
|
||||
Try:
|
||||
lMax = UBound(vServicesArray, 1) + 1
|
||||
If lMax <= 0 Then
|
||||
ReDim vServicesArray(0 To 0, 0 To 2)
|
||||
Else
|
||||
ReDim Preserve vServicesArray(0 To lMax, 0 To 2)
|
||||
End If
|
||||
vServicesArray(lMax, 0) = psServiceName
|
||||
vServicesArray(lMax, 1) = pvServiceReference
|
||||
vServicesArray(lMax, 2) = pbEvent
|
||||
bRegister = True
|
||||
|
||||
Finally:
|
||||
_AddToServicesArray = bRegister
|
||||
Exit Function
|
||||
End Function ' ScriptForge.SF_Services._AddToServicesArray
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Function _FindModuleFromMethod(ByVal psLibrary As String _
|
||||
, ByVal psMethod As String _
|
||||
) As String
|
||||
''' Find in the given library the name of the module containing
|
||||
''' the method given as 2nd argument (usually RegisterScriptServices)
|
||||
''' Args:
|
||||
''' psLibrary: the name of the Basic library
|
||||
''' psMethod: the method to locate
|
||||
''' Returns:
|
||||
''' The name of the module or a zero-length string if not found
|
||||
|
||||
Dim vCategories As Variant ' "user" or "share" library categories
|
||||
Dim sCategory As String
|
||||
Dim vLanguages As Variant ' "Basic", "Python", ... programming languages
|
||||
Dim sLanguage As String
|
||||
Dim vLibraries As Variant ' Library names
|
||||
Dim sLibrary As String
|
||||
Dim vModules As Variant ' Module names
|
||||
Dim sModule As String ' Return value
|
||||
Dim vMethods As Variant ' Method/properties/subs/functions
|
||||
Dim sMethod As String
|
||||
Dim oRoot As Object ' com.sun.star.script.browse.BrowseNodeFactory
|
||||
Dim i As Integer, j As Integer, k As Integer, l As Integer, m As Integer
|
||||
|
||||
_FindModuleFromMethod = ""
|
||||
Set oRoot = SF_Utils._GetUNOService("BrowseNodeFactory").createView(com.sun.star.script.browse.BrowseNodeFactoryViewTypes.MACROORGANIZER)
|
||||
|
||||
' Exploration is done via tree nodes
|
||||
If Not IsNull(oRoot) Then
|
||||
If oRoot.hasChildNodes() Then
|
||||
vCategories = oRoot.getChildNodes()
|
||||
For i = 0 To UBound(vCategories)
|
||||
sCategory = vCategories(i).getName()
|
||||
' Consider "My macros & Dialogs" and "LibreOffice Macros & Dialogs" only
|
||||
If sCategory = "user" Or sCategory = "share" Then
|
||||
If vCategories(i).hasChildNodes() Then
|
||||
vLanguages = vCategories(i).getChildNodes()
|
||||
For j = 0 To UBound(vLanguages)
|
||||
sLanguage = vLanguages(j).getName()
|
||||
' Consider Basic libraries only
|
||||
If sLanguage = "Basic" Then
|
||||
If vLanguages(j).hasChildNodes() Then
|
||||
vLibraries = vLanguages(j).getChildNodes()
|
||||
For k = 0 To UBound(vLibraries)
|
||||
sLibrary = vLibraries(k).getName()
|
||||
' Consider the given library only
|
||||
If sLibrary = psLibrary Then
|
||||
If vLibraries(k).hasChildNodes() Then
|
||||
vModules = vLibraries(k).getChildNodes()
|
||||
For l = 0 To UBound(vModules)
|
||||
sModule = vModules(l).getName()
|
||||
' Check if the module contains the targeted method
|
||||
If vModules(l).hasChildNodes() Then
|
||||
vMethods = vModules(l).getChildNodes()
|
||||
For m = 0 To UBound(vMethods)
|
||||
sMethod = vMethods(m).getName()
|
||||
If sMethod = psMethod Then
|
||||
_FindModuleFromMethod = sModule
|
||||
Exit Function
|
||||
End If
|
||||
Next m
|
||||
End If
|
||||
Next l
|
||||
End If
|
||||
End If
|
||||
Next k
|
||||
End If
|
||||
End If
|
||||
Next j
|
||||
End If
|
||||
End If
|
||||
Next i
|
||||
End If
|
||||
End If
|
||||
|
||||
End Function ' ScriptForge.SF_Services._FindModuleFromMethod
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Function _LoadLibraryServices(ByVal psLibrary As String) As Boolean
|
||||
''' Execute psLibrary.RegisterScriptServices() and load its services into the persistent storage
|
||||
''' Args:
|
||||
''' psLibrary: the name of the Basic library
|
||||
''' Library will be loaded if not yet done
|
||||
''' Returns:
|
||||
''' True if success
|
||||
''' The list of services is loaded directly into the persistent storage
|
||||
|
||||
|
||||
Dim vServicesList As Variant ' Dictionary of services
|
||||
Dim vService As Variant ' Single service entry in dictionary
|
||||
Dim vServiceItem As Variant ' Single service in vServicesArray
|
||||
Dim sModule As String ' Name of module containing the RegisterScriptServices method
|
||||
Dim i As Long
|
||||
Const cstRegister = "RegisterScriptServices"
|
||||
|
||||
Try:
|
||||
_LoadLibraryServices = False
|
||||
|
||||
vServicesArray = Array()
|
||||
|
||||
If psLibrary = "ScriptForge" Then
|
||||
' Direct call
|
||||
ScriptForge.SF_Services.RegisterScriptServices()
|
||||
Else
|
||||
' Register services via script provider
|
||||
If GlobalScope.BasicLibraries.hasByName(psLibrary) Then
|
||||
If Not GlobalScope.BasicLibraries.isLibraryLoaded(psLibrary) Then
|
||||
GlobalScope.BasicLibraries.LoadLibrary(psLibrary)
|
||||
End If
|
||||
Else
|
||||
GoTo Finally
|
||||
End If
|
||||
sModule = SF_Services._FindModuleFromMethod(psLibrary, cstRegister)
|
||||
If Len(sModule) = 0 Then GoTo Finally
|
||||
SF_Session.ExecuteBasicScript(, psLibrary & "." & sModule & "." & cstRegister)
|
||||
End If
|
||||
|
||||
' Store in persistent storage
|
||||
' - Create list of services for the current library
|
||||
Set vServicesList = SF_Services._NewDictionary()
|
||||
For i = 0 To UBound(vServicesArray, 1)
|
||||
Set vService = New _Service
|
||||
With vService
|
||||
.ServiceName = vServicesArray(i, 0)
|
||||
vServiceItem = vServicesArray(i, 1)
|
||||
If VarType(vServiceItem) = V_STRING Then
|
||||
.ServiceType = 2
|
||||
.ServiceMethod = vServiceItem
|
||||
Set .ServiceReference = Nothing
|
||||
Else ' OBJECT
|
||||
.ServiceType = 1
|
||||
.ServiceMethod = ""
|
||||
Set .ServiceReference = vServiceItem
|
||||
End If
|
||||
.EventManager = vServicesArray(i, 2)
|
||||
End With
|
||||
vServicesList.Add(vServicesArray(i, 0), vService)
|
||||
Next i
|
||||
' - Add the new dictionary to the persistent dictionary
|
||||
_SF_.ServicesList.Add(psLibrary, vServicesList)
|
||||
_LoadLibraryServices = True
|
||||
vServicesArray = Empty
|
||||
|
||||
Finally:
|
||||
Exit Function
|
||||
End Function ' ScriptForge.SF_Services._LoadLibraryServices
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function _NewDictionary() As Variant
|
||||
''' Create a new instance of the SF_Dictionary class
|
||||
''' Returns: the instance or Nothing
|
||||
|
||||
Dim oDict As Variant
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
|
||||
Check:
|
||||
|
||||
Try:
|
||||
Set oDict = New SF_Dictionary
|
||||
Set oDict.[Me] = oDict
|
||||
|
||||
Finally:
|
||||
Set _NewDictionary = oDict
|
||||
Exit Function
|
||||
Catch:
|
||||
Set oDict = Nothing
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Services._NewDictionary
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function _NewL10N(Optional ByVal pvArgs As Variant) As Variant
|
||||
''' Create a new instance of the SF_L10N class
|
||||
' Args:
|
||||
''' FolderName: the folder containing the PO files in SF_FileSystem.FileNaming notation
|
||||
''' Locale: locale of user session (default) or any other valid la{nguage]-CO[UNTRY] combination
|
||||
''' The country part is optional. Valid are f.i. "fr", "fr-CH", "en-US"
|
||||
''' Encoding: The character set that should be used
|
||||
''' Use one of the Names listed in https://www.iana.org/assignments/character-sets/character-sets.xhtml
|
||||
''' Note that LibreOffice probably does not implement all existing sets
|
||||
''' Default = UTF-8
|
||||
''' Locale2: fallback Locale to select if Locale po file does not exist (typically "en-US")
|
||||
''' Encoding2: Encoding of the 2nd Locale file
|
||||
''' Returns: the instance or Nothing
|
||||
''' Exceptions:
|
||||
''' UNKNOWNFILEERROR The PO file does not exist
|
||||
|
||||
Dim oL10N As Variant ' Return value
|
||||
Dim sFolderName As String ' Folder containing the PO files
|
||||
Dim sLocale As String ' Passed argument or that of the user session
|
||||
Dim sLocale2 As String ' Alias for Locale2
|
||||
Dim oLocale As Variant ' com.sun.star.lang.Locale
|
||||
Dim sPOFile As String ' PO file must exist
|
||||
Dim sEncoding As String ' Alias for Encoding
|
||||
Dim sEncoding2 As String ' Alias for Encoding2
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
|
||||
Check:
|
||||
If IsMissing(pvArgs) Then pvArgs = Array()
|
||||
sPOFile = ""
|
||||
sEncoding = ""
|
||||
If UBound(pvArgs) >= 0 Then
|
||||
If Not SF_Utils._ValidateFile(pvArgs(0), "Folder (Arg0)", , True) Then GoTo Catch
|
||||
sFolderName = pvArgs(0)
|
||||
sLocale = ""
|
||||
If UBound(pvArgs) >= 1 Then
|
||||
If Not SF_Utils._Validate(pvArgs(1), "Locale (Arg1)", V_STRING) Then GoTo Catch
|
||||
sLocale = pvArgs(1)
|
||||
End If
|
||||
If Len(sLocale) = 0 Then ' Called from Python, the Locale argument may be the zero-length string
|
||||
Set oLocale = SF_Utils._GetUNOService("OfficeLocale")
|
||||
sLocale = oLocale.Language & "-" & oLocale.Country
|
||||
End If
|
||||
If UBound(pvArgs) >= 2 Then
|
||||
If IsMissing(pvArgs(2)) Or IsEmpty(pvArgs(2)) Then pvArgs(2) = "UTF-8"
|
||||
If Not SF_Utils._Validate(pvArgs(2), "Encoding (Arg2)", V_STRING) Then GoTo Catch
|
||||
sEncoding = pvArgs(2)
|
||||
Else
|
||||
sEncoding = "UTF-8"
|
||||
End If
|
||||
sLocale2 = ""
|
||||
If UBound(pvArgs) >= 3 Then
|
||||
If Not SF_Utils._Validate(pvArgs(3), "Locale2 (Arg3)", V_STRING) Then GoTo Catch
|
||||
sLocale2 = pvArgs(3)
|
||||
End If
|
||||
If UBound(pvArgs) >= 4 Then
|
||||
If Not SF_Utils._Validate(pvArgs(4), "Encoding2 (Arg4)", V_STRING) Then GoTo Catch
|
||||
sEncoding2 = pvArgs(4)
|
||||
Else
|
||||
sEncoding2 = "UTF-8"
|
||||
End If
|
||||
If Len(sFolderName) > 0 Then
|
||||
sPOFile = SF_FileSystem.BuildPath(sFolderName, sLocale & ".po")
|
||||
If Not SF_FileSystem.FileExists(sPOFile) Then
|
||||
If Len(sLocale2) = 0 Then GoTo CatchNotExists ' No fallback => error
|
||||
' Try the fallback
|
||||
sPOFile = SF_FileSystem.BuildPath(sFolderName, sLocale2 & ".po")
|
||||
If Not SF_FileSystem.FileExists(sPOFile) Then GoTo CatchNotExists
|
||||
sEncoding = sEncoding2
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
|
||||
Try:
|
||||
Set oL10N = New SF_L10N
|
||||
Set oL10N.[Me] = oL10N
|
||||
oL10N._Initialize(sPOFile, sEncoding)
|
||||
|
||||
Finally:
|
||||
Set _NewL10N = oL10N
|
||||
Exit Function
|
||||
Catch:
|
||||
Set oL10N = Nothing
|
||||
GoTo Finally
|
||||
CatchNotExists:
|
||||
SF_Exception.RaiseFatal(UNKNOWNFILEERROR, "FileName", sPOFile)
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Services._NewL10N
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function _NewTimer(Optional ByVal pvArgs As Variant) As Variant
|
||||
''' Create a new instance of the SF_Timer class
|
||||
''' Args:
|
||||
''' [0] : If True, start the timer immediately
|
||||
''' Returns: the instance or Nothing
|
||||
|
||||
Dim oTimer As Variant ' Return value
|
||||
Dim bStart As Boolean ' Automatic start ?
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
|
||||
Check:
|
||||
If IsMissing(pvArgs) Then pvArgs = Array()
|
||||
If UBound(pvArgs) < 0 Then
|
||||
bStart = False
|
||||
Else
|
||||
If Not SF_Utils._Validate(pvArgs(0), "Start (Arg0)", V_BOOLEAN) Then GoTo Catch
|
||||
bStart = pvArgs(0)
|
||||
End If
|
||||
Try:
|
||||
Set oTimer = New SF_Timer
|
||||
Set oTimer.[Me] = oTimer
|
||||
If bStart Then oTimer.Start()
|
||||
|
||||
Finally:
|
||||
Set _NewTimer = oTimer
|
||||
Exit Function
|
||||
Catch:
|
||||
Set oTimer = Nothing
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Services._NewTimer
|
||||
|
||||
REM ============================================== END OF SCRIPTFORGE.SF_SERVICES
|
||||
</script:module>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,702 @@
|
||||
<?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_TextStream" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
|
||||
REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
|
||||
REM === Full documentation is available on https://help.libreoffice.org/ ===
|
||||
REM =======================================================================================================================
|
||||
|
||||
Option Compatible
|
||||
Option ClassModule
|
||||
|
||||
Option Explicit
|
||||
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
''' SF_TextStream
|
||||
''' =============
|
||||
''' Class instantiated by the
|
||||
''' SF_FileSystem.CreateTextFile
|
||||
''' SF_FileSystem.OpenTextFile
|
||||
''' methods to facilitate the sequential processing of text files
|
||||
''' All open/read/write/close operations are presumed to happen during the same macro run
|
||||
''' The encoding to be used may be chosen by the user
|
||||
''' The list is in the Name column of https://www.iana.org/assignments/character-sets/character-sets.xhtml
|
||||
''' Note that probably not all values are available
|
||||
''' Line delimiters may be chosen by the user
|
||||
''' In input, CR, LF or CR+LF are supported
|
||||
''' In output, the default value is the usual newline on the actual operating system (see SF_FileSystem.sfNEWLINE)
|
||||
'''
|
||||
''' The design choices are largely inspired by
|
||||
''' https://docs.microsoft.com/en-us/office/vba/language/reference/user-interface-help/textstream-object
|
||||
''' The implementation is mainly based on the XTextInputStream and XTextOutputStream UNO interfaces
|
||||
''' https://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1io_1_1XTextInputStream.html
|
||||
''' https://api.libreoffice.org/docs/idl/ref/interfacecom_1_1sun_1_1star_1_1io_1_1XTextOutputStream.html
|
||||
'''
|
||||
''' Instantiation example:
|
||||
''' Dim FSO As Object, myFile As Object
|
||||
''' Set FSO = CreateScriptService("FileSystem")
|
||||
''' Set myFile = FSO.OpenTextFile("C:\Temp\ThisFile.txt", FSO.ForReading) ' Once per file
|
||||
'''
|
||||
''' Detailed user documentation:
|
||||
''' https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03/sf_textstream.html?DbPAR=BASIC
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
REM ================================================================== EXCEPTIONS
|
||||
|
||||
Const FILENOTOPENERROR = "FILENOTOPENERROR" ' The file is already closed
|
||||
Const FILEOPENMODEERROR = "FILEOPENMODEERROR" ' The file is open in incompatible mode
|
||||
Const ENDOFFILEERROR = "ENDOFFILEERROR" ' When file was read, an end-of-file was encountered
|
||||
|
||||
REM ============================================================= PRIVATE MEMBERS
|
||||
|
||||
Private [Me] As Object
|
||||
Private [_Parent] As Object
|
||||
Private ObjectType As String ' Must be TEXTSTREAM
|
||||
Private ServiceName As String
|
||||
Private _FileName As String ' File where it is about
|
||||
Private _IOMode As Integer ' ForReading, ForWriting or ForAppending
|
||||
Private _Encoding As String ' https://www.iana.org/assignments/character-sets/character-sets.xhtml
|
||||
Private _NewLine As String ' Line break in write mode
|
||||
Private _FileExists As Boolean ' True if file exists before open
|
||||
Private _LineNumber As Long ' Number of lines read or written
|
||||
Private _FileHandler As Object ' com.sun.star.io.XInputStream or
|
||||
' com.sun.star.io.XOutputStream or
|
||||
' com.sun.star.io.XStream
|
||||
Private _InputStream As Object ' com.sun.star.io.TextInputStream
|
||||
Private _OutputStream As Object ' com.sun.star.io.TextOutputStream
|
||||
Private _ForceBlankLine As Boolean ' Workaround: XTextInputStream misses last line if file ends with newline
|
||||
|
||||
REM ============================================================ MODULE CONSTANTS
|
||||
|
||||
REM ===================================================== CONSTRUCTOR/DESTRUCTOR
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Sub Class_Initialize()
|
||||
Set [Me] = Nothing
|
||||
Set [_Parent] = Nothing
|
||||
ObjectType = "TEXTSTREAM"
|
||||
ServiceName = "ScriptForge.TextStream"
|
||||
_FileName = ""
|
||||
_IOMode = -1
|
||||
_Encoding = ""
|
||||
_NewLine = ""
|
||||
_FileExists = False
|
||||
_LineNumber = 0
|
||||
Set _FileHandler = Nothing
|
||||
Set _InputStream = Nothing
|
||||
Set _OutputStream = Nothing
|
||||
_ForceBlankLine = False
|
||||
End Sub ' ScriptForge.SF_TextStream Constructor
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Sub Class_Terminate()
|
||||
Call Class_Initialize()
|
||||
End Sub ' ScriptForge.SF_TextStream Destructor
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Dispose() As Variant
|
||||
Call Class_Terminate()
|
||||
Set Dispose = Nothing
|
||||
End Function ' ScriptForge.SF_TextStream Explicit Destructor
|
||||
|
||||
REM ================================================================== PROPERTIES
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get AtEndOfStream() As Boolean
|
||||
''' In reading mode, True indicates that the end of the file has been reached
|
||||
''' In write and append modes, or if the file is not ready => always True
|
||||
''' The property should be invoked BEFORE each ReadLine() method:
|
||||
''' A ReadLine() executed while AtEndOfStream is True will raise an error
|
||||
''' Example:
|
||||
''' Dim sLine As String
|
||||
''' Do While Not myFile.AtEndOfStream
|
||||
''' sLine = myFile.ReadLine()
|
||||
''' ' ...
|
||||
''' Loop
|
||||
|
||||
AtEndOfStream = _PropertyGet("AtEndOfStream")
|
||||
|
||||
End Property ' ScriptForge.SF_TextStream.AtEndOfStream
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get Encoding() As String
|
||||
''' Returns the name of the text file either in url or in native operating system format
|
||||
''' Example:
|
||||
''' Dim myFile As Object
|
||||
''' FSO.FileNaming = "SYS"
|
||||
''' Set myFile = FSO.OpenTextFile("C:\Temp\myFile.txt")
|
||||
''' MsgBox myFile.Encoding ' UTF-8
|
||||
|
||||
Encoding = _PropertyGet("Encoding")
|
||||
|
||||
End Property ' ScriptForge.SF_TextStream.Encoding
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get FileName() As String
|
||||
''' Returns the name of the text file either in url or in native operating system format
|
||||
''' Example:
|
||||
''' Dim myFile As Object
|
||||
''' FSO.FileNaming = "SYS"
|
||||
''' Set myFile = FSO.OpenTextFile("C:\Temp\myFile.txt")
|
||||
''' MsgBox myFile.FileName ' C:\Temp\myFile.txt
|
||||
|
||||
FileName = _PropertyGet("FileName")
|
||||
|
||||
End Property ' ScriptForge.SF_TextStream.FileName
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get IOMode() As String
|
||||
''' Returns either "READ", "WRITE" or "APPEND"
|
||||
''' Example:
|
||||
''' Dim myFile As Object
|
||||
''' FSO.FileNaming = "SYS"
|
||||
''' Set myFile = FSO.OpenTextFile("C:\Temp\myFile.txt")
|
||||
''' MsgBox myFile.IOMode ' READ
|
||||
|
||||
IOMode = _PropertyGet("IOMode")
|
||||
|
||||
End Property ' ScriptForge.SF_TextStream.IOMode
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get Line() As Long
|
||||
''' Returns the number of lines read or written so far
|
||||
''' Example:
|
||||
''' Dim myFile As Object
|
||||
''' FSO.FileNaming = "SYS"
|
||||
''' Set myFile = FSO.OpenTextFile("C:\Temp\myFile.txt", FSO.ForAppending)
|
||||
''' MsgBox myFile.Line ' The number of lines already present in myFile
|
||||
|
||||
Line = _PropertyGet("Line")
|
||||
|
||||
End Property ' ScriptForge.SF_TextStream.Line
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get NewLine() As Variant
|
||||
''' Returns the current character string to be inserted between 2 successive written lines
|
||||
''' The default value is the native line separator in the current operating system
|
||||
''' Example:
|
||||
''' MsgBox myFile.NewLine
|
||||
|
||||
NewLine = _PropertyGet("NewLine")
|
||||
|
||||
End Property ' ScriptForge.SF_TextStream.NewLine (get)
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Let NewLine(ByVal pvLineBreak As Variant)
|
||||
''' Sets the current character string to be inserted between 2 successive written lines
|
||||
''' Example:
|
||||
''' myFile.NewLine = Chr(13) & Chr(10)
|
||||
|
||||
Const cstThisSub = "TextStream.setNewLine"
|
||||
|
||||
SF_Utils._EnterFunction(cstThisSub)
|
||||
If VarType(pvLineBreak) = V_STRING Then _NewLine = pvLineBreak
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
|
||||
End Property ' ScriptForge.SF_TextStream.NewLine (let)
|
||||
|
||||
REM ===================================================================== METHODS
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function CloseFile() As Boolean
|
||||
''' Empties the output buffer if relevant. Closes the actual input or output stream
|
||||
''' Args:
|
||||
''' Returns:
|
||||
''' True if the closure was successful
|
||||
''' Exceptions:
|
||||
''' FILENOTOPENERROR Nothing found to close
|
||||
''' Examples:
|
||||
''' myFile.CloseFile()
|
||||
|
||||
Dim bClose As Boolean ' Return value
|
||||
Const cstThisSub = "TextStream.CloseFile"
|
||||
Const cstSubArgs = ""
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
bClose = False
|
||||
|
||||
Check:
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
If Not _IsFileOpen() Then GoTo Finally
|
||||
|
||||
Try:
|
||||
If Not IsNull(_InputStream) Then _InputStream.closeInput()
|
||||
If Not IsNull(_OutputStream) Then
|
||||
_OutputStream.flush()
|
||||
_OutputStream.closeOutput()
|
||||
End If
|
||||
Set _InputStream = Nothing
|
||||
Set _OutputStream = Nothing
|
||||
Set _FileHandler = Nothing
|
||||
bClose = True
|
||||
|
||||
Finally:
|
||||
CloseFile = bClose
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_TextStream.CloseFile
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function GetProperty(Optional ByVal PropertyName As Variant) As Variant
|
||||
''' Return the actual value of the given property
|
||||
''' Args:
|
||||
''' PropertyName: the name of the property as a string
|
||||
''' Returns:
|
||||
''' The actual value of the property
|
||||
''' If the property does not exist, returns Null
|
||||
''' Exceptions:
|
||||
''' see the exceptions of the individual properties
|
||||
''' Examples:
|
||||
''' myModel.GetProperty("MyProperty")
|
||||
|
||||
Const cstThisSub = "TextStream.GetProperty"
|
||||
Const cstSubArgs = ""
|
||||
|
||||
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, "PropertyName", V_STRING, Properties()) Then GoTo Catch
|
||||
End If
|
||||
|
||||
Try:
|
||||
GetProperty = _PropertyGet(PropertyName)
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_TextStream.GetProperty
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Methods() As Variant
|
||||
''' Return the list of public methods of the Model service as an array
|
||||
|
||||
Methods = Array( _
|
||||
"CloseFile" _
|
||||
, "ReadAll" _
|
||||
, "readLine" _
|
||||
, "SkipLine" _
|
||||
, "WriteBlankLines" _
|
||||
, "WriteLine" _
|
||||
)
|
||||
|
||||
End Function ' ScriptForge.SF_TextStream.Methods
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Properties() As Variant
|
||||
''' Return the list or properties of the Timer class as an array
|
||||
|
||||
Properties = Array( _
|
||||
"AtEndOfStream" _
|
||||
, "Encoding" _
|
||||
, "FileName" _
|
||||
, "IOMode" _
|
||||
, "Line" _
|
||||
, "NewLine" _
|
||||
)
|
||||
|
||||
End Function ' ScriptForge.SF_TextStream.Properties
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function ReadAll() As String
|
||||
''' Returns all the remaining lines in the text stream as one string. Line breaks are NOT removed
|
||||
''' The resulting string can be split in lines
|
||||
''' either by using the usual Split Basic builtin function if the line delimiter is known
|
||||
''' or with the SF_String.SplitLines method
|
||||
''' For large files, using the ReadAll method wastes memory resources.
|
||||
''' Other techniques should be used to input a file, such as reading a file line-by-line
|
||||
''' Args:
|
||||
''' Returns:
|
||||
''' The read lines. The string may be empty.
|
||||
''' Note that the Line property in incremented only by 1
|
||||
''' Exceptions:
|
||||
''' FILENOTOPENERROR File not open or already closed
|
||||
''' FILEOPENMODEERROR File opened in write or append modes
|
||||
''' ENDOFFILEERROR Previous reads already reached the end of the file
|
||||
''' Examples:
|
||||
''' Dim a As String
|
||||
''' a = myFile.ReadAll()
|
||||
|
||||
Dim sRead As String ' Return value
|
||||
Const cstThisSub = "TextStream.ReadAll"
|
||||
Const cstSubArgs = ""
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
sRead = ""
|
||||
|
||||
Check:
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not _IsFileOpen("READ") Then GoTo Finally
|
||||
If _InputStream.isEOF() Then GoTo CatchEOF
|
||||
End If
|
||||
|
||||
Try:
|
||||
sRead = _InputStream.readString(Array(), False)
|
||||
_LineNumber = _LineNumber + 1
|
||||
|
||||
Finally:
|
||||
ReadAll = sRead
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
CatchEOF:
|
||||
SF_Exception.RaiseFatal(ENDOFFILEERROR, FileName)
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_TextStream.ReadAll
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function ReadLine() As String
|
||||
''' Returns the next line in the text stream as a string. Line breaks are removed.
|
||||
''' Args:
|
||||
''' Returns:
|
||||
''' The read line. The string may be empty.
|
||||
''' Exceptions:
|
||||
''' FILENOTOPENERROR File not open or already closed
|
||||
''' FILEOPENMODEERROR File opened in write or append modes
|
||||
''' ENDOFFILEERROR Previous reads already reached the end of the file
|
||||
''' Examples:
|
||||
''' Dim a As String
|
||||
''' a = myFile.ReadLine()
|
||||
|
||||
Dim sRead As String ' Return value
|
||||
Dim iRead As Integer ' Length of line break
|
||||
Const cstThisSub = "TextStream.ReadLine"
|
||||
Const cstSubArgs = ""
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
sRead = ""
|
||||
|
||||
Check:
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not _IsFileOpen("READ") Then GoTo Finally
|
||||
If AtEndOfStream Then GoTo CatchEOF
|
||||
End If
|
||||
|
||||
Try:
|
||||
' When the text file ends with a line break,
|
||||
' XTextInputStream.readLine() returns the line break together with the last line
|
||||
' Hence the workaround to force a blank line at the end
|
||||
If _ForceBlankLine Then
|
||||
sRead = ""
|
||||
_ForceBlankLine = False
|
||||
Else
|
||||
sRead = _InputStream.readLine()
|
||||
' The isEOF() is set immediately after having read the last line
|
||||
If _InputStream.isEOF() And Len(sRead) > 0 Then
|
||||
iRead = 0
|
||||
If SF_String.EndsWith(sRead, SF_String.sfCRLF) Then
|
||||
iRead = 2
|
||||
ElseIf SF_String.EndsWith(sRead, SF_String.sfLF) Or SF_String.EndsWith(sRead, SF_String.sfCR) Then
|
||||
iRead = 1
|
||||
End If
|
||||
If iRead > 0 Then
|
||||
sRead = Left(sRead, Len(sRead) - iRead)
|
||||
_ForceBlankLine = True ' Provision for a last empty line at the next read loop
|
||||
End If
|
||||
End If
|
||||
End If
|
||||
_LineNumber = _LineNumber + 1
|
||||
|
||||
Finally:
|
||||
ReadLine = sRead
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
CatchEOF:
|
||||
SF_Exception.RaiseFatal(ENDOFFILEERROR, FileName)
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_TextStream.ReadLine
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function SetProperty(Optional ByVal PropertyName As Variant _
|
||||
, Optional ByRef Value As Variant _
|
||||
) As Boolean
|
||||
''' Set a new value to the given property
|
||||
''' Args:
|
||||
''' PropertyName: the name of the property as a string
|
||||
''' Value: its new value
|
||||
''' Exceptions
|
||||
''' ARGUMENTERROR The property does not exist
|
||||
|
||||
Dim bSet As Boolean ' Return value
|
||||
Const cstThisSub = "TextStream.SetProperty"
|
||||
Const cstSubArgs = "PropertyName, Value"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
bSet = False
|
||||
|
||||
Check:
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(PropertyName, "PropertyName", V_STRING, Properties()) Then GoTo Catch
|
||||
End If
|
||||
|
||||
Try:
|
||||
bSet = True
|
||||
Select Case UCase(PropertyName)
|
||||
Case "NEWLINE"
|
||||
If Not SF_Utils._Validate(Value, "Value", V_STRING) Then GoTo Catch
|
||||
NewLine = Value
|
||||
Case Else
|
||||
bSet = False
|
||||
End Select
|
||||
|
||||
Finally:
|
||||
SetProperty = bSet
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_TextStream.SetProperty
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Sub SkipLine()
|
||||
''' Skips the next line when reading a TextStream file.
|
||||
''' Args:
|
||||
''' Exceptions:
|
||||
''' FILENOTOPENERROR File not open or already closed
|
||||
''' FILEOPENMODEERROR File opened in write or append modes
|
||||
''' ENDOFFILEERROR Previous reads already reached the end of the file
|
||||
''' Examples:
|
||||
''' myFile.SkipLine()
|
||||
|
||||
Dim sRead As String ' Read buffer
|
||||
Const cstThisSub = "TextStream.SkipLine"
|
||||
Const cstSubArgs = ""
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
|
||||
Check:
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not _IsFileOpen("READ") Then GoTo Finally
|
||||
If Not _ForceBlankLine Then ' The file ends with a newline => return one empty line more
|
||||
If _InputStream.isEOF() Then GoTo CatchEOF
|
||||
End If
|
||||
End If
|
||||
|
||||
Try:
|
||||
sRead = ReadLine()
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Sub
|
||||
Catch:
|
||||
GoTo Finally
|
||||
CatchEOF:
|
||||
SF_Exception.RaiseFatal(ENDOFFILEERROR, FileName)
|
||||
GoTo Finally
|
||||
End Sub ' ScriptForge.SF_TextStream.SkipLine
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Sub WriteBlankLines(Optional ByVal Lines As Variant)
|
||||
''' Writes a number of empty lines in the output stream
|
||||
''' Args:
|
||||
''' Lines: the number of lines to write
|
||||
''' Returns:
|
||||
''' Exceptions:
|
||||
''' FILENOTOPENERROR File not open or already closed
|
||||
''' FILEOPENMODEERROR File opened in read mode
|
||||
''' Examples:
|
||||
''' myFile.WriteBlankLines(10)
|
||||
Dim i As Long
|
||||
Const cstThisSub = "TextStream.WriteBlankLines"
|
||||
Const cstSubArgs = "Lines"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
|
||||
Check:
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not _IsFileOpen("WRITE") Then GoTo Finally
|
||||
If Not SF_Utils._Validate(Lines, "Lines", V_NUMERIC) Then GoTo Finally
|
||||
End If
|
||||
|
||||
Try:
|
||||
For i = 1 To Lines
|
||||
_OutputStream.writeString(_NewLine)
|
||||
Next i
|
||||
_LineNumber = _LineNumber + Lines
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Sub
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Sub ' ScriptForge.SF_TextStream.WriteBlankLines
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Sub WriteLine(Optional ByVal Line As Variant)
|
||||
''' Writes the given line to the output stream. A newline is inserted if relevant
|
||||
''' Args:
|
||||
''' Line: the line to write, may be empty
|
||||
''' Returns:
|
||||
''' Exceptions:
|
||||
''' FILENOTOPENERROR File not open or already closed
|
||||
''' FILEOPENMODEERROR File opened in in read mode
|
||||
''' Examples:
|
||||
''' myFile.WriteLine("Next line")
|
||||
Dim i As Long
|
||||
Const cstThisSub = "TextStream.WriteLine"
|
||||
Const cstSubArgs = "Line"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
|
||||
Check:
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not _IsFileOpen("WRITE") Then GoTo Finally
|
||||
If Not SF_Utils._Validate(Line, "Line", V_STRING) Then GoTo Finally
|
||||
End If
|
||||
|
||||
Try:
|
||||
_OutputStream.writeString(Iif(_LineNumber > 0, _NewLine, "") & Line)
|
||||
_LineNumber = _LineNumber + 1
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Sub
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Sub ' ScriptForge.SF_TextStream.WriteLine
|
||||
|
||||
REM =========================================================== PRIVATE FUNCTIONS
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Sub _Initialize()
|
||||
''' Opens file and setup input and/or output streams (ForAppending requires both)
|
||||
|
||||
Dim oSfa As Object ' com.sun.star.ucb.SimpleFileAccess
|
||||
|
||||
' Default newline related to current operating system
|
||||
_NewLine = SF_String.sfNEWLINE
|
||||
|
||||
Set oSfa = SF_Utils._GetUNOService("FileAccess")
|
||||
|
||||
' Setup input and/or output streams based on READ/WRITE/APPEND IO modes
|
||||
Select Case _IOMode
|
||||
Case SF_FileSystem.ForReading
|
||||
Set _FileHandler = oSfa.openFileRead(_FileName)
|
||||
Set _InputStream = CreateUnoService("com.sun.star.io.TextInputStream")
|
||||
_InputStream.setInputStream(_FileHandler)
|
||||
Case SF_FileSystem.ForWriting
|
||||
' Output file is deleted beforehand
|
||||
If _FileExists Then oSfa.kill(_FileName)
|
||||
Set _FileHandler = oSfa.openFileWrite(_FileName)
|
||||
Set _OutputStream = CreateUnoService("com.sun.star.io.TextOutputStream")
|
||||
_OutputStream.setOutputStream(_FileHandler)
|
||||
Case SF_FileSystem.ForAppending
|
||||
Set _FileHandler = oSfa.openFileReadWrite(_FileName)
|
||||
Set _InputStream = CreateUnoService("com.sun.star.io.TextInputStream")
|
||||
Set _OutputStream = CreateUnoService("com.sun.star.io.TextOutputStream")
|
||||
_InputStream.setInputStream(_FileHandler)
|
||||
' Position at end of file: Skip and count existing lines
|
||||
_LineNumber = 0
|
||||
Do While Not _InputStream.isEOF()
|
||||
_InputStream.readLine()
|
||||
_LineNumber = _LineNumber + 1
|
||||
Loop
|
||||
_OutputStream.setOutputStream(_FileHandler)
|
||||
End Select
|
||||
|
||||
If _Encoding = "" Then _Encoding = "UTF-8"
|
||||
If Not IsNull(_InputStream) Then _InputStream.setEncoding(_Encoding)
|
||||
If Not IsNull(_OutputStream) Then _OutputStream.setEncoding(_Encoding)
|
||||
|
||||
End Sub ' ScriptForge.SF_TextStream._Initialize
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Function _IsFileOpen(Optional ByVal psMode As String) As Boolean
|
||||
''' Checks if file is open with the right mode (READ or WRITE)
|
||||
''' Raises an exception if the file is not open at all or not in the right mode
|
||||
''' Args:
|
||||
''' psMode: READ or WRITE or zero-length string
|
||||
''' Exceptions:
|
||||
''' FILENOTOPENERROR File not open or already closed
|
||||
''' FILEOPENMODEERROR File opened in incompatible mode
|
||||
|
||||
_IsFileOpen = False
|
||||
If IsMissing(psMode) Then psMode = ""
|
||||
If IsNull(_InputStream) And IsNull(_OutputStream) Then GoTo CatchNotOpen
|
||||
Select Case psMode
|
||||
Case "READ"
|
||||
If IsNull(_InputStream) Then GoTo CatchOpenMode
|
||||
If _IOMode <> SF_FileSystem.ForReading Then GoTo CatchOpenMode
|
||||
Case "WRITE"
|
||||
If IsNull(_OutputStream) Then GoTo CatchOpenMode
|
||||
If _IOMode = SF_FileSystem.ForReading Then GoTo CatchOpenMode
|
||||
Case Else
|
||||
End Select
|
||||
_IsFileOpen = True
|
||||
|
||||
Finally:
|
||||
Exit Function
|
||||
CatchNotOpen:
|
||||
SF_Exception.RaiseFatal(FILENOTOPENERROR, FileName)
|
||||
GoTo Finally
|
||||
CatchOpenMode:
|
||||
SF_Exception.RaiseFatal(FILEOPENMODEERROR, FileName, IOMode)
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_TextStream._IsFileOpen
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Function _PropertyGet(Optional ByVal psProperty As String)
|
||||
''' Return the value of the named property
|
||||
''' Args:
|
||||
''' psProperty: the name of the property
|
||||
|
||||
Dim cstThisSub As String
|
||||
Dim cstSubArgs As String
|
||||
|
||||
cstThisSub = "TextStream.get" & psProperty
|
||||
cstSubArgs = ""
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Select Case UCase(psProperty)
|
||||
Case UCase("AtEndOfStream")
|
||||
Select Case _IOMode
|
||||
Case SF_FileSystem.ForReading
|
||||
If IsNull(_InputStream) Then _PropertyGet = True Else _PropertyGet = CBool(_InputStream.isEOF() And Not _ForceBlankLine)
|
||||
Case Else : _PropertyGet = True
|
||||
End Select
|
||||
Case UCase("Encoding")
|
||||
_PropertyGet = _Encoding
|
||||
Case UCase("FileName")
|
||||
_PropertyGet = SF_FileSystem._ConvertFromUrl(_FileName) ' Depends on FileNaming
|
||||
Case UCase("IOMode")
|
||||
With SF_FileSystem
|
||||
Select Case _IOMode
|
||||
Case .ForReading : _PropertyGet = "READ"
|
||||
Case .ForWriting : _PropertyGet = "WRITE"
|
||||
Case .ForAppending : _PropertyGet = "APPEND"
|
||||
Case Else : _PropertyGet = ""
|
||||
End Select
|
||||
End With
|
||||
Case UCase("Line")
|
||||
_PropertyGet = _LineNumber
|
||||
Case UCase("NewLine")
|
||||
_PropertyGet = _NewLine
|
||||
Case Else
|
||||
_PropertyGet = Null
|
||||
End Select
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
End Function ' ScriptForge.SF_TextStream._PropertyGet
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Function _Repr() As String
|
||||
''' Convert the TextStream instance to a readable string, typically for debugging purposes (DebugPrint ...)
|
||||
''' Args:
|
||||
''' Return:
|
||||
''' "[TextStream]: File name, IOMode, LineNumber"
|
||||
|
||||
_Repr = "[TextStream]: " & FileName & "," & IOMode & "," & CStr(Line)
|
||||
|
||||
End Function ' ScriptForge.SF_TextStream._Repr
|
||||
|
||||
REM ============================================ END OF SCRIPTFORGE.SF_TextStream
|
||||
</script:module>
|
||||
@@ -0,0 +1,466 @@
|
||||
<?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_Timer" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
|
||||
REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
|
||||
REM === Full documentation is available on https://help.libreoffice.org/ ===
|
||||
REM =======================================================================================================================
|
||||
|
||||
Option Compatible
|
||||
Option ClassModule
|
||||
|
||||
Option Explicit
|
||||
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
''' SF_Timer
|
||||
''' ========
|
||||
''' Class for management of scripts execution performance
|
||||
''' A Timer measures durations. It can be suspended, resumed, restarted
|
||||
''' Duration properties are expressed in seconds with a precision of 3 decimal digits
|
||||
'''
|
||||
''' Service invocation example:
|
||||
''' Dim myTimer As Variant
|
||||
''' myTimer = CreateScriptService("Timer")
|
||||
''' myTimer = CreateScriptService("Timer", True) ' => To start timer immediately
|
||||
'''
|
||||
''' Detailed user documentation:
|
||||
''' https://help.libreoffice.org/latest/en-US/text/sbasic/shared/03/sf_timer.html?DbPAR=BASIC
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
REM ================================================================== EXCEPTIONS
|
||||
|
||||
REM ============================================================= PRIVATE MEMBERS
|
||||
|
||||
Private [Me] As Object
|
||||
Private [_Parent] As Object
|
||||
Private ObjectType As String ' Must be "TIMER"
|
||||
Private ServiceName As String
|
||||
Private _TimerStatus As Integer ' inactive, started, suspended or stopped
|
||||
Private _StartTime As Double ' Moment when timer started, restarted
|
||||
Private _EndTime As Double ' Moment when timer stopped
|
||||
Private _SuspendTime As Double ' Moment when timer suspended
|
||||
Private _SuspendDuration As Double ' Duration of suspended status as a difference of times
|
||||
|
||||
REM ============================================================ MODULE CONSTANTS
|
||||
|
||||
Private Const STATUSINACTIVE = 0
|
||||
Private Const STATUSSTARTED = 1
|
||||
Private Const STATUSSUSPENDED = 2
|
||||
Private Const STATUSSTOPPED = 3
|
||||
|
||||
Private Const DSECOND As Double = 1 / (24 * 60 * 60) ' Duration of 1 second as compared to 1.0 = 1 day
|
||||
|
||||
REM ===================================================== CONSTRUCTOR/DESTRUCTOR
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Sub Class_Initialize()
|
||||
Set [Me] = Nothing
|
||||
Set [_Parent] = Nothing
|
||||
ObjectType = "TIMER"
|
||||
ServiceName = "ScriptForge.Timer"
|
||||
_TimerStatus = STATUSINACTIVE
|
||||
_StartTime = 0
|
||||
_EndTime = 0
|
||||
_SuspendTime = 0
|
||||
_SuspendDuration = 0
|
||||
End Sub ' ScriptForge.SF_Timer Constructor
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Sub Class_Terminate()
|
||||
Call Class_Initialize()
|
||||
End Sub ' ScriptForge.SF_Timer Destructor
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Dispose() As Variant
|
||||
Call Class_Terminate()
|
||||
Set Dispose = Nothing
|
||||
End Function ' ScriptForge.SF_Timer Explicit destructor
|
||||
|
||||
REM ================================================================== PROPERTIES
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Duration() As Double
|
||||
''' Returns the actual (out of suspensions) time elapsed since start or between start and stop
|
||||
''' Args:
|
||||
''' Returns:
|
||||
''' A Double expressing the duration in seconds
|
||||
''' Example:
|
||||
''' myTimer.Duration returns 1.234 (1 sec, 234 ms)
|
||||
|
||||
Duration = _PropertyGet("Duration")
|
||||
|
||||
End Function ' ScriptForge.SF_Timer.Duration
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get IsStarted() As Boolean
|
||||
''' Returns True if timer is started or suspended
|
||||
''' Example:
|
||||
''' myTimer.IsStarted
|
||||
|
||||
IsStarted = _PropertyGet("IsStarted")
|
||||
|
||||
End Property ' ScriptForge.SF_Timer.IsStarted
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get IsSuspended() As Boolean
|
||||
''' Returns True if timer is started and suspended
|
||||
''' Example:
|
||||
''' myTimer.IsSuspended
|
||||
|
||||
IsSuspended = _PropertyGet("IsSuspended")
|
||||
|
||||
End Property ' ScriptForge.SF_Timer.IsSuspended
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function SuspendDuration() As Double
|
||||
''' Returns the actual time elapsed while suspended since start or between start and stop
|
||||
''' Args:
|
||||
''' Returns:
|
||||
''' A Double expressing the duration in seconds
|
||||
''' Example:
|
||||
''' myTimer.SuspendDuration returns 1.234 (1 sec, 234 ms)
|
||||
|
||||
SuspendDuration = _PropertyGet("SuspendDuration")
|
||||
|
||||
End Function ' ScriptForge.SF_Timer.SuspendDuration
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function TotalDuration() As Double
|
||||
''' Returns the actual time elapsed (including suspensions) since start or between start and stop
|
||||
''' Args:
|
||||
''' Returns:
|
||||
''' A Double expressing the duration in seconds
|
||||
''' Example:
|
||||
''' myTimer.TotalDuration returns 1.234 (1 sec, 234 ms)
|
||||
|
||||
TotalDuration = _PropertyGet("TotalDuration")
|
||||
|
||||
End Function ' ScriptForge.SF_Timer.TotalDuration
|
||||
|
||||
REM ===================================================================== METHODS
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Continue() As Boolean
|
||||
''' Halt suspension of a running timer
|
||||
''' Args:
|
||||
''' Returns:
|
||||
''' True if successful, False if the timer is not suspended
|
||||
''' Examples:
|
||||
''' myTimer.Continue()
|
||||
|
||||
Const cstThisSub = "Timer.Continue"
|
||||
Const cstSubArgs = ""
|
||||
|
||||
Check:
|
||||
Continue = False
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Try:
|
||||
If _TimerStatus = STATUSSUSPENDED Then
|
||||
_TimerStatus = STATUSSTARTED
|
||||
_SuspendDuration = _SuspendDuration + _Now() - _SuspendTime
|
||||
_SuspendTime = 0
|
||||
Continue = True
|
||||
End If
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
End Function ' ScriptForge.SF_Timer.Continue
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function GetProperty(Optional ByVal PropertyName As Variant) As Variant
|
||||
''' Return the actual value of the given property
|
||||
''' Args:
|
||||
''' PropertyName: the name of the property as a string
|
||||
''' Returns:
|
||||
''' The actual value of the property
|
||||
''' Exceptions
|
||||
''' ARGUMENTERROR The property does not exist
|
||||
''' Examples:
|
||||
''' myTimer.GetProperty("Duration")
|
||||
|
||||
Const cstThisSub = "Timer.GetProperty"
|
||||
Const cstSubArgs = "PropertyName"
|
||||
|
||||
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, "PropertyName", V_STRING, Properties()) Then GoTo Catch
|
||||
End If
|
||||
|
||||
Try:
|
||||
GetProperty = _PropertyGet(PropertyName)
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Timer.Properties
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Methods() As Variant
|
||||
''' Return the list or methods of the Timer class as an array
|
||||
|
||||
Methods = Array( _
|
||||
"Continue" _
|
||||
, "Restart" _
|
||||
, "Start" _
|
||||
, "Suspend" _
|
||||
, "Terminate" _
|
||||
)
|
||||
|
||||
End Function ' ScriptForge.SF_Timer.Methods
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Properties() As Variant
|
||||
''' Return the list or properties of the Timer class as an array
|
||||
|
||||
Properties = Array( _
|
||||
"Duration" _
|
||||
, "IsStarted" _
|
||||
, "IsSuspended" _
|
||||
, "SuspendDuration" _
|
||||
, "TotalDuration" _
|
||||
)
|
||||
|
||||
End Function ' ScriptForge.SF_Timer.Properties
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Restart() As Boolean
|
||||
''' Terminate the timer and restart a new clean timer
|
||||
''' Args:
|
||||
''' Returns:
|
||||
''' True if successful, False if the timer is inactive
|
||||
''' Examples:
|
||||
''' myTimer.Restart()
|
||||
|
||||
Const cstThisSub = "Timer.Restart"
|
||||
Const cstSubArgs = ""
|
||||
|
||||
Check:
|
||||
Restart = False
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Try:
|
||||
If _TimerStatus <> STATUSINACTIVE Then
|
||||
If _TimerStatus <> STATUSSTOPPED Then Terminate()
|
||||
Start()
|
||||
Restart = True
|
||||
End If
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
End Function ' ScriptForge.SF_Timer.Restart
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function SetProperty(Optional ByVal PropertyName As Variant _
|
||||
, Optional ByRef Value As Variant _
|
||||
) As Boolean
|
||||
''' Set a new value to the given property
|
||||
''' Args:
|
||||
''' PropertyName: the name of the property as a string
|
||||
''' Value: its new value
|
||||
''' Exceptions
|
||||
''' ARGUMENTERROR The property does not exist
|
||||
|
||||
Const cstThisSub = "Timer.SetProperty"
|
||||
Const cstSubArgs = "PropertyName, Value"
|
||||
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
SetProperty = False
|
||||
|
||||
Check:
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
If Not SF_Utils._Validate(PropertyName, "PropertyName", V_STRING, Properties()) Then GoTo Catch
|
||||
End If
|
||||
|
||||
Try:
|
||||
Select Case UCase(PropertyName)
|
||||
Case Else
|
||||
End Select
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Timer.SetProperty
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Start() As Boolean
|
||||
''' Start a new clean timer
|
||||
''' Args:
|
||||
''' Returns:
|
||||
''' True if successful, False if the timer is already started
|
||||
''' Examples:
|
||||
''' myTimer.Start()
|
||||
|
||||
Const cstThisSub = "Timer.Start"
|
||||
Const cstSubArgs = ""
|
||||
|
||||
Check:
|
||||
Start = False
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Try:
|
||||
If _TimerStatus = STATUSINACTIVE Or _TimerStatus = STATUSSTOPPED Then
|
||||
_TimerStatus = STATUSSTARTED
|
||||
_StartTime = _Now()
|
||||
_EndTime = 0
|
||||
_SuspendTime = 0
|
||||
_SuspendDuration = 0
|
||||
Start = True
|
||||
End If
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
End Function ' ScriptForge.SF_Timer.Start
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Suspend() As Boolean
|
||||
''' Suspend a running timer
|
||||
''' Args:
|
||||
''' Returns:
|
||||
''' True if successful, False if the timer is not started or already suspended
|
||||
''' Examples:
|
||||
''' myTimer.Suspend()
|
||||
|
||||
Const cstThisSub = "Timer.Suspend"
|
||||
Const cstSubArgs = ""
|
||||
|
||||
Check:
|
||||
Suspend = False
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Try:
|
||||
If _TimerStatus = STATUSSTARTED Then
|
||||
_TimerStatus = STATUSSUSPENDED
|
||||
_SuspendTime = _Now()
|
||||
Suspend = True
|
||||
End If
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
End Function ' ScriptForge.SF_Timer.Suspend
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Terminate() As Boolean
|
||||
''' Terminate a running timer
|
||||
''' Args:
|
||||
''' Returns:
|
||||
''' True if successful, False if the timer is neither started nor suspended
|
||||
''' Examples:
|
||||
''' myTimer.Terminate()
|
||||
|
||||
Const cstThisSub = "Timer.Terminate"
|
||||
Const cstSubArgs = ""
|
||||
|
||||
Check:
|
||||
Terminate = False
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Try:
|
||||
If _TimerStatus = STATUSSTARTED Or _TimerStatus = STATUSSUSPENDED Then
|
||||
If _TimerSTatus = STATUSSUSPENDED Then Continue()
|
||||
_TimerStatus = STATUSSTOPPED
|
||||
_EndTime = _Now()
|
||||
Terminate = True
|
||||
End If
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
End Function ' ScriptForge.SF_Timer.Terminate
|
||||
|
||||
REM =========================================================== PRIVATE FUNCTIONS
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Function _Now() As Double
|
||||
''' Returns the current date and time
|
||||
''' Uses the Calc NOW() function to get a higher precision than the usual Basic Now() function
|
||||
''' Args:
|
||||
''' Returns:
|
||||
''' The actual time as a number
|
||||
''' The integer part represents the date, the decimal part represents the time
|
||||
|
||||
_Now = SF_Session.ExecuteCalcFunction("NOW")
|
||||
|
||||
End Function ' ScriptForge.SF_Timer._Now
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Function _PropertyGet(Optional ByVal psProperty As String)
|
||||
''' Return the named property
|
||||
''' Args:
|
||||
''' psProperty: the name of the property
|
||||
|
||||
Dim dDuration As Double ' Computed duration
|
||||
Dim cstThisSub As String
|
||||
Dim cstSubArgs As String
|
||||
|
||||
cstThisSub = "Timer.get" & psProperty
|
||||
cstSubArgs = ""
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Select Case UCase(psProperty)
|
||||
Case UCase("Duration")
|
||||
Select Case _TimerStatus
|
||||
Case STATUSINACTIVE : dDuration = 0.0
|
||||
Case STATUSSTARTED
|
||||
dDuration = _Now() - _StartTime - _SuspendDuration
|
||||
Case STATUSSUSPENDED
|
||||
dDuration = _SuspendTime - _StartTime - _SuspendDuration
|
||||
Case STATUSSTOPPED
|
||||
dDuration = _EndTime - _StartTime - _SuspendDuration
|
||||
End Select
|
||||
_PropertyGet = Fix(dDuration * 1000 / DSECOND) / 1000
|
||||
Case UCase("IsStarted")
|
||||
_PropertyGet = CBool( _TimerStatus = STATUSSTARTED Or _TimerStatus = STATUSSUSPENDED )
|
||||
Case UCase("IsSuspended")
|
||||
_PropertyGet = CBool( _TimerStatus = STATUSSUSPENDED )
|
||||
Case UCase("SuspendDuration")
|
||||
Select Case _TimerStatus
|
||||
Case STATUSINACTIVE : dDuration = 0.0
|
||||
Case STATUSSTARTED, STATUSSTOPPED
|
||||
dDuration = _SuspendDuration
|
||||
Case STATUSSUSPENDED
|
||||
dDuration = _Now() - _SuspendTime + _SuspendDuration
|
||||
End Select
|
||||
_PropertyGet = Fix(dDuration * 1000 / DSECOND) / 1000
|
||||
Case UCase("TotalDuration")
|
||||
Select Case _TimerStatus
|
||||
Case STATUSINACTIVE : dDuration = 0.0
|
||||
Case STATUSSTARTED, STATUSSUSPENDED
|
||||
dDuration = _Now() - _StartTime
|
||||
Case STATUSSTOPPED
|
||||
dDuration = _EndTime - _StartTime
|
||||
End Select
|
||||
_PropertyGet = Fix(dDuration * 1000 / DSECOND) / 1000
|
||||
End Select
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
End Function ' ScriptForge.SF_Timer._PropertyGet
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Function _Repr() As String
|
||||
''' Convert the Timer instance to a readable string, typically for debugging purposes (DebugPrint ...)
|
||||
''' Args:
|
||||
''' Return:
|
||||
''' "[Timer] Duration:xxx.yyy
|
||||
|
||||
Const cstTimer = "[Timer] Duration: "
|
||||
Const cstMaxLength = 50 ' Maximum length for items
|
||||
|
||||
_Repr = cstTimer & Replace(SF_Utils._Repr(Duration), ".", """")
|
||||
|
||||
End Function ' ScriptForge.SF_Timer._Repr
|
||||
|
||||
REM ============================================ END OF SCRIPTFORGE.SF_TIMER
|
||||
</script:module>
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,100 @@
|
||||
<?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="_CodingConventions" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
|
||||
REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
|
||||
REM === Full documentation is available on https://help.libreoffice.org/ ===
|
||||
REM =======================================================================================================================
|
||||
|
||||
'''
|
||||
' Conventions used in the coding of the *ScriptForge* library
|
||||
' -----------------------------------------------------------
|
||||
'''
|
||||
' Library and Modules
|
||||
' ===================
|
||||
' * Module names are all prefixed with "SF_".
|
||||
' * The *Option Explicit* statement is mandatory in every module.
|
||||
' * The *Option Private Module* statement is recommended in internal modules.
|
||||
' * A standard header presenting the module/class is mandatory
|
||||
' * An end of file (eof) comment line is mandatory
|
||||
' * Every module lists the constants that are related to it and documented as return values, arguments, etc.
|
||||
' They are defined as *Global Const*.
|
||||
' The scope of global constants being limited to one single library, their invocation from user scripts shall be qualified.
|
||||
' * The Basic reserved words are *Proper-Cased*.
|
||||
'''
|
||||
' Functions and Subroutines
|
||||
' =========================
|
||||
' * LibreOffice ignores the Private/Public attribute in Functions or Subs declarations.
|
||||
' Nevertheless the attribute must be present.
|
||||
' Rules to recognize their scope are:
|
||||
' * Public + name starts with a letter
|
||||
' The Sub/Function belongs to the official ScriptForge API.
|
||||
' As such it may be called from any user script.
|
||||
' * Public + name starts with an underscore "_"
|
||||
' The Sub/Function may be called only from within the ScriptForge library.
|
||||
' As such it MUST NOT be called from another library or from a user script,
|
||||
' as there is no guarantee about the arguments, the semantic or even the existence of that piece of code in a later release.
|
||||
' * Private - The Sub/Function name must start with an underscore "_".
|
||||
' The Sub/Function may be called only from the module in which it is located.
|
||||
' * Functions and Subroutines belonging to the API (= "standard" functions/Subs) are defined in their module in alphabetical order.
|
||||
' For class modules, all the properties precede the methods which precede the events.
|
||||
' * Functions and Subroutines not belonging to the API are defined in their module in alphabetical order below the standard ones.
|
||||
' * The return value of a function is always declared explicitly.
|
||||
' * The parameters are always declared explicitly even if they're variants.
|
||||
' * The Function and Sub declarations start at the 1st column of the line.
|
||||
' * The End Function/Sub statement is followed by a comment reminding the name of the containing library.module and of the function or sub.
|
||||
' If the Function/Sub is declared for the first time or modified in a release > initial public release, the actual release number is mentioned as well.
|
||||
'''
|
||||
' Variable declarations
|
||||
' =====================
|
||||
' * Variable names use only alpha characters, the underscore and digits (no accented characters).
|
||||
' Exceptionally, names of private variables may be embraced with `[` and `]` if `Option Compatible` is present.
|
||||
' * The Global, Dim and Const statements always start in the first column of the line.
|
||||
' * The type (*Dim ... As ...*, *Function ... As ...*) is always declared explicitly, even if the type is Variant.
|
||||
' * Variables are *Proper-Cased*. They are always preceded by a lower-case letter indicating their type.
|
||||
' With next exception: variables i, j, k, l, m and n must be declared as integers or longs.
|
||||
' > b Boolean
|
||||
' > d Date
|
||||
' > v Variant
|
||||
' > o Object
|
||||
' > i Integer
|
||||
' > l Long
|
||||
' > s String
|
||||
' Example:
|
||||
' Dim sValue As String
|
||||
' * Parameters are preceded by the letter *p* which itself precedes the single *typing letter*.
|
||||
' In official methods, to match their published documentation, the *p* and the *typing letter* may be omitted. Like in:
|
||||
' Private Function MyFunction(psValue As String) As Variant
|
||||
' Public Function MyOfficialFunction(Value As String) As Variant
|
||||
' * Global variables in the ScriptForge library are ALL preceded by an underscore "_" as NONE of them should be invoked from outside the library.
|
||||
' * Constant values with a local scope are *Proper-Cased* and preceded by the letters *cst*.
|
||||
' * Constants with a global scope are *UPPER-CASED*.
|
||||
' Example:
|
||||
' Global Const ACONSTANT = "This is a global constant"
|
||||
' Function MyFunction(pocControl As Object, piValue) As Variant
|
||||
' Dim iValue As Integer
|
||||
' Const cstMyConstant = 3
|
||||
'''
|
||||
' Indentation
|
||||
' ===========
|
||||
' Code shall be indented with TAB characters.
|
||||
'''
|
||||
' Goto/Gosub
|
||||
' ==========
|
||||
' The *GoSub* … *Return* statement is forbidden.
|
||||
' The *GoTo* statement is forbidden.
|
||||
' However *GoTo* is highly recommended for *error* and *exception* handling.
|
||||
'''
|
||||
' Comments (english only)
|
||||
' ========
|
||||
' * Every public routine should be documented with a python-like "docstring":
|
||||
' 1. Role of Sub/Function
|
||||
' 2. List of arguments, mandatory/optional, role
|
||||
' 3. Returned value(s) type and meaning
|
||||
' 4. Examples when useful
|
||||
' 5. Eventual specific exception codes
|
||||
' * The "docstring" comments shall be marked by a triple (single) quote character at the beginning of the line
|
||||
' * Meaningful variables shall be declared one per line. Comment on same line.
|
||||
' * Comments about a code block should be left indented.
|
||||
' If it concerns only the next line, no indent required (may also be put at the end of the line).
|
||||
'''
|
||||
</script:module>
|
||||
@@ -0,0 +1,221 @@
|
||||
<?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="_ModuleModel" script:language="StarBasic" script:moduleType="normal">REM =======================================================================================================================
|
||||
REM === The ScriptForge library and its associated libraries are part of the LibreOffice project. ===
|
||||
REM === Full documentation is available on https://help.libreoffice.org/ ===
|
||||
REM =======================================================================================================================
|
||||
|
||||
Option Compatible
|
||||
Option ClassModule
|
||||
'Option Private Module
|
||||
|
||||
Option Explicit
|
||||
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
''' ModuleModel (aka SF_Model)
|
||||
''' ===========
|
||||
''' Illustration of how the ScriptForge modules are structured
|
||||
''' Copy and paste this code in an empty Basic module to start a new service
|
||||
''' Comment in, comment out, erase what you want, but at the end respect the overall structure
|
||||
'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
||||
|
||||
REM ================================================================== EXCEPTIONS
|
||||
|
||||
''' FAKENEWSERROR
|
||||
|
||||
REM ============================================================= PRIVATE MEMBERS
|
||||
|
||||
Private [Me] As Object ' Should be initialized immediately after the New statement
|
||||
' Dim obj As Object : Set obj = New SF_Model
|
||||
' Set obj.[Me] = obj
|
||||
Private [_Parent] As Object ' To keep trace of the instance having created a sub-instance
|
||||
' Set obj._Parent = [Me]
|
||||
Private ObjectType As String ' Must be UNIQUE
|
||||
|
||||
REM ============================================================ MODULE CONSTANTS
|
||||
|
||||
Private Const SOMECONSTANT = 1
|
||||
|
||||
REM ====================================================== CONSTRUCTOR/DESTRUCTOR
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Sub Class_Initialize()
|
||||
Set [Me] = Nothing
|
||||
Set [_Parent] = Nothing
|
||||
ObjectType = "MODEL"
|
||||
End Sub ' ScriptForge.SF_Model Constructor
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Sub Class_Terminate()
|
||||
Call Class_Initialize()
|
||||
End Sub ' ScriptForge.SF_Model Destructor
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Dispose() As Variant
|
||||
Call Class_Terminate()
|
||||
Set Dispose = Nothing
|
||||
End Function ' ScriptForge.SF_Model Explicit Destructor
|
||||
|
||||
REM ================================================================== PROPERTIES
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Property Get MyProperty() As Boolean
|
||||
''' Returns True or False
|
||||
''' Example:
|
||||
''' myModel.MyProperty
|
||||
|
||||
MyProperty = _PropertyGet("MyProperty")
|
||||
|
||||
End Property ' ScriptForge.SF_Model.MyProperty
|
||||
|
||||
REM ===================================================================== METHODS
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function GetProperty(Optional ByVal PropertyName As Variant) As Variant
|
||||
''' Return the actual value of the given property
|
||||
''' Args:
|
||||
''' PropertyName: the name of the property as a string
|
||||
''' Returns:
|
||||
''' The actual value of the property
|
||||
''' If the property does not exist, returns Null
|
||||
''' Exceptions:
|
||||
''' see the exceptions of the individual properties
|
||||
''' Examples:
|
||||
''' myModel.GetProperty("MyProperty")
|
||||
|
||||
Const cstThisSub = "Model.GetProperty"
|
||||
Const cstSubArgs = ""
|
||||
|
||||
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, "PropertyName", V_STRING, Properties()) Then GoTo Catch
|
||||
End If
|
||||
|
||||
Try:
|
||||
GetProperty = _PropertyGet(PropertyName)
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Model.GetProperty
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Methods() As Variant
|
||||
''' Return the list of public methods of the Model service as an array
|
||||
|
||||
Methods = Array( _
|
||||
"MyFunction" _
|
||||
, "etc" _
|
||||
)
|
||||
|
||||
End Function ' ScriptForge.SF_Model.Methods
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function MyFunction(Optional ByVal Arg1 As Variant _
|
||||
, Optional ByVal Arg2 As Variant _
|
||||
) As Variant
|
||||
''' Fictive function that concatenates Arg1 Arg2 times
|
||||
''' Args:
|
||||
''' Arg1 String Text
|
||||
''' Arg2 Numeric Number of times (default = 2)
|
||||
''' Returns:
|
||||
''' The new string
|
||||
''' Exceptions:
|
||||
''' FAKENEWSERROR
|
||||
''' Examples:
|
||||
''' MyFunction("value1") returns "value1value1"
|
||||
|
||||
Dim sOutput As String ' Output buffer
|
||||
Dim i As Integer
|
||||
Const cstThisSub = "Model.myFunction"
|
||||
Const cstSubArgs = "Arg1, [Arg2=2]"
|
||||
|
||||
' _ErrorHandling returns False when, for debugging, the standard error handling is preferred
|
||||
If SF_Utils._ErrorHandling() Then On Local Error GoTo Catch
|
||||
myFunction = ""
|
||||
|
||||
Check:
|
||||
If IsMissing(Arg2) Then Arg2 = 2
|
||||
' _EnterFunction returns True when current method is invoked from a user script
|
||||
If SF_Utils._EnterFunction(cstThisSub, cstSubArgs) Then
|
||||
' Check Arg1 is a string and Arg2 is a number.
|
||||
' Validation rules for scalars and arrays are described in SF_Utils
|
||||
If Not SF_Utils._Validate(Arg1, "Arg1", V_STRING) Then GoTo Finally
|
||||
If Not SF_Utils._Validate(Arg2, "Arg2", V_NUMERIC) Then GoTo Finally
|
||||
' Fatal error ?
|
||||
If Arg2 < 0 Then GoTo CatchFake
|
||||
End If
|
||||
|
||||
Try:
|
||||
sOutput = ""
|
||||
For i = 0 To Arg2
|
||||
sOutput = sOutput & Arg1
|
||||
Next i
|
||||
myFunction = sOutput
|
||||
|
||||
Finally:
|
||||
' _ExitFunction manages internal (On Local) errors
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
Catch:
|
||||
GoTo Finally
|
||||
CatchFake:
|
||||
SF_Exception.RaiseFatal("FAKENEWSERROR", cstThisSub)
|
||||
GoTo Finally
|
||||
End Function ' ScriptForge.SF_Model.myFunction
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Public Function Properties() As Variant
|
||||
''' Return the list or properties of the Model class as an array
|
||||
|
||||
Properties = Array( _
|
||||
"MyProperty" _
|
||||
, "etc" _
|
||||
)
|
||||
|
||||
End Function ' ScriptForge.SF_Model.Properties
|
||||
|
||||
REM =========================================================== PRIVATE FUNCTIONS
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Function _PropertyGet(Optional ByVal psProperty As String) As Variant
|
||||
''' Return the value of the named property
|
||||
''' Args:
|
||||
''' psProperty: the name of the property
|
||||
|
||||
Dim cstThisSub As String
|
||||
Const cstSubArgs = ""
|
||||
|
||||
cstThisSub = "SF_Model.get" & psProperty
|
||||
SF_Utils._EnterFunction(cstThisSub, cstSubArgs)
|
||||
|
||||
Select Case psProperty
|
||||
Case "MyProperty"
|
||||
_PropertyGet = TBD
|
||||
Case Else
|
||||
_PropertyGet = Null
|
||||
End Select
|
||||
|
||||
Finally:
|
||||
SF_Utils._ExitFunction(cstThisSub)
|
||||
Exit Function
|
||||
End Function ' ScriptForge.SF_Model._PropertyGet
|
||||
|
||||
REM -----------------------------------------------------------------------------
|
||||
Private Function _Repr() As String
|
||||
''' Convert the Model instance to a readable string, typically for debugging purposes (DebugPrint ...)
|
||||
''' Args:
|
||||
''' Return:
|
||||
''' "[MODEL]: A readable string"
|
||||
|
||||
_Repr = "[MODEL]: A readable string"
|
||||
|
||||
End Function ' ScriptForge.SF_Model._Repr
|
||||
|
||||
REM ============================================ END OF SCRIPTFORGE.SF_MODEL
|
||||
</script:module>
|
||||
@@ -0,0 +1,25 @@
|
||||
<?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">
|
||||
''' 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 === Full documentation is available on https://help.libreoffice.org/ ===
|
||||
REM =======================================================================================================================
|
||||
|
||||
''' ScriptForge is distributed in the hope that it will be useful,
|
||||
''' but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
''' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
|
||||
''' ScriptForge is free software; you can redistribute it and/or modify it under the terms of either (at your option):
|
||||
|
||||
''' 1) The Mozilla Public License, v. 2.0. If a copy of the MPL was not
|
||||
''' distributed with this file, you can obtain one at http://mozilla.org/MPL/2.0/ .
|
||||
|
||||
''' 2) The GNU Lesser General Public License as published by
|
||||
''' the Free Software Foundation, either version 3 of the License, or
|
||||
''' (at your option) any later version. If a copy of the LGPL was not
|
||||
''' distributed with this file, see http://www.gnu.org/licenses/ .
|
||||
|
||||
</script:module>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?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="ScriptForge" library:readonly="false" library:passwordprotected="false">
|
||||
<library:element library:name="dlgConsole"/>
|
||||
<library:element library:name="dlgProgress"/>
|
||||
</library:library>
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE dlg:window PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "dialog.dtd">
|
||||
<dlg:window xmlns:dlg="http://openoffice.org/2000/dialog" xmlns:script="http://openoffice.org/2000/script" dlg:id="dlgConsole" dlg:left="114" dlg:top="32" dlg:width="321" dlg:height="239" dlg:closeable="true" dlg:moveable="true" dlg:title="ScriptForge">
|
||||
<dlg:styles>
|
||||
<dlg:style dlg:style-id="0" dlg:font-name="Courier New" dlg:font-stylename="Regular" dlg:font-family="modern"/>
|
||||
</dlg:styles>
|
||||
<dlg:bulletinboard>
|
||||
<dlg:textfield dlg:style-id="0" dlg:id="ConsoleLines" dlg:tab-index="0" dlg:left="4" dlg:top="2" dlg:width="312" dlg:height="225" dlg:hscroll="true" dlg:vscroll="true" dlg:multiline="true" dlg:readonly="true"/>
|
||||
<dlg:button dlg:id="CloseNonModalButton" dlg:tab-index="2" dlg:left="265" dlg:top="228" dlg:width="50" dlg:height="10" dlg:default="true" dlg:image-src="private:graphicrepository/cmd/sc_cancel.png">
|
||||
<script:event script:event-name="on-performaction" script:macro-name="vnd.sun.star.script:ScriptForge.SF_Exception._CloseConsole?language=Basic&location=application" script:language="Script"/>
|
||||
</dlg:button>
|
||||
<dlg:button dlg:id="CloseModalButton" dlg:tab-index="1" dlg:left="265" dlg:top="228" dlg:width="50" dlg:height="10" dlg:default="true" dlg:button-type="ok" dlg:image-src="private:graphicrepository/cmd/sc_cancel.png"/>
|
||||
</dlg:bulletinboard>
|
||||
</dlg:window>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE dlg:window PUBLIC "-//OpenOffice.org//DTD OfficeDocument 1.0//EN" "dialog.dtd">
|
||||
<dlg:window xmlns:dlg="http://openoffice.org/2000/dialog" xmlns:script="http://openoffice.org/2000/script" dlg:id="dlgProgress" dlg:left="180" dlg:top="90" dlg:width="275" dlg:height="37" dlg:closeable="true" dlg:moveable="true">
|
||||
<dlg:bulletinboard>
|
||||
<dlg:text dlg:id="ProgressText" dlg:tab-index="1" dlg:left="16" dlg:top="7" dlg:width="245" dlg:height="8" dlg:value="ProgressText" dlg:tabstop="true"/>
|
||||
<dlg:progressmeter dlg:id="ProgressBar" dlg:tab-index="0" dlg:left="16" dlg:top="18" dlg:width="190" dlg:height="10" dlg:value="50"/>
|
||||
<dlg:button dlg:id="CloseButton" dlg:tab-index="2" dlg:left="210" dlg:top="18" dlg:width="50" dlg:height="10" dlg:image-src="private:graphicrepository/cmd/sc_cancel.png">
|
||||
<script:event script:event-name="on-performaction" script:macro-name="vnd.sun.star.script:ScriptForge.SF_UI._CloseProgressBar?language=Basic&location=application" script:language="Script"/>
|
||||
</dlg:button>
|
||||
</dlg:bulletinboard>
|
||||
</dlg:window>
|
||||
@@ -0,0 +1,992 @@
|
||||
#
|
||||
# This pristine POT file has been generated by LibreOffice/ScriptForge
|
||||
# Full documentation is available on https://help.libreoffice.org/
|
||||
#
|
||||
# *********************************************************************
|
||||
# *** The ScriptForge library and its associated libraries ***
|
||||
# *** are part of the LibreOffice project. ***
|
||||
# *********************************************************************
|
||||
#
|
||||
# ScriptForge Release 7.4
|
||||
# -----------------------
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.libreoffice.org/enter_bug.cgi?product=LibreOffice&bug_status=UNCONFIRMED&component=UI\n"
|
||||
"POT-Creation-Date: 2022-10-12 15:07:35\n"
|
||||
"PO-Revision-Date: YYYY-MM-DD HH:MM:SS\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n"
|
||||
"Language: en_US\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||
"X-Generator: LibreOffice - ScriptForge\n"
|
||||
"X-Accelerator-Marker: ~\n"
|
||||
|
||||
#. Title in error message box
|
||||
#. %1: an error number
|
||||
#, kde-format
|
||||
msgctxt "ERRORNUMBER"
|
||||
msgid "Error %1"
|
||||
msgstr ""
|
||||
|
||||
#. Error message box
|
||||
#. %1: a line number
|
||||
#, kde-format
|
||||
msgctxt "ERRORLOCATION"
|
||||
msgid "Location : %1"
|
||||
msgstr ""
|
||||
|
||||
#. Logfile record
|
||||
#, kde-format
|
||||
msgctxt "LONGERRORDESC"
|
||||
msgid "Error %1 - Location = %2 - Description = %3"
|
||||
msgstr ""
|
||||
|
||||
#. Any blocking error message
|
||||
msgctxt "STOPEXECUTION"
|
||||
msgid "THE EXECUTION IS CANCELLED."
|
||||
msgstr ""
|
||||
|
||||
#. Any blocking error message
|
||||
#. %1: a method name
|
||||
#, kde-format
|
||||
msgctxt "NEEDMOREHELP"
|
||||
msgid "Do you want to receive more information about the '%1' method ?"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Exception.RaiseAbort error message
|
||||
msgctxt "INTERNALERROR"
|
||||
msgid ""
|
||||
"The ScriptForge library has crashed. The reason is unknown.\n"
|
||||
"Maybe a bug that could be reported on\n"
|
||||
" https://bugs.documentfoundation.org/\n"
|
||||
"\n"
|
||||
"More details : \n"
|
||||
"\n"
|
||||
""
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._Validate error message
|
||||
#. %1: probably ScriptForge
|
||||
#. %2: service or module name
|
||||
#. %3: property or method name where the error occurred
|
||||
#, kde-format
|
||||
msgctxt "VALIDATESOURCE"
|
||||
msgid ""
|
||||
"Library : %1\n"
|
||||
"Service : %2\n"
|
||||
"Method : %3"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._Validate error message
|
||||
#. %1: list of arguments of the method
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEARGS"
|
||||
msgid "Arguments: %1"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._Validate error message
|
||||
#. %1: Wrong argument name
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEERROR"
|
||||
msgid "A serious error has been detected in your code on argument : « %1 »."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils.Validate error message
|
||||
msgctxt "VALIDATIONRULES"
|
||||
msgid " Validation rules :"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._Validate error message
|
||||
#. %1: Wrong argument name
|
||||
#. %2: Comma separated list of allowed types
|
||||
#, kde-format
|
||||
msgctxt "VALIDATETYPES"
|
||||
msgid " « %1 » must have next type (or one of next types) : %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._Validate error message
|
||||
#. %1: Wrong argument name
|
||||
#. %2: Comma separated list of allowed values
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEVALUES"
|
||||
msgid " « %1 » must contain one of next values : %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._Validate error message
|
||||
#. %1: Wrong argument name
|
||||
#. %2: A regular expression
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEREGEX"
|
||||
msgid " « %1 » must match next regular expression : %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._Validate error message
|
||||
#. %1: Wrong argument name
|
||||
#. %2: The name of a Basic class
|
||||
#, kde-format
|
||||
msgctxt "VALIDATECLASS"
|
||||
msgid " « %1 » must be a Basic object of class : %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._Validate error message
|
||||
#. %1: Wrong argument name
|
||||
#. %2: The value of the argument as a string
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEACTUAL"
|
||||
msgid "The actual value of « %1 » is : '%2'"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._Validate error message
|
||||
#. %1: Wrong argument name
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEMISSING"
|
||||
msgid "The « %1 » argument is mandatory, yet it is missing."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._ValidateArray error message
|
||||
#. %1: Wrong argument name
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEARRAY"
|
||||
msgid " « %1 » must be an array."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._ValidateArray error message
|
||||
#. %1: Wrong argument name
|
||||
#. %2: Number of dimensions of the array
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEDIMS"
|
||||
msgid " « %1 » must have exactly %2 dimension(s)."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._ValidateArray error message
|
||||
#. %1: Wrong argument name
|
||||
#. %2: Either one single type or 'String, Date, Numeric'
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEALLTYPES"
|
||||
msgid " « %1 » must have all elements of the same type : %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._ValidateArray error message
|
||||
#. %1: Wrong argument name
|
||||
#. NULL and EMPTY should not be translated
|
||||
#, kde-format
|
||||
msgctxt "VALIDATENOTNULL"
|
||||
msgid " « %1 » must not contain any NULL or EMPTY elements."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._ValidateFile error message
|
||||
#. %1: Wrong argument name
|
||||
#. 'String' should not be translated
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEFILE"
|
||||
msgid " « %1 » must be of type String."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._ValidateFile error message
|
||||
#. %1: Wrong argument name
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEFILESYS"
|
||||
msgid ""
|
||||
" « %1 » must be a valid file or folder name expressed in the "
|
||||
"operating system native notation."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._ValidateFile error message
|
||||
#. %1: Wrong argument name
|
||||
#. 'URL' should not be translated
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEFILEURL"
|
||||
msgid ""
|
||||
" « %1 » must be a valid file or folder name expressed in the "
|
||||
"portable URL notation."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._ValidateFile error message
|
||||
#. %1: Wrong argument name
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEFILEANY"
|
||||
msgid " « %1 » must be a valid file or folder name."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._ValidateFile error message
|
||||
#. %1: Wrong argument name
|
||||
#. '(?, *)' is to be left as is
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEWILDCARD"
|
||||
msgid ""
|
||||
" « %1 » may contain one or more wildcard characters (?, *) in "
|
||||
"its last path component only."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Array.RangeInit error message
|
||||
#. %1, %2, %3: Numeric values
|
||||
#. 'From', 'UpTo', 'ByStep' should not be translated
|
||||
#, kde-format
|
||||
msgctxt "ARRAYSEQUENCE"
|
||||
msgid ""
|
||||
"The respective values of 'From', 'UpTo' and 'ByStep' are incoherent.\n"
|
||||
"\n"
|
||||
" « From » = %1\n"
|
||||
" « UpTo » = %2\n"
|
||||
" « ByStep » = %3"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Array.AppendColumn (...) error message
|
||||
#. %1: 'Column' or 'Row' of a matrix
|
||||
#. %2, %3: array contents
|
||||
#. 'Array_2D' should not be translated
|
||||
#, kde-format
|
||||
msgctxt "ARRAYINSERT"
|
||||
msgid ""
|
||||
"The array and the vector to insert have incompatible sizes.\n"
|
||||
"\n"
|
||||
" « Array_2D » = %2\n"
|
||||
" « %1 » = %3"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Array.ExtractColumn (...) error message
|
||||
#. %1: 'Column' or 'Row' of a matrix
|
||||
#. %2, %3: array contents
|
||||
#. 'Array_2D' should not be translated
|
||||
#, kde-format
|
||||
msgctxt "ARRAYINDEX1"
|
||||
msgid ""
|
||||
"The given index does not fit within the bounds of the array.\n"
|
||||
"\n"
|
||||
" « Array_2D » = %2\n"
|
||||
" « %1 » = %3"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Array.ExtractColumn (...) error message
|
||||
#. %1: 'Column' or 'Row' of a matrix
|
||||
#. %2, %3: array contents
|
||||
#. 'Array_1D', 'From' and 'UpTo' should not be translated
|
||||
#, kde-format
|
||||
msgctxt "ARRAYINDEX2"
|
||||
msgid ""
|
||||
"The given slice limits do not fit within the bounds of the array.\n"
|
||||
"\n"
|
||||
" « Array_1D » = %1\n"
|
||||
" « From » = %2\n"
|
||||
" « UpTo » = %3"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Array.ImportFromCSVFile error message
|
||||
#. %1: a file name
|
||||
#. %2: numeric
|
||||
#. %3: a long string
|
||||
#, kde-format
|
||||
msgctxt "CSVPARSING"
|
||||
msgid ""
|
||||
"The given file could not be parsed as a valid CSV file.\n"
|
||||
"\n"
|
||||
" « File name » = %1\n"
|
||||
" Line number = %2\n"
|
||||
" Content = %3"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Dictionary Add/ReplaceKey error message
|
||||
#. %1: An identifier%2: a (potentially long) string
|
||||
#, kde-format
|
||||
msgctxt "DUPLICATEKEY"
|
||||
msgid ""
|
||||
"The insertion of a new key into a dictionary failed because the key "
|
||||
"already exists.\n"
|
||||
"Note that the comparison between keys is NOT case-sensitive.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Dictionary Remove/ReplaceKey/ReplaceItem error message
|
||||
#. %1: An identifier%2: a (potentially long) string
|
||||
#, kde-format
|
||||
msgctxt "UNKNOWNKEY"
|
||||
msgid ""
|
||||
"The requested key does not exist in the dictionary.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Dictionary Add/ReplaceKey error message
|
||||
#.
|
||||
msgctxt "INVALIDKEY"
|
||||
msgid ""
|
||||
"The insertion or the update of an entry into a dictionary failed "
|
||||
"because the given key contains only spaces."
|
||||
msgstr ""
|
||||
|
||||
#. SF_FileSystem copy/move/delete error message
|
||||
#. %1: An identifier
|
||||
#. %2: A file name
|
||||
#, kde-format
|
||||
msgctxt "UNKNOWNFILE"
|
||||
msgid ""
|
||||
"The given file could not be found on your system.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_FileSystem copy/move/delete error message
|
||||
#. %1: An identifier
|
||||
#. %2: A folder name
|
||||
#, kde-format
|
||||
msgctxt "UNKNOWNFOLDER"
|
||||
msgid ""
|
||||
"The given folder could not be found on your system.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_FileSystem copy/move/delete error message
|
||||
#. %1: An identifier
|
||||
#. %2: A file name
|
||||
#, kde-format
|
||||
msgctxt "NOTAFILE"
|
||||
msgid ""
|
||||
"« %1 » contains the name of an existing folder, not that of a file.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_FileSystem copy/move/delete error message
|
||||
#. %1: An identifier
|
||||
#. %2: A folder name
|
||||
#, kde-format
|
||||
msgctxt "NOTAFOLDER"
|
||||
msgid ""
|
||||
"« %1 » contains the name of an existing file, not that of a folder.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_FileSystem copy/move/... error message
|
||||
#. %1: An identifier
|
||||
#. %2: A file name
|
||||
#, kde-format
|
||||
msgctxt "OVERWRITE"
|
||||
msgid ""
|
||||
"You tried to create a new file which already exists. Overwriting it "
|
||||
"has been rejected.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_FileSystem copy/move/delete error message
|
||||
#. %1: An identifier
|
||||
#. %2: A file name
|
||||
#, kde-format
|
||||
msgctxt "READONLY"
|
||||
msgid ""
|
||||
"Copying or moving a file to a destination which has its read-only "
|
||||
"attribute set, or deleting such a file or folder is forbidden.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_FileSystem copy/move/delete error message
|
||||
#. %1: An identifier
|
||||
#. %2: A file or folder name with wildcards
|
||||
#, kde-format
|
||||
msgctxt "NOFILEMATCH"
|
||||
msgid ""
|
||||
"When « %1 » contains wildcards. at least one file or folder must "
|
||||
"match the given filter. Otherwise the operation is rejected.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_FileSystem CreateFolder error message
|
||||
#. %1: An identifier
|
||||
#. %2: A file or folder name
|
||||
#, kde-format
|
||||
msgctxt "FOLDERCREATION"
|
||||
msgid ""
|
||||
"« %1 » contains the name of an existing file or an existing folder. "
|
||||
"The operation is rejected.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Services.CreateScriptService error message
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#. %3: A Basic library name
|
||||
#. %4: A service (1 word) name
|
||||
#, kde-format
|
||||
msgctxt "UNKNOWNSERVICE"
|
||||
msgid ""
|
||||
"No service named '%4' has been registered for the library '%3'.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Services.CreateScriptService error message
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#. %3: A Basic library name
|
||||
#, kde-format
|
||||
msgctxt "SERVICESNOTLOADED"
|
||||
msgid ""
|
||||
"The library '%3' and its services could not been loaded.\n"
|
||||
"The reason is unknown.\n"
|
||||
"However, checking the '%3.SF_Services.RegisterScriptServices()' "
|
||||
"function and its return value can be a good starting point.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Session.ExecuteCalcFunction error message
|
||||
#. 'Calc' should not be translated
|
||||
#, kde-format
|
||||
msgctxt "CALCFUNC"
|
||||
msgid ""
|
||||
"The Calc '%1' function encountered an error. Either the given "
|
||||
"function does not exist or its arguments are invalid."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Session._GetScript error message
|
||||
#. %1: 'Basic' or 'Python'
|
||||
#. %2: An identifier
|
||||
#. %3: A string
|
||||
#. %4: An identifier
|
||||
#. %5: A string
|
||||
#, kde-format
|
||||
msgctxt "NOSCRIPT"
|
||||
msgid ""
|
||||
"The requested %1 script could not be located in the given libraries "
|
||||
"and modules.\n"
|
||||
"« %2 » = %3\n"
|
||||
"« %4 » = %5"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Session.ExecuteBasicScript error message
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#. %3: A (long) string
|
||||
#, kde-format
|
||||
msgctxt "SCRIPTEXEC"
|
||||
msgid ""
|
||||
"An exception occurred during the execution of the Basic script.\n"
|
||||
"Cause: %3\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Session.SendMail error message
|
||||
#. %1 = a mail address
|
||||
#, kde-format
|
||||
msgctxt "WRONGEMAIL"
|
||||
msgid ""
|
||||
"One of the email addresses has been found invalid.\n"
|
||||
"Invalid mail = « %1 »"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Session.SendMail error message
|
||||
msgctxt "SENDMAIL"
|
||||
msgid ""
|
||||
"The message could not be sent due to a system error.\n"
|
||||
"A possible cause is that LibreOffice could not find any mail client."
|
||||
msgstr ""
|
||||
|
||||
#. SF_TextStream._IsFileOpen error message
|
||||
#. %1: A file name
|
||||
#, kde-format
|
||||
msgctxt "FILENOTOPEN"
|
||||
msgid ""
|
||||
"The requested file operation could not be executed because the file "
|
||||
"was closed previously.\n"
|
||||
"\n"
|
||||
"File name = '%1'"
|
||||
msgstr ""
|
||||
|
||||
#. SF_TextStream._IsFileOpen error message
|
||||
#. %1: A file name
|
||||
#. %2: READ, WRITE or APPEND
|
||||
#, kde-format
|
||||
msgctxt "FILEOPENMODE"
|
||||
msgid ""
|
||||
"The requested file operation could not be executed because it is "
|
||||
"incompatible with the mode in which the file was opened.\n"
|
||||
"\n"
|
||||
"File name = '%1'\n"
|
||||
"Open mode = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_TextStream.ReadLine/ReadAll/SkipLine error message
|
||||
#. %1: A file name
|
||||
#, kde-format
|
||||
msgctxt "ENDOFFILE"
|
||||
msgid ""
|
||||
"The requested file read operation could not be completed because an "
|
||||
"unexpected end-of-file was encountered.\n"
|
||||
"\n"
|
||||
"File name = '%1'"
|
||||
msgstr ""
|
||||
|
||||
#. SF_UI.GetDocument error message
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#, kde-format
|
||||
msgctxt "DOCUMENT"
|
||||
msgid ""
|
||||
"The requested document could not be found.\n"
|
||||
"\n"
|
||||
"%1 = '%2'"
|
||||
msgstr ""
|
||||
|
||||
#. SF_UI.GetDocument error message
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#. %3: An identifier
|
||||
#. %4: A string
|
||||
#, kde-format
|
||||
msgctxt "DOCUMENTCREATION"
|
||||
msgid ""
|
||||
"The creation of a new document failed.\n"
|
||||
"Something must be wrong with some arguments.\n"
|
||||
"\n"
|
||||
"Either the document type is unknown, or no template file was given,\n"
|
||||
"or the given template file was not found on your system.\n"
|
||||
"\n"
|
||||
"%1 = '%2'\n"
|
||||
"%3 = '%4'"
|
||||
msgstr ""
|
||||
|
||||
#. SF_UI.OpenDocument error message
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#. %3: An identifier
|
||||
#. %4: A string
|
||||
#. %5: An identifier
|
||||
#. %6: A string
|
||||
#, kde-format
|
||||
msgctxt "DOCUMENTOPEN"
|
||||
msgid ""
|
||||
"The opening of the document failed.\n"
|
||||
"Something must be wrong with some arguments.\n"
|
||||
"\n"
|
||||
"Either the file does not exist, or the password is wrong, or the "
|
||||
"given filter is invalid.\n"
|
||||
"\n"
|
||||
"%1 = '%2'\n"
|
||||
"%3 = '%4'\n"
|
||||
"%5 = '%6'"
|
||||
msgstr ""
|
||||
|
||||
#. SF_UI.OpenDocument error message
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#. %3: An identifier
|
||||
#. %4: A string
|
||||
#, kde-format
|
||||
msgctxt "BASEDOCUMENTOPEN"
|
||||
msgid ""
|
||||
"The opening of the Base document failed.\n"
|
||||
"Something must be wrong with some arguments.\n"
|
||||
"\n"
|
||||
"Either the file does not exist, or the file is not registered under "
|
||||
"the given name.\n"
|
||||
"\n"
|
||||
"%1 = '%2'\n"
|
||||
"%3 = '%4'"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Document._IsStillAlive error message
|
||||
#. %1: A file name
|
||||
#, kde-format
|
||||
msgctxt "DOCUMENTDEAD"
|
||||
msgid ""
|
||||
"The requested action could not be executed because the document was "
|
||||
"closed inadvertently.\n"
|
||||
"\n"
|
||||
"The concerned document is '%1'"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Document.SaveAs error message
|
||||
#. %1: An identifier
|
||||
#. %2: A file name
|
||||
#.
|
||||
#, kde-format
|
||||
msgctxt "DOCUMENTSAVE"
|
||||
msgid ""
|
||||
"The document could not be saved.\n"
|
||||
"Either the document has been opened read-only, or the destination "
|
||||
"file has a read-only attribute set, or the file where to save to is "
|
||||
"undefined.\n"
|
||||
"\n"
|
||||
"%1 = '%2'"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Document.SaveAs error message
|
||||
#. %1: An identifier
|
||||
#. %2: A file name
|
||||
#. %3: An identifier
|
||||
#. %4: True or False
|
||||
#. %5: An identifier
|
||||
#. %6: A string
|
||||
#, kde-format
|
||||
msgctxt "DOCUMENTSAVEAS"
|
||||
msgid ""
|
||||
"The document could not be saved.\n"
|
||||
"Either the document must not be overwritten, or the destination file "
|
||||
"has a read-only attribute set, or the given filter is invalid.\n"
|
||||
"\n"
|
||||
"%1 = '%2'\n"
|
||||
"%3 = %4\n"
|
||||
"%5 = '%6'"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Document any update
|
||||
#. %1: An identifier
|
||||
#. %2: A file name
|
||||
#, kde-format
|
||||
msgctxt "DOCUMENTREADONLY"
|
||||
msgid ""
|
||||
"You tried to edit a document which is not modifiable. The document "
|
||||
"has not been changed.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Base GetDatabase
|
||||
#. %1: An identifier
|
||||
#. %2: A user name
|
||||
#. %3: An identifier
|
||||
#. %4: A password
|
||||
#. %5: A file name
|
||||
#, kde-format
|
||||
msgctxt "DBCONNECT"
|
||||
msgid ""
|
||||
"The database related to the actual Base document could not be "
|
||||
"retrieved.\n"
|
||||
"Check the connection/login parameters.\n"
|
||||
"\n"
|
||||
"« %1 » = '%2'\n"
|
||||
"« %3 » = '%4'\n"
|
||||
"« Document » = %5"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Calc _ParseAddress (sheet)
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#. %3: An identifier
|
||||
#. %4: A file name
|
||||
#, kde-format
|
||||
msgctxt "CALCADDRESS1"
|
||||
msgid ""
|
||||
"The given address does not correspond with a valid sheet name.\n"
|
||||
"\n"
|
||||
"« %1 » = %2\n"
|
||||
"« %3 » = %4"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Calc _ParseAddress (range)
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#. %3: An identifier
|
||||
#. %4: A file name
|
||||
#, kde-format
|
||||
msgctxt "CALCADDRESS2"
|
||||
msgid ""
|
||||
"The given address does not correspond with a valid range of cells.\n"
|
||||
"\n"
|
||||
"« %1 » = %2\n"
|
||||
"« %3 » = %4"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Calc InsertSheet
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#. %3: An identifier
|
||||
#. %4: A file name
|
||||
#, kde-format
|
||||
msgctxt "DUPLICATESHEET"
|
||||
msgid ""
|
||||
"There exists already in the document a sheet with the same name.\n"
|
||||
"\n"
|
||||
"« %1 » = %2\n"
|
||||
"« %3 » = %4"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Calc Offset
|
||||
#. %1: An identifier
|
||||
#. %2: A Calc reference
|
||||
#. %3: An identifier
|
||||
#. %4: A number
|
||||
#. %5: An identifier
|
||||
#. %6: A number
|
||||
#. %7: An identifier
|
||||
#. %8: A number
|
||||
#. %9: An identifier
|
||||
#. %10: A number
|
||||
#. %11: An identifier
|
||||
#. %12: A file name
|
||||
#, kde-format
|
||||
msgctxt "OFFSETADDRESS"
|
||||
msgid ""
|
||||
"The computed range falls beyond the sheet boundaries or is "
|
||||
"meaningless.\n"
|
||||
"\n"
|
||||
"« %1 » = %2\n"
|
||||
"« %3 » = %4\n"
|
||||
"« %5 » = %6\n"
|
||||
"« %7 » = %8\n"
|
||||
"« %9 » = %10\n"
|
||||
"« %11 » = %12"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Calc CreateChart
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#. %3: An identifier
|
||||
#. %4: A string
|
||||
#. %5: An identifier
|
||||
#. %6: A file name
|
||||
#, kde-format
|
||||
msgctxt "DUPLICATECHART"
|
||||
msgid ""
|
||||
"A chart with the same name exists already in the sheet.\n"
|
||||
"\n"
|
||||
"« %1 » = %2\n"
|
||||
"« %3 » = %4\n"
|
||||
"« %5 » = %6\n"
|
||||
""
|
||||
msgstr ""
|
||||
|
||||
#. SF_Calc.ExportRangeToFile error message
|
||||
#. %1: An identifier
|
||||
#. %2: A file name
|
||||
#. %3: An identifier
|
||||
#. %4: True or False
|
||||
#.
|
||||
#, kde-format
|
||||
msgctxt "RANGEEXPORT"
|
||||
msgid ""
|
||||
"The given range could not be exported.\n"
|
||||
"Either the destination file must not be overwritten, or it has a "
|
||||
"read-only attribute set.\n"
|
||||
"\n"
|
||||
"%1 = '%2'\n"
|
||||
"%3 = %4"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Chart.ExportToFile error message
|
||||
#. %1: An identifier
|
||||
#. %2: A file name
|
||||
#. %3: An identifier
|
||||
#. %4: True or False
|
||||
#.
|
||||
#, kde-format
|
||||
msgctxt "CHARTEXPORT"
|
||||
msgid ""
|
||||
"The chart could not be exported.\n"
|
||||
"Either the destination file must not be overwritten, or it has a "
|
||||
"read-only attribute set.\n"
|
||||
"\n"
|
||||
"%1 = '%2'\n"
|
||||
"%3 = %4"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Dialog._IsStillAlive error message
|
||||
#. %1: An identifier%2: A file name
|
||||
#, kde-format
|
||||
msgctxt "FORMDEAD"
|
||||
msgid ""
|
||||
"The requested action could not be executed because the form is not "
|
||||
"open or the document was closed inadvertently.\n"
|
||||
"\n"
|
||||
"The concerned form is '%1' in document '%2'."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Form determination
|
||||
#. %1: A number
|
||||
#. %2: A sheet name
|
||||
#. %3: A file name
|
||||
#, kde-format
|
||||
msgctxt "CALCFORMNOTFOUND"
|
||||
msgid ""
|
||||
"The requested form could not be found in the Calc sheet. The given "
|
||||
"index is off-limits.\n"
|
||||
"\n"
|
||||
"The concerned Calc document is '%3'.\n"
|
||||
"\n"
|
||||
"The name of the sheet = '%2'\n"
|
||||
"The index = %1."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Form determination
|
||||
#. %1: A number
|
||||
#. %2: A file name
|
||||
#, kde-format
|
||||
msgctxt "WRITERFORMNOTFOUND"
|
||||
msgid ""
|
||||
"The requested form could not be found in the Writer document. The "
|
||||
"given index is off-limits.\n"
|
||||
"\n"
|
||||
"The concerned Writer document is '%2'.\n"
|
||||
"\n"
|
||||
"The index = %1."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Form determination
|
||||
#. %1: A number
|
||||
#. %2: A string
|
||||
#. %3: A file name
|
||||
#, kde-format
|
||||
msgctxt "BASEFORMNOTFOUND"
|
||||
msgid ""
|
||||
"The requested form could not be found in the form document '%2'. The "
|
||||
"given index is off-limits.\n"
|
||||
"\n"
|
||||
"The concerned Base document is '%3'.\n"
|
||||
"\n"
|
||||
"The index = %1."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Form determination
|
||||
#. %1: A form name
|
||||
#. %2: A form name
|
||||
#, kde-format
|
||||
msgctxt "SUBFORMNOTFOUND"
|
||||
msgid ""
|
||||
"The requested subform could not be found below the given main form.\n"
|
||||
"\n"
|
||||
"The main form = '%2'.\n"
|
||||
"The subform = '%1'."
|
||||
msgstr ""
|
||||
|
||||
#. SF_FormControl property setting
|
||||
#. %1: An identifier
|
||||
#. %2: An identifier
|
||||
#. %3: A string
|
||||
#. %4: An identifier
|
||||
#, kde-format
|
||||
msgctxt "FORMCONTROLTYPE"
|
||||
msgid ""
|
||||
"The control '%1' in form '%2' is of type '%3'.\n"
|
||||
"The property or method '%4' is not applicable on that type of form "
|
||||
"controls."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Dialog creation
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#. %3: An identifier
|
||||
#. %4: A file name
|
||||
#. %5: An identifier
|
||||
#. %6: A string
|
||||
#. %7: An identifier
|
||||
#. %8: A string
|
||||
#, kde-format
|
||||
msgctxt "DIALOGNOTFOUND"
|
||||
msgid ""
|
||||
"The requested dialog could not be located in the given container or "
|
||||
"library.\n"
|
||||
"« %1 » = %2\n"
|
||||
"« %3 » = %4\n"
|
||||
"« %5 » = %6\n"
|
||||
"« %7 » = %8"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Dialog._IsStillAlive error message
|
||||
#. %1: An identifier
|
||||
#, kde-format
|
||||
msgctxt "DIALOGDEAD"
|
||||
msgid ""
|
||||
"The requested action could not be executed because the dialog was "
|
||||
"closed inadvertently.\n"
|
||||
"\n"
|
||||
"The concerned dialog is '%1'."
|
||||
msgstr ""
|
||||
|
||||
#. SF_DialogControl property setting
|
||||
#. %1: An identifier
|
||||
#. %2: An identifier
|
||||
#. %3: A string
|
||||
#. %4: An identifier
|
||||
#, kde-format
|
||||
msgctxt "CONTROLTYPE"
|
||||
msgid ""
|
||||
"The control '%1' in dialog '%2' is of type '%3'.\n"
|
||||
"The property or method '%4' is not applicable on that type of dialog "
|
||||
"controls."
|
||||
msgstr ""
|
||||
|
||||
#. SF_DialogControl add line in textbox
|
||||
#. %1: An identifier
|
||||
#. %2: An identifier
|
||||
#, kde-format
|
||||
msgctxt "TEXTFIELD"
|
||||
msgid ""
|
||||
"The control '%1' in dialog '%2' is not a multiline text field.\n"
|
||||
"The requested method could not be executed."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Dialog Page Manager setting
|
||||
#. %1: An identifier
|
||||
#. %2: A list of names separated by commas
|
||||
#. %3: An identifier
|
||||
#. %4: A list of names separated by commas
|
||||
#. %5: An identifier
|
||||
#. %6: A list of names separated by commas
|
||||
#, kde-format
|
||||
msgctxt "PAGEMANAGER"
|
||||
msgid ""
|
||||
"The Page Manager could not be setup due to inconsistent arguments.\n"
|
||||
"\n"
|
||||
" %1 : « %2 »\n"
|
||||
" %3 : « %4 »\n"
|
||||
" %5 : « %6 »"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Database when running update SQL statement
|
||||
#. %1: The concerned method
|
||||
#, kde-format
|
||||
msgctxt "DBREADONLY"
|
||||
msgid ""
|
||||
"The database has been opened in read-only mode.\n"
|
||||
"The '%1' method must not be executed in this context."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Database can't interpret SQL statement
|
||||
#. %1: The statement
|
||||
#, kde-format
|
||||
msgctxt "SQLSYNTAX"
|
||||
msgid ""
|
||||
"An SQL statement could not be interpreted or executed by the "
|
||||
"database system.\n"
|
||||
"Check its syntax, table and/or field names, ...\n"
|
||||
"\n"
|
||||
"SQL Statement : « %1 »"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Exception.PythonShell error messageAPSO: to leave unchanged
|
||||
msgctxt "PYTHONSHELL"
|
||||
msgid ""
|
||||
"The APSO extension could not be located in your LibreOffice "
|
||||
"installation."
|
||||
msgstr ""
|
||||
|
||||
#. SFUnitTest could not locate the library gven as argument
|
||||
#. %1: The name of the library
|
||||
#, kde-format
|
||||
msgctxt "UNITTESTLIBRARY"
|
||||
msgid ""
|
||||
"The requested library could not be located.\n"
|
||||
"The UnitTest service has not been initialized.\n"
|
||||
"\n"
|
||||
"Library name : « %1 »"
|
||||
msgstr ""
|
||||
|
||||
#. SFUnitTest finds a RunTest() call in a inappropriate location
|
||||
#. %1: The name of a method
|
||||
#, kde-format
|
||||
msgctxt "UNITTESTMETHOD"
|
||||
msgid ""
|
||||
"The method '%1' is unexpected in the current context.\n"
|
||||
"The UnitTest service cannot proceed further with the on-going test."
|
||||
msgstr ""
|
||||
@@ -0,0 +1,992 @@
|
||||
#
|
||||
# This pristine POT file has been generated by LibreOffice/ScriptForge
|
||||
# Full documentation is available on https://help.libreoffice.org/
|
||||
#
|
||||
# *********************************************************************
|
||||
# *** The ScriptForge library and its associated libraries ***
|
||||
# *** are part of the LibreOffice project. ***
|
||||
# *********************************************************************
|
||||
#
|
||||
# ScriptForge Release 7.4
|
||||
# -----------------------
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: https://bugs.libreoffice.org/enter_bug.cgi?product=LibreOffice&bug_status=UNCONFIRMED&component=UI\n"
|
||||
"POT-Creation-Date: 2022-10-12 15:07:35\n"
|
||||
"PO-Revision-Date: YYYY-MM-DD HH:MM:SS\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <EMAIL@ADDRESS>\n"
|
||||
"Language: en_US\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n > 1;\n"
|
||||
"X-Generator: LibreOffice - ScriptForge\n"
|
||||
"X-Accelerator-Marker: ~\n"
|
||||
|
||||
#. Title in error message box
|
||||
#. %1: an error number
|
||||
#, kde-format
|
||||
msgctxt "ERRORNUMBER"
|
||||
msgid "Error %1"
|
||||
msgstr ""
|
||||
|
||||
#. Error message box
|
||||
#. %1: a line number
|
||||
#, kde-format
|
||||
msgctxt "ERRORLOCATION"
|
||||
msgid "Location : %1"
|
||||
msgstr ""
|
||||
|
||||
#. Logfile record
|
||||
#, kde-format
|
||||
msgctxt "LONGERRORDESC"
|
||||
msgid "Error %1 - Location = %2 - Description = %3"
|
||||
msgstr ""
|
||||
|
||||
#. Any blocking error message
|
||||
msgctxt "STOPEXECUTION"
|
||||
msgid "THE EXECUTION IS CANCELLED."
|
||||
msgstr ""
|
||||
|
||||
#. Any blocking error message
|
||||
#. %1: a method name
|
||||
#, kde-format
|
||||
msgctxt "NEEDMOREHELP"
|
||||
msgid "Do you want to receive more information about the '%1' method ?"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Exception.RaiseAbort error message
|
||||
msgctxt "INTERNALERROR"
|
||||
msgid ""
|
||||
"The ScriptForge library has crashed. The reason is unknown.\n"
|
||||
"Maybe a bug that could be reported on\n"
|
||||
" https://bugs.documentfoundation.org/\n"
|
||||
"\n"
|
||||
"More details : \n"
|
||||
"\n"
|
||||
""
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._Validate error message
|
||||
#. %1: probably ScriptForge
|
||||
#. %2: service or module name
|
||||
#. %3: property or method name where the error occurred
|
||||
#, kde-format
|
||||
msgctxt "VALIDATESOURCE"
|
||||
msgid ""
|
||||
"Library : %1\n"
|
||||
"Service : %2\n"
|
||||
"Method : %3"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._Validate error message
|
||||
#. %1: list of arguments of the method
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEARGS"
|
||||
msgid "Arguments: %1"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._Validate error message
|
||||
#. %1: Wrong argument name
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEERROR"
|
||||
msgid "A serious error has been detected in your code on argument : « %1 »."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils.Validate error message
|
||||
msgctxt "VALIDATIONRULES"
|
||||
msgid " Validation rules :"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._Validate error message
|
||||
#. %1: Wrong argument name
|
||||
#. %2: Comma separated list of allowed types
|
||||
#, kde-format
|
||||
msgctxt "VALIDATETYPES"
|
||||
msgid " « %1 » must have next type (or one of next types) : %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._Validate error message
|
||||
#. %1: Wrong argument name
|
||||
#. %2: Comma separated list of allowed values
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEVALUES"
|
||||
msgid " « %1 » must contain one of next values : %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._Validate error message
|
||||
#. %1: Wrong argument name
|
||||
#. %2: A regular expression
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEREGEX"
|
||||
msgid " « %1 » must match next regular expression : %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._Validate error message
|
||||
#. %1: Wrong argument name
|
||||
#. %2: The name of a Basic class
|
||||
#, kde-format
|
||||
msgctxt "VALIDATECLASS"
|
||||
msgid " « %1 » must be a Basic object of class : %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._Validate error message
|
||||
#. %1: Wrong argument name
|
||||
#. %2: The value of the argument as a string
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEACTUAL"
|
||||
msgid "The actual value of « %1 » is : '%2'"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._Validate error message
|
||||
#. %1: Wrong argument name
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEMISSING"
|
||||
msgid "The « %1 » argument is mandatory, yet it is missing."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._ValidateArray error message
|
||||
#. %1: Wrong argument name
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEARRAY"
|
||||
msgid " « %1 » must be an array."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._ValidateArray error message
|
||||
#. %1: Wrong argument name
|
||||
#. %2: Number of dimensions of the array
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEDIMS"
|
||||
msgid " « %1 » must have exactly %2 dimension(s)."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._ValidateArray error message
|
||||
#. %1: Wrong argument name
|
||||
#. %2: Either one single type or 'String, Date, Numeric'
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEALLTYPES"
|
||||
msgid " « %1 » must have all elements of the same type : %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._ValidateArray error message
|
||||
#. %1: Wrong argument name
|
||||
#. NULL and EMPTY should not be translated
|
||||
#, kde-format
|
||||
msgctxt "VALIDATENOTNULL"
|
||||
msgid " « %1 » must not contain any NULL or EMPTY elements."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._ValidateFile error message
|
||||
#. %1: Wrong argument name
|
||||
#. 'String' should not be translated
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEFILE"
|
||||
msgid " « %1 » must be of type String."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._ValidateFile error message
|
||||
#. %1: Wrong argument name
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEFILESYS"
|
||||
msgid ""
|
||||
" « %1 » must be a valid file or folder name expressed in the "
|
||||
"operating system native notation."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._ValidateFile error message
|
||||
#. %1: Wrong argument name
|
||||
#. 'URL' should not be translated
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEFILEURL"
|
||||
msgid ""
|
||||
" « %1 » must be a valid file or folder name expressed in the "
|
||||
"portable URL notation."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._ValidateFile error message
|
||||
#. %1: Wrong argument name
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEFILEANY"
|
||||
msgid " « %1 » must be a valid file or folder name."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Utils._ValidateFile error message
|
||||
#. %1: Wrong argument name
|
||||
#. '(?, *)' is to be left as is
|
||||
#, kde-format
|
||||
msgctxt "VALIDATEWILDCARD"
|
||||
msgid ""
|
||||
" « %1 » may contain one or more wildcard characters (?, *) in "
|
||||
"its last path component only."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Array.RangeInit error message
|
||||
#. %1, %2, %3: Numeric values
|
||||
#. 'From', 'UpTo', 'ByStep' should not be translated
|
||||
#, kde-format
|
||||
msgctxt "ARRAYSEQUENCE"
|
||||
msgid ""
|
||||
"The respective values of 'From', 'UpTo' and 'ByStep' are incoherent.\n"
|
||||
"\n"
|
||||
" « From » = %1\n"
|
||||
" « UpTo » = %2\n"
|
||||
" « ByStep » = %3"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Array.AppendColumn (...) error message
|
||||
#. %1: 'Column' or 'Row' of a matrix
|
||||
#. %2, %3: array contents
|
||||
#. 'Array_2D' should not be translated
|
||||
#, kde-format
|
||||
msgctxt "ARRAYINSERT"
|
||||
msgid ""
|
||||
"The array and the vector to insert have incompatible sizes.\n"
|
||||
"\n"
|
||||
" « Array_2D » = %2\n"
|
||||
" « %1 » = %3"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Array.ExtractColumn (...) error message
|
||||
#. %1: 'Column' or 'Row' of a matrix
|
||||
#. %2, %3: array contents
|
||||
#. 'Array_2D' should not be translated
|
||||
#, kde-format
|
||||
msgctxt "ARRAYINDEX1"
|
||||
msgid ""
|
||||
"The given index does not fit within the bounds of the array.\n"
|
||||
"\n"
|
||||
" « Array_2D » = %2\n"
|
||||
" « %1 » = %3"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Array.ExtractColumn (...) error message
|
||||
#. %1: 'Column' or 'Row' of a matrix
|
||||
#. %2, %3: array contents
|
||||
#. 'Array_1D', 'From' and 'UpTo' should not be translated
|
||||
#, kde-format
|
||||
msgctxt "ARRAYINDEX2"
|
||||
msgid ""
|
||||
"The given slice limits do not fit within the bounds of the array.\n"
|
||||
"\n"
|
||||
" « Array_1D » = %1\n"
|
||||
" « From » = %2\n"
|
||||
" « UpTo » = %3"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Array.ImportFromCSVFile error message
|
||||
#. %1: a file name
|
||||
#. %2: numeric
|
||||
#. %3: a long string
|
||||
#, kde-format
|
||||
msgctxt "CSVPARSING"
|
||||
msgid ""
|
||||
"The given file could not be parsed as a valid CSV file.\n"
|
||||
"\n"
|
||||
" « File name » = %1\n"
|
||||
" Line number = %2\n"
|
||||
" Content = %3"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Dictionary Add/ReplaceKey error message
|
||||
#. %1: An identifier%2: a (potentially long) string
|
||||
#, kde-format
|
||||
msgctxt "DUPLICATEKEY"
|
||||
msgid ""
|
||||
"The insertion of a new key into a dictionary failed because the key "
|
||||
"already exists.\n"
|
||||
"Note that the comparison between keys is NOT case-sensitive.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Dictionary Remove/ReplaceKey/ReplaceItem error message
|
||||
#. %1: An identifier%2: a (potentially long) string
|
||||
#, kde-format
|
||||
msgctxt "UNKNOWNKEY"
|
||||
msgid ""
|
||||
"The requested key does not exist in the dictionary.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Dictionary Add/ReplaceKey error message
|
||||
#.
|
||||
msgctxt "INVALIDKEY"
|
||||
msgid ""
|
||||
"The insertion or the update of an entry into a dictionary failed "
|
||||
"because the given key contains only spaces."
|
||||
msgstr ""
|
||||
|
||||
#. SF_FileSystem copy/move/delete error message
|
||||
#. %1: An identifier
|
||||
#. %2: A file name
|
||||
#, kde-format
|
||||
msgctxt "UNKNOWNFILE"
|
||||
msgid ""
|
||||
"The given file could not be found on your system.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_FileSystem copy/move/delete error message
|
||||
#. %1: An identifier
|
||||
#. %2: A folder name
|
||||
#, kde-format
|
||||
msgctxt "UNKNOWNFOLDER"
|
||||
msgid ""
|
||||
"The given folder could not be found on your system.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_FileSystem copy/move/delete error message
|
||||
#. %1: An identifier
|
||||
#. %2: A file name
|
||||
#, kde-format
|
||||
msgctxt "NOTAFILE"
|
||||
msgid ""
|
||||
"« %1 » contains the name of an existing folder, not that of a file.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_FileSystem copy/move/delete error message
|
||||
#. %1: An identifier
|
||||
#. %2: A folder name
|
||||
#, kde-format
|
||||
msgctxt "NOTAFOLDER"
|
||||
msgid ""
|
||||
"« %1 » contains the name of an existing file, not that of a folder.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_FileSystem copy/move/... error message
|
||||
#. %1: An identifier
|
||||
#. %2: A file name
|
||||
#, kde-format
|
||||
msgctxt "OVERWRITE"
|
||||
msgid ""
|
||||
"You tried to create a new file which already exists. Overwriting it "
|
||||
"has been rejected.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_FileSystem copy/move/delete error message
|
||||
#. %1: An identifier
|
||||
#. %2: A file name
|
||||
#, kde-format
|
||||
msgctxt "READONLY"
|
||||
msgid ""
|
||||
"Copying or moving a file to a destination which has its read-only "
|
||||
"attribute set, or deleting such a file or folder is forbidden.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_FileSystem copy/move/delete error message
|
||||
#. %1: An identifier
|
||||
#. %2: A file or folder name with wildcards
|
||||
#, kde-format
|
||||
msgctxt "NOFILEMATCH"
|
||||
msgid ""
|
||||
"When « %1 » contains wildcards. at least one file or folder must "
|
||||
"match the given filter. Otherwise the operation is rejected.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_FileSystem CreateFolder error message
|
||||
#. %1: An identifier
|
||||
#. %2: A file or folder name
|
||||
#, kde-format
|
||||
msgctxt "FOLDERCREATION"
|
||||
msgid ""
|
||||
"« %1 » contains the name of an existing file or an existing folder. "
|
||||
"The operation is rejected.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Services.CreateScriptService error message
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#. %3: A Basic library name
|
||||
#. %4: A service (1 word) name
|
||||
#, kde-format
|
||||
msgctxt "UNKNOWNSERVICE"
|
||||
msgid ""
|
||||
"No service named '%4' has been registered for the library '%3'.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Services.CreateScriptService error message
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#. %3: A Basic library name
|
||||
#, kde-format
|
||||
msgctxt "SERVICESNOTLOADED"
|
||||
msgid ""
|
||||
"The library '%3' and its services could not been loaded.\n"
|
||||
"The reason is unknown.\n"
|
||||
"However, checking the '%3.SF_Services.RegisterScriptServices()' "
|
||||
"function and its return value can be a good starting point.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Session.ExecuteCalcFunction error message
|
||||
#. 'Calc' should not be translated
|
||||
#, kde-format
|
||||
msgctxt "CALCFUNC"
|
||||
msgid ""
|
||||
"The Calc '%1' function encountered an error. Either the given "
|
||||
"function does not exist or its arguments are invalid."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Session._GetScript error message
|
||||
#. %1: 'Basic' or 'Python'
|
||||
#. %2: An identifier
|
||||
#. %3: A string
|
||||
#. %4: An identifier
|
||||
#. %5: A string
|
||||
#, kde-format
|
||||
msgctxt "NOSCRIPT"
|
||||
msgid ""
|
||||
"The requested %1 script could not be located in the given libraries "
|
||||
"and modules.\n"
|
||||
"« %2 » = %3\n"
|
||||
"« %4 » = %5"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Session.ExecuteBasicScript error message
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#. %3: A (long) string
|
||||
#, kde-format
|
||||
msgctxt "SCRIPTEXEC"
|
||||
msgid ""
|
||||
"An exception occurred during the execution of the Basic script.\n"
|
||||
"Cause: %3\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Session.SendMail error message
|
||||
#. %1 = a mail address
|
||||
#, kde-format
|
||||
msgctxt "WRONGEMAIL"
|
||||
msgid ""
|
||||
"One of the email addresses has been found invalid.\n"
|
||||
"Invalid mail = « %1 »"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Session.SendMail error message
|
||||
msgctxt "SENDMAIL"
|
||||
msgid ""
|
||||
"The message could not be sent due to a system error.\n"
|
||||
"A possible cause is that LibreOffice could not find any mail client."
|
||||
msgstr ""
|
||||
|
||||
#. SF_TextStream._IsFileOpen error message
|
||||
#. %1: A file name
|
||||
#, kde-format
|
||||
msgctxt "FILENOTOPEN"
|
||||
msgid ""
|
||||
"The requested file operation could not be executed because the file "
|
||||
"was closed previously.\n"
|
||||
"\n"
|
||||
"File name = '%1'"
|
||||
msgstr ""
|
||||
|
||||
#. SF_TextStream._IsFileOpen error message
|
||||
#. %1: A file name
|
||||
#. %2: READ, WRITE or APPEND
|
||||
#, kde-format
|
||||
msgctxt "FILEOPENMODE"
|
||||
msgid ""
|
||||
"The requested file operation could not be executed because it is "
|
||||
"incompatible with the mode in which the file was opened.\n"
|
||||
"\n"
|
||||
"File name = '%1'\n"
|
||||
"Open mode = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_TextStream.ReadLine/ReadAll/SkipLine error message
|
||||
#. %1: A file name
|
||||
#, kde-format
|
||||
msgctxt "ENDOFFILE"
|
||||
msgid ""
|
||||
"The requested file read operation could not be completed because an "
|
||||
"unexpected end-of-file was encountered.\n"
|
||||
"\n"
|
||||
"File name = '%1'"
|
||||
msgstr ""
|
||||
|
||||
#. SF_UI.GetDocument error message
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#, kde-format
|
||||
msgctxt "DOCUMENT"
|
||||
msgid ""
|
||||
"The requested document could not be found.\n"
|
||||
"\n"
|
||||
"%1 = '%2'"
|
||||
msgstr ""
|
||||
|
||||
#. SF_UI.GetDocument error message
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#. %3: An identifier
|
||||
#. %4: A string
|
||||
#, kde-format
|
||||
msgctxt "DOCUMENTCREATION"
|
||||
msgid ""
|
||||
"The creation of a new document failed.\n"
|
||||
"Something must be wrong with some arguments.\n"
|
||||
"\n"
|
||||
"Either the document type is unknown, or no template file was given,\n"
|
||||
"or the given template file was not found on your system.\n"
|
||||
"\n"
|
||||
"%1 = '%2'\n"
|
||||
"%3 = '%4'"
|
||||
msgstr ""
|
||||
|
||||
#. SF_UI.OpenDocument error message
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#. %3: An identifier
|
||||
#. %4: A string
|
||||
#. %5: An identifier
|
||||
#. %6: A string
|
||||
#, kde-format
|
||||
msgctxt "DOCUMENTOPEN"
|
||||
msgid ""
|
||||
"The opening of the document failed.\n"
|
||||
"Something must be wrong with some arguments.\n"
|
||||
"\n"
|
||||
"Either the file does not exist, or the password is wrong, or the "
|
||||
"given filter is invalid.\n"
|
||||
"\n"
|
||||
"%1 = '%2'\n"
|
||||
"%3 = '%4'\n"
|
||||
"%5 = '%6'"
|
||||
msgstr ""
|
||||
|
||||
#. SF_UI.OpenDocument error message
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#. %3: An identifier
|
||||
#. %4: A string
|
||||
#, kde-format
|
||||
msgctxt "BASEDOCUMENTOPEN"
|
||||
msgid ""
|
||||
"The opening of the Base document failed.\n"
|
||||
"Something must be wrong with some arguments.\n"
|
||||
"\n"
|
||||
"Either the file does not exist, or the file is not registered under "
|
||||
"the given name.\n"
|
||||
"\n"
|
||||
"%1 = '%2'\n"
|
||||
"%3 = '%4'"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Document._IsStillAlive error message
|
||||
#. %1: A file name
|
||||
#, kde-format
|
||||
msgctxt "DOCUMENTDEAD"
|
||||
msgid ""
|
||||
"The requested action could not be executed because the document was "
|
||||
"closed inadvertently.\n"
|
||||
"\n"
|
||||
"The concerned document is '%1'"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Document.SaveAs error message
|
||||
#. %1: An identifier
|
||||
#. %2: A file name
|
||||
#.
|
||||
#, kde-format
|
||||
msgctxt "DOCUMENTSAVE"
|
||||
msgid ""
|
||||
"The document could not be saved.\n"
|
||||
"Either the document has been opened read-only, or the destination "
|
||||
"file has a read-only attribute set, or the file where to save to is "
|
||||
"undefined.\n"
|
||||
"\n"
|
||||
"%1 = '%2'"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Document.SaveAs error message
|
||||
#. %1: An identifier
|
||||
#. %2: A file name
|
||||
#. %3: An identifier
|
||||
#. %4: True or False
|
||||
#. %5: An identifier
|
||||
#. %6: A string
|
||||
#, kde-format
|
||||
msgctxt "DOCUMENTSAVEAS"
|
||||
msgid ""
|
||||
"The document could not be saved.\n"
|
||||
"Either the document must not be overwritten, or the destination file "
|
||||
"has a read-only attribute set, or the given filter is invalid.\n"
|
||||
"\n"
|
||||
"%1 = '%2'\n"
|
||||
"%3 = %4\n"
|
||||
"%5 = '%6'"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Document any update
|
||||
#. %1: An identifier
|
||||
#. %2: A file name
|
||||
#, kde-format
|
||||
msgctxt "DOCUMENTREADONLY"
|
||||
msgid ""
|
||||
"You tried to edit a document which is not modifiable. The document "
|
||||
"has not been changed.\n"
|
||||
"\n"
|
||||
"« %1 » = %2"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Base GetDatabase
|
||||
#. %1: An identifier
|
||||
#. %2: A user name
|
||||
#. %3: An identifier
|
||||
#. %4: A password
|
||||
#. %5: A file name
|
||||
#, kde-format
|
||||
msgctxt "DBCONNECT"
|
||||
msgid ""
|
||||
"The database related to the actual Base document could not be "
|
||||
"retrieved.\n"
|
||||
"Check the connection/login parameters.\n"
|
||||
"\n"
|
||||
"« %1 » = '%2'\n"
|
||||
"« %3 » = '%4'\n"
|
||||
"« Document » = %5"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Calc _ParseAddress (sheet)
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#. %3: An identifier
|
||||
#. %4: A file name
|
||||
#, kde-format
|
||||
msgctxt "CALCADDRESS1"
|
||||
msgid ""
|
||||
"The given address does not correspond with a valid sheet name.\n"
|
||||
"\n"
|
||||
"« %1 » = %2\n"
|
||||
"« %3 » = %4"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Calc _ParseAddress (range)
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#. %3: An identifier
|
||||
#. %4: A file name
|
||||
#, kde-format
|
||||
msgctxt "CALCADDRESS2"
|
||||
msgid ""
|
||||
"The given address does not correspond with a valid range of cells.\n"
|
||||
"\n"
|
||||
"« %1 » = %2\n"
|
||||
"« %3 » = %4"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Calc InsertSheet
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#. %3: An identifier
|
||||
#. %4: A file name
|
||||
#, kde-format
|
||||
msgctxt "DUPLICATESHEET"
|
||||
msgid ""
|
||||
"There exists already in the document a sheet with the same name.\n"
|
||||
"\n"
|
||||
"« %1 » = %2\n"
|
||||
"« %3 » = %4"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Calc Offset
|
||||
#. %1: An identifier
|
||||
#. %2: A Calc reference
|
||||
#. %3: An identifier
|
||||
#. %4: A number
|
||||
#. %5: An identifier
|
||||
#. %6: A number
|
||||
#. %7: An identifier
|
||||
#. %8: A number
|
||||
#. %9: An identifier
|
||||
#. %10: A number
|
||||
#. %11: An identifier
|
||||
#. %12: A file name
|
||||
#, kde-format
|
||||
msgctxt "OFFSETADDRESS"
|
||||
msgid ""
|
||||
"The computed range falls beyond the sheet boundaries or is "
|
||||
"meaningless.\n"
|
||||
"\n"
|
||||
"« %1 » = %2\n"
|
||||
"« %3 » = %4\n"
|
||||
"« %5 » = %6\n"
|
||||
"« %7 » = %8\n"
|
||||
"« %9 » = %10\n"
|
||||
"« %11 » = %12"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Calc CreateChart
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#. %3: An identifier
|
||||
#. %4: A string
|
||||
#. %5: An identifier
|
||||
#. %6: A file name
|
||||
#, kde-format
|
||||
msgctxt "DUPLICATECHART"
|
||||
msgid ""
|
||||
"A chart with the same name exists already in the sheet.\n"
|
||||
"\n"
|
||||
"« %1 » = %2\n"
|
||||
"« %3 » = %4\n"
|
||||
"« %5 » = %6\n"
|
||||
""
|
||||
msgstr ""
|
||||
|
||||
#. SF_Calc.ExportRangeToFile error message
|
||||
#. %1: An identifier
|
||||
#. %2: A file name
|
||||
#. %3: An identifier
|
||||
#. %4: True or False
|
||||
#.
|
||||
#, kde-format
|
||||
msgctxt "RANGEEXPORT"
|
||||
msgid ""
|
||||
"The given range could not be exported.\n"
|
||||
"Either the destination file must not be overwritten, or it has a "
|
||||
"read-only attribute set.\n"
|
||||
"\n"
|
||||
"%1 = '%2'\n"
|
||||
"%3 = %4"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Chart.ExportToFile error message
|
||||
#. %1: An identifier
|
||||
#. %2: A file name
|
||||
#. %3: An identifier
|
||||
#. %4: True or False
|
||||
#.
|
||||
#, kde-format
|
||||
msgctxt "CHARTEXPORT"
|
||||
msgid ""
|
||||
"The chart could not be exported.\n"
|
||||
"Either the destination file must not be overwritten, or it has a "
|
||||
"read-only attribute set.\n"
|
||||
"\n"
|
||||
"%1 = '%2'\n"
|
||||
"%3 = %4"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Dialog._IsStillAlive error message
|
||||
#. %1: An identifier%2: A file name
|
||||
#, kde-format
|
||||
msgctxt "FORMDEAD"
|
||||
msgid ""
|
||||
"The requested action could not be executed because the form is not "
|
||||
"open or the document was closed inadvertently.\n"
|
||||
"\n"
|
||||
"The concerned form is '%1' in document '%2'."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Form determination
|
||||
#. %1: A number
|
||||
#. %2: A sheet name
|
||||
#. %3: A file name
|
||||
#, kde-format
|
||||
msgctxt "CALCFORMNOTFOUND"
|
||||
msgid ""
|
||||
"The requested form could not be found in the Calc sheet. The given "
|
||||
"index is off-limits.\n"
|
||||
"\n"
|
||||
"The concerned Calc document is '%3'.\n"
|
||||
"\n"
|
||||
"The name of the sheet = '%2'\n"
|
||||
"The index = %1."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Form determination
|
||||
#. %1: A number
|
||||
#. %2: A file name
|
||||
#, kde-format
|
||||
msgctxt "WRITERFORMNOTFOUND"
|
||||
msgid ""
|
||||
"The requested form could not be found in the Writer document. The "
|
||||
"given index is off-limits.\n"
|
||||
"\n"
|
||||
"The concerned Writer document is '%2'.\n"
|
||||
"\n"
|
||||
"The index = %1."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Form determination
|
||||
#. %1: A number
|
||||
#. %2: A string
|
||||
#. %3: A file name
|
||||
#, kde-format
|
||||
msgctxt "BASEFORMNOTFOUND"
|
||||
msgid ""
|
||||
"The requested form could not be found in the form document '%2'. The "
|
||||
"given index is off-limits.\n"
|
||||
"\n"
|
||||
"The concerned Base document is '%3'.\n"
|
||||
"\n"
|
||||
"The index = %1."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Form determination
|
||||
#. %1: A form name
|
||||
#. %2: A form name
|
||||
#, kde-format
|
||||
msgctxt "SUBFORMNOTFOUND"
|
||||
msgid ""
|
||||
"The requested subform could not be found below the given main form.\n"
|
||||
"\n"
|
||||
"The main form = '%2'.\n"
|
||||
"The subform = '%1'."
|
||||
msgstr ""
|
||||
|
||||
#. SF_FormControl property setting
|
||||
#. %1: An identifier
|
||||
#. %2: An identifier
|
||||
#. %3: A string
|
||||
#. %4: An identifier
|
||||
#, kde-format
|
||||
msgctxt "FORMCONTROLTYPE"
|
||||
msgid ""
|
||||
"The control '%1' in form '%2' is of type '%3'.\n"
|
||||
"The property or method '%4' is not applicable on that type of form "
|
||||
"controls."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Dialog creation
|
||||
#. %1: An identifier
|
||||
#. %2: A string
|
||||
#. %3: An identifier
|
||||
#. %4: A file name
|
||||
#. %5: An identifier
|
||||
#. %6: A string
|
||||
#. %7: An identifier
|
||||
#. %8: A string
|
||||
#, kde-format
|
||||
msgctxt "DIALOGNOTFOUND"
|
||||
msgid ""
|
||||
"The requested dialog could not be located in the given container or "
|
||||
"library.\n"
|
||||
"« %1 » = %2\n"
|
||||
"« %3 » = %4\n"
|
||||
"« %5 » = %6\n"
|
||||
"« %7 » = %8"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Dialog._IsStillAlive error message
|
||||
#. %1: An identifier
|
||||
#, kde-format
|
||||
msgctxt "DIALOGDEAD"
|
||||
msgid ""
|
||||
"The requested action could not be executed because the dialog was "
|
||||
"closed inadvertently.\n"
|
||||
"\n"
|
||||
"The concerned dialog is '%1'."
|
||||
msgstr ""
|
||||
|
||||
#. SF_DialogControl property setting
|
||||
#. %1: An identifier
|
||||
#. %2: An identifier
|
||||
#. %3: A string
|
||||
#. %4: An identifier
|
||||
#, kde-format
|
||||
msgctxt "CONTROLTYPE"
|
||||
msgid ""
|
||||
"The control '%1' in dialog '%2' is of type '%3'.\n"
|
||||
"The property or method '%4' is not applicable on that type of dialog "
|
||||
"controls."
|
||||
msgstr ""
|
||||
|
||||
#. SF_DialogControl add line in textbox
|
||||
#. %1: An identifier
|
||||
#. %2: An identifier
|
||||
#, kde-format
|
||||
msgctxt "TEXTFIELD"
|
||||
msgid ""
|
||||
"The control '%1' in dialog '%2' is not a multiline text field.\n"
|
||||
"The requested method could not be executed."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Dialog Page Manager setting
|
||||
#. %1: An identifier
|
||||
#. %2: A list of names separated by commas
|
||||
#. %3: An identifier
|
||||
#. %4: A list of names separated by commas
|
||||
#. %5: An identifier
|
||||
#. %6: A list of names separated by commas
|
||||
#, kde-format
|
||||
msgctxt "PAGEMANAGER"
|
||||
msgid ""
|
||||
"The Page Manager could not be setup due to inconsistent arguments.\n"
|
||||
"\n"
|
||||
" %1 : « %2 »\n"
|
||||
" %3 : « %4 »\n"
|
||||
" %5 : « %6 »"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Database when running update SQL statement
|
||||
#. %1: The concerned method
|
||||
#, kde-format
|
||||
msgctxt "DBREADONLY"
|
||||
msgid ""
|
||||
"The database has been opened in read-only mode.\n"
|
||||
"The '%1' method must not be executed in this context."
|
||||
msgstr ""
|
||||
|
||||
#. SF_Database can't interpret SQL statement
|
||||
#. %1: The statement
|
||||
#, kde-format
|
||||
msgctxt "SQLSYNTAX"
|
||||
msgid ""
|
||||
"An SQL statement could not be interpreted or executed by the "
|
||||
"database system.\n"
|
||||
"Check its syntax, table and/or field names, ...\n"
|
||||
"\n"
|
||||
"SQL Statement : « %1 »"
|
||||
msgstr ""
|
||||
|
||||
#. SF_Exception.PythonShell error messageAPSO: to leave unchanged
|
||||
msgctxt "PYTHONSHELL"
|
||||
msgid ""
|
||||
"The APSO extension could not be located in your LibreOffice "
|
||||
"installation."
|
||||
msgstr ""
|
||||
|
||||
#. SFUnitTest could not locate the library gven as argument
|
||||
#. %1: The name of the library
|
||||
#, kde-format
|
||||
msgctxt "UNITTESTLIBRARY"
|
||||
msgid ""
|
||||
"The requested library could not be located.\n"
|
||||
"The UnitTest service has not been initialized.\n"
|
||||
"\n"
|
||||
"Library name : « %1 »"
|
||||
msgstr ""
|
||||
|
||||
#. SFUnitTest finds a RunTest() call in a inappropriate location
|
||||
#. %1: The name of a method
|
||||
#, kde-format
|
||||
msgctxt "UNITTESTMETHOD"
|
||||
msgid ""
|
||||
"The method '%1' is unexpected in the current context.\n"
|
||||
"The UnitTest service cannot proceed further with the on-going test."
|
||||
msgstr ""
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,23 @@
|
||||
<?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="ScriptForge" library:readonly="false" library:passwordprotected="false">
|
||||
<library:element library:name="__License"/>
|
||||
<library:element library:name="SF_String"/>
|
||||
<library:element library:name="_CodingConventions"/>
|
||||
<library:element library:name="SF_Timer"/>
|
||||
<library:element library:name="_ModuleModel"/>
|
||||
<library:element library:name="SF_Utils"/>
|
||||
<library:element library:name="SF_Root"/>
|
||||
<library:element library:name="SF_Array"/>
|
||||
<library:element library:name="SF_Services"/>
|
||||
<library:element library:name="SF_Dictionary"/>
|
||||
<library:element library:name="SF_Session"/>
|
||||
<library:element library:name="SF_FileSystem"/>
|
||||
<library:element library:name="SF_TextStream"/>
|
||||
<library:element library:name="SF_L10N"/>
|
||||
<library:element library:name="SF_Exception"/>
|
||||
<library:element library:name="SF_UI"/>
|
||||
<library:element library:name="SF_Platform"/>
|
||||
<library:element library:name="SF_PythonHelper"/>
|
||||
<library:element library:name="SF_Region"/>
|
||||
</library:library>
|
||||
Reference in New Issue
Block a user