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 ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' ''' SF_Root ''' ======= ''' FOR INTERNAL USE ONLY ''' Singleton class holding all persistent variables shared ''' by all the modules of the ScriptForge library ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' REM ============================================================= PRIVATE MEMBERS ' Internals Private [Me] As Object Private [_Parent] As Object Private ObjectType As String ' Must be "ROOT" Private MainFunction As String ' Name of method or property called by user script Private MainFunctionArgs As String ' Syntax of method called by user script Private StackLevel As Integer ' Depth of calls between internal methods ' Error management Private ErrorHandler As Boolean ' True = error handling active, False = internal debugging Private ConsoleLines() As Variant ' Array of messages displayable in console Private ConsoleDialog As Object ' SFDialogs.Dialog object Private ConsoleControl As Object ' SFDialogs.DialogControl object Private DisplayEnabled As Boolean ' When True, display of console or error messages is allowed Private StopWhenError As Boolean ' When True, process stops after error > "WARNING" Private DebugMode As Boolean ' When True, log enter/exit each official Sub ' Services management Private ServicesList As Variant ' Dictionary of provided services ' Usual UNO services Private FunctionAccess As Object ' com.sun.star.sheet.FunctionAccess Private PathSettings As Object ' com.sun.star.util.PathSettings Private PathSubstitution As Object ' com.sun.star.util.PathSubstitution Private ScriptProvider As Object ' com.sun.star.script.provider.MasterScriptProviderFactory Private SystemShellExecute As Object ' com.sun.star.system.SystemShellExecute Private CoreReflection As Object ' com.sun.star.reflection.CoreReflection Private DispatchHelper As Object ' com.sun.star.frame.DispatchHelper Private TextSearch As Object ' com.sun.star.util.TextSearch Private SearchOptions As Object ' com.sun.star.util.SearchOptions Private Locale As Object ' com.sun.star.lang.Locale Private CharacterClass As Object ' com.sun.star.i18n.CharacterClassification Private FileAccess As Object ' com.sun.star.ucb.SimpleFileAccess Private FilterFactory As Object ' com.sun.star.document.FilterFactory Private FolderPicker As Object ' com.sun.star.ui.dialogs.FolderPicker Private FilePicker As Object ' com.sun.star.ui.dialogs.FilePicker Private URLTransformer As Object ' com.sun.star.util.URLTransformer Private Introspection As Object ' com.sun.star.beans.Introspection Private BrowseNodeFactory As Object ' com.sun.star.script.browse.BrowseNodeFactory Private DatabaseContext As Object ' com.sun.star.sdb.DatabaseContext Private ConfigurationProvider _ As Object ' com.sun.star.configuration.ConfigurationProvider Private MailService As Object ' com.sun.star.system.SimpleCommandMail or com.sun.star.system.SimpleSystemMail Private TreeDataModel As Object ' com.sun.star.awt.tree.MutableTreeDataModel ' Specific persistent services objects or properties Private FileSystemNaming As String ' If "SYS", file and folder naming is based on operating system notation Private PythonHelper As String ' File name of Python helper functions (stored in $(inst)/share/Scripts/python) Private Interface As Object ' ScriptForge own L10N service Private OSName As String ' WIN, LINUX, MACOS Private SFDialogs As Variant ' Persistent storage for the SFDialogs library Private SFForms As Variant ' Persistent storage for the SF_Form class in the SFDocuments library REM ====================================================== CONSTRUCTOR/DESTRUCTOR REM ----------------------------------------------------------------------------- Private Sub Class_Initialize() Set [Me] = Nothing Set [_Parent] = Nothing ObjectType = "ROOT" MainFunction = "" MainFunctionArgs = "" StackLevel = 0 ErrorHandler = True ConsoleLines = Array() Set ConsoleDialog = Nothing Set ConsoleControl = Nothing DisplayEnabled = True StopWhenError = True DebugMode = False ServicesList = Empty Set FunctionAccess = Nothing Set PathSettings = Nothing Set PathSubstitution = Nothing Set ScriptProvider = Nothing Set SystemShellExecute = Nothing Set CoreReflection = Nothing Set DispatchHelper = Nothing Set TextSearch = Nothing Set SearchOptions = Nothing Set Locale = Nothing Set CharacterClass = Nothing Set FileAccess = Nothing Set FilterFactory = Nothing Set FolderPicker = Nothing Set FilePicker = Nothing Set URLTransformer = Nothing Set Introspection = Nothing FileSystemNaming = "ANY" PythonHelper = "ScriptForgeHelper.py" Set Interface = Nothing Set BrowseNodeFactory = Nothing Set DatabaseContext = Nothing Set ConfigurationProvider = Nothing Set MailService = Nothing Set TreeDataModel = Nothing OSName = "" SFDialogs = Empty SFForms = Empty End Sub ' ScriptForge.SF_Root Constructor REM ----------------------------------------------------------------------------- Private Sub Class_Terminate() Call Class_Initialize() End Sub ' ScriptForge.SF_Root Destructor REM ----------------------------------------------------------------------------- Public Function Dispose() As Variant Call Class_Terminate() Set Dispose = Nothing End Function ' ScriptForge.SF_Root Explicit destructor REM =========================================================== PRIVATE FUNCTIONS REM ----------------------------------------------------------------------------- Public Sub _AddToConsole(ByVal psLine As String) ''' Add a new line to the console ''' TAB characters are expanded before the insertion of the line ''' NB: Array redimensioning of a member of an object must be done in the class module ''' Args: ''' psLine: the line to add Dim lConsole As Long ' UBound of ConsoleLines Dim sLine As String ' Alias of psLine ' Resize ConsoleLines lConsole = UBound(ConsoleLines) If lConsole < 0 Then ReDim ConsoleLines(0) Else ReDim Preserve ConsoleLines(0 To lConsole + 1) End If ' Add a timestamp to the line and insert it (without date) sLine = Mid(SF_Utils._Repr(Now()), 12) & " -> " & psLine ConsoleLines(lConsole + 1) = Mid(SF_Utils._Repr(Now()), 12) & " -> " & psLine ' Add the new line to the actual (probably non-modal) console, if active If Not IsNull(ConsoleDialog) Then If ConsoleDialog._IsStillAlive(False) Then ' False to not raise an error If IsNull(ConsoleControl) Then Set ConsoleControl = ConsoleDialog.Controls(SF_Exception.CONSOLENAME) ' Should not happen ... ConsoleControl.WriteLine(sLine) End If End If End Sub ' ScriptForge.SF_Root._AddToConsole REM ----------------------------------------------------------------------------- Public Sub _LoadLocalizedInterface(Optional ByVal psMode As String) ''' Build the user interface in a persistent L10N object ''' Executed - only once - at first ScriptForge invocation by a user script ''' Args: ''' psMode: ADDTEXT => the (english) labels are loaded from code below ''' POFILE => the localized labels are loaded from a PO file ''' the name of the file is "la.po" where la = language part of locale ''' (fallback to ADDTEXT mode if file does not exist) Dim sInstallFolder As String ' ScriptForge installation directory Dim sPOFolder As String ' Folder containing the PO files Dim sPOFile As String ' PO File to load Dim sLocale As String ' Locale If ErrorHandler Then On Local Error GoTo Catch Try: 'TODO: Modify default value If IsMissing(psMode) Then psMode = "POFILE" If psMode = "POFILE" Then ' Use this mode in production ' Build the po file name With SF_FileSystem sInstallFolder = ._SFInstallFolder() ' ScriptForge installation folder sLocale = SF_Utils._GetUNOService("Locale").Language sPOFolder = .BuildPath(sInstallFolder, "po") sPOFile = .BuildPath(sPOFolder, sLocale & ".po") If Not .FileExists(sPOFile) Then ' File not found => load texts from code below psMode = "ADDTEXT" Else Set Interface = CreateScriptService("L10N", sPOFolder, sLocale) End If End With End If If psMode = "ADDTEXT" Then ' Use this mode in development to prepare a new POT file Set Interface = CreateScriptService("L10N") With Interface ' SF_Exception.Raise .AddText( Context := "CLOSEBUTTON" _ , MsgId := "Close" _ , Comment := "Text in close buttons of progress and console dialog boxes" _ ) .AddText( Context := "ERRORNUMBER" _ , MsgId := "Error %1" _ , Comment := "Title in error message box\n" _ & "%1: an error number" _ ) .AddText( Context := "ERRORLOCATION" _ , MsgId := "Location : %1" _ , Comment := "Error message box\n" _ & "%1: a line number" _ ) .AddText( Context := "LONGERRORDESC" _ , MsgId := "Error %1 - Location = %2 - Description = %3" _ , Comment := "Logfile record" _ ) .AddText( Context := "STOPEXECUTION" _ , MsgId := "THE EXECUTION IS CANCELLED." _ , Comment := "SF_Utils._Validate error message" _ ) ' SF_Exception.RaiseAbort .AddText( Context := "INTERNALERROR" _ , MsgId := "The ScriptForge library has crashed. The reason is unknown.\n" _ & "Maybe a bug that could be reported on\n" _ & "\thttps://bugs.documentfoundation.org/\n\n" _ & "More details : \n\n" _ , Comment := "SF_Exception.RaiseAbort error message" _ ) ' SF_Utils._Validate .AddText( Context := "VALIDATESOURCE" _ , MsgId := "Library : \t%1\nService : \t%2\nMethod : \t%3" _ , Comment := "SF_Utils._Validate error message\n" _ & "%1: probably ScriptForge\n" _ & "%2: service or module name\n" _ & "%3: property or method name where the error occurred" _ ) .AddText( Context := "VALIDATEARGS" _ , MsgId := "Arguments: %1" _ , Comment := "SF_Utils._Validate error message\n" _ & "%1: list of arguments of the method" _ ) .AddText( Context := "VALIDATEERROR" _ , MsgId := "A serious error has been detected in your code on argument : « %1 »." _ , Comment := "SF_Utils._Validate error message\n" _ & "%1: Wrong argument name" _ ) .AddText( Context := "VALIDATIONRULES" _ , MsgId := "\tValidation rules :", Comment := "SF_Utils.Validate error message" _ ) .AddText( Context := "VALIDATETYPES" _ , MsgId := "\t\t« %1 » must have next type (or one of next types) : %2" _ , Comment := "SF_Utils._Validate error message\n" _ & "%1: Wrong argument name\n" _ & "%2: Comma separated list of allowed types" _ ) .AddText( Context := "VALIDATEVALUES" _ , MsgId := "\t\t« %1 » must contain one of next values : %2" _ , Comment := "SF_Utils._Validate error message\n" _ & "%1: Wrong argument name\n" _ & "%2: Comma separated list of allowed values" _ ) .AddText( Context := "VALIDATEREGEX" _ , MsgId := "\t\t« %1 » must match next regular expression : %2" _ , Comment := "SF_Utils._Validate error message\n" _ & "%1: Wrong argument name\n" _ & "%2: A regular expression" _ ) .AddText( Context := "VALIDATECLASS" _ , MsgId := "\t\t« %1 » must be a Basic object of class : %2" _ , Comment := "SF_Utils._Validate error message\n" _ & "%1: Wrong argument name\n" _ & "%2: The name of a Basic class" _ ) .AddText( Context := "VALIDATEACTUAL" _ , MsgId := "The actual value of « %1 » is : '%2'" _ , Comment := "SF_Utils._Validate error message\n" _ & "%1: Wrong argument name\n" _ & "%2: The value of the argument as a string" _ ) .AddText( Context := "VALIDATEMISSING" _ , MsgId := "The « %1 » argument is mandatory, yet it is missing." _ , Comment := "SF_Utils._Validate error message\n" _ & "%1: Wrong argument name" _ ) ' SF_Utils._ValidateArray .AddText( Context := "VALIDATEARRAY" _ , MsgId := "\t\t« %1 » must be an array." _ , Comment := "SF_Utils._ValidateArray error message\n" _ & "%1: Wrong argument name" _ ) .AddText( Context := "VALIDATEDIMS" _ , MsgId := "\t\t« %1 » must have exactly %2 dimension(s)." _ , Comment := "SF_Utils._ValidateArray error message\n" _ & "%1: Wrong argument name\n" _ & "%2: Number of dimensions of the array" _ ) .AddText( Context := "VALIDATEALLTYPES" _ , MsgId := "\t\t« %1 » must have all elements of the same type : %2" _ , Comment := "SF_Utils._ValidateArray error message\n" _ & "%1: Wrong argument name\n" _ & "%2: Either one single type or 'String, Date, Numeric'" _ ) .AddText( Context := "VALIDATENOTNULL" _ , MsgId := "\t\t« %1 » must not contain any NULL or EMPTY elements." _ , Comment := "SF_Utils._ValidateArray error message\n" _ & "%1: Wrong argument name\n" _ & "NULL and EMPTY should not be translated" _ ) ' SF_Utils._ValidateFile .AddText( Context := "VALIDATEFILE" _ , MsgId := "\t\t« %1 » must be of type String." _ , Comment := "SF_Utils._ValidateFile error message\n" _ & "%1: Wrong argument name\n" _ & "'String' should not be translated" _ ) .AddText( Context := "VALIDATEFILESYS" _ , MsgId := "\t\t« %1 » must be a valid file or folder name expressed in the operating system native notation." _ , Comment := "SF_Utils._ValidateFile error message\n" _ & "%1: Wrong argument name" _ ) .AddText( Context := "VALIDATEFILEURL" _ , MsgId := "\t\t« %1 » must be a valid file or folder name expressed in the portable URL notation." _ , Comment := "SF_Utils._ValidateFile error message\n" _ & "%1: Wrong argument name\n" _ & "'URL' should not be translated" _ ) .AddText( Context := "VALIDATEFILEANY" _ , MsgId := "\t\t« %1 » must be a valid file or folder name." _ , Comment := "SF_Utils._ValidateFile error message\n" _ & "%1: Wrong argument name" _ ) .AddText( Context := "VALIDATEWILDCARD" _ , MsgId := "\t\t« %1 » may contain one or more wildcard characters (?, *) in its last path component only." _ , Comment := "SF_Utils._ValidateFile error message\n" _ & "%1: Wrong argument name\n" _ & "'(?, *)' is to be left as is" _ ) ' SF_Array.RangeInit .AddText( Context := "ARRAYSEQUENCE" _ , MsgId := "The respective values of 'From', 'UpTo' and 'ByStep' are incoherent.\n\n" _ & "\t« From » = %1\n" _ & "\t« UpTo » = %2\n" _ & "\t« ByStep » = %3" _ , Comment := "SF_Array.RangeInit error message\n" _ & "%1, %2, %3: Numeric values\n" _ & "'From', 'UpTo', 'ByStep' should not be translated" _ ) ' SF_Array.AppendColumn, AppendRow, PrependColumn, PrependRow .AddText( Context := "ARRAYINSERT" _ , MsgId := "The array and the vector to insert have incompatible sizes.\n\n" _ & "\t« Array_2D » = %2\n" _ & "\t« %1 » = %3" _ , Comment := "SF_Array.AppendColumn (...) error message\n" _ & "%1: 'Column' or 'Row' of a matrix\n" _ & "%2, %3: array contents\n" _ & "'Array_2D' should not be translated" _ ) ' SF_Array.ExtractColumn, ExtractRow .AddText( Context := "ARRAYINDEX1" _ , MsgId := "The given index does not fit within the bounds of the array.\n\n" _ & "\t« Array_2D » = %2\n" _ & "\t« %1 » = %3" _ , Comment := "SF_Array.ExtractColumn (...) error message\n" _ & "%1: 'Column' or 'Row' of a matrix\n" _ & "%2, %3: array contents\n" _ & "'Array_2D' should not be translated" _ ) ' SF_Array.ExtractColumn, ExtractRow .AddText( Context := "ARRAYINDEX2" _ , MsgId := "The given slice limits do not fit within the bounds of the array.\n\n" _ & "\t« Array_2D » = %1\n" _ & "\t« From » = %2\n" _ & "\t« UpTo » = %3" _ , Comment := "SF_Array.ExtractColumn (...) error message\n" _ & "%1: 'Column' or 'Row' of a matrix\n" _ & "%2, %3: array contents\n" _ & "'Array_2D', 'From' and 'UpTo' should not be translated" _ ) ' SF_Array.ImportFromCSVFile .AddText( Context := "CSVPARSING" _ , MsgId := "The given file could not be parsed as a valid CSV file.\n\n" _ & "\t« File name » = %1\n" _ & "\tLine number = %2\n" _ & "\tContent = %3" _ , Comment := "SF_Array.ImportFromCSVFile error message\n" _ & "%1: a file name\n" _ & "%2: numeric\n" _ & "%3: a long string" _ ) ' SF_Dictionary.Add/ReplaceKey .AddText( Context := "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" _ , Comment := "SF_Dictionary Add/ReplaceKey error message\n" _ & "%1: An identifier" _ & "%2: a (potentially long) string" _ ) ' SF_Dictionary.Remove/ReplaceKey/ReplaceItem .AddText( Context := "UNKNOWNKEY" _ , MsgId := "The requested key does not exist in the dictionary.\n\n" _ & "« %1 » = %2" _ , Comment := "SF_Dictionary Remove/ReplaceKey/ReplaceItem error message\n" _ & "%1: An identifier" _ & "%2: a (potentially long) string" _ ) ' SF_Dictionary.Add/ReplaceKey .AddText( Context := "INVALIDKEY" _ , MsgId := "The insertion or the update of an entry " _ & "into a dictionary failed because the given key contains only spaces." _ , Comment := "SF_Dictionary Add/ReplaceKey error message\n" _ ) ' SF_FileSystem.CopyFile/MoveFile/DeleteFile/CreateScriptService("L10N") .AddText( Context := "UNKNOWNFILE" _ , MsgId := "The given file could not be found on your system.\n\n" _ & "« %1 » = %2" _ , Comment := "SF_FileSystem copy/move/delete error message\n" _ & "%1: An identifier\n" _ & "%2: A file name" _ ) ' SF_FileSystem.CopyFolder/MoveFolder/DeleteFolder/Files/SubFolders .AddText( Context := "UNKNOWNFOLDER" _ , MsgId := "The given folder could not be found on your system.\n\n" _ & "« %1 » = %2" _ , Comment := "SF_FileSystem copy/move/delete error message\n" _ & "%1: An identifier\n" _ & "%2: A folder name" _ ) ' SF_FileSystem.CopyFile/MoveFolder/DeleteFile .AddText( Context := "NOTAFILE" _ , MsgId := "« %1 » contains the name of an existing folder, not that of a file.\n\n" _ & "« %1 » = %2" _ , Comment := "SF_FileSystem copy/move/delete error message\n" _ & "%1: An identifier\n" _ & "%2: A file name" _ ) ' SF_FileSystem.CopyFolder/MoveFolder/DeleteFolder/Files/SubFolders .AddText( Context := "NOTAFOLDER" _ , MsgId := "« %1 » contains the name of an existing file, not that of a folder.\n\n" _ & "« %1 » = %2" _ , Comment := "SF_FileSystem copy/move/delete error message\n" _ & "%1: An identifier\n" _ & "%2: A folder name" _ ) ' SF_FileSystem.Copy+Move/File+Folder/CreateTextFile/OpenTextFile .AddText( Context := "OVERWRITE" _ , MsgId := "You tried to create a new file which already exists. Overwriting it has been rejected.\n\n" _ & "« %1 » = %2" _ , Comment := "SF_FileSystem copy/move/... error message\n" _ & "%1: An identifier\n" _ & "%2: A file name" _ ) ' SF_FileSystem.Copy+Move+Delete/File+Folder .AddText( Context := "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" _ , Comment := "SF_FileSystem copy/move/delete error message\n" _ & "%1: An identifier\n" _ & "%2: A file name" _ ) ' SF_FileSystem.Copy+Move+Delete/File+Folder .AddText( Context := "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" _ , Comment := "SF_FileSystem copy/move/delete error message\n" _ & "%1: An identifier\n" _ & "%2: A file or folder name with wildcards" _ ) ' SF_FileSystem.CreateFolder .AddText( Context := "FOLDERCREATION" _ , MsgId := "« %1 » contains the name of an existing file or an existing folder. The operation is rejected.\n\n" _ & "« %1 » = %2" _ , Comment := "SF_FileSystem CreateFolder error message\n" _ & "%1: An identifier\n" _ & "%2: A file or folder name" _ ) ' SF_Services.CreateScriptService .AddText( Context := "UNKNOWNSERVICE" _ , MsgId := "No service named '%4' has been registered for the library '%3'.\n\n" _ & "« %1 » = %2" _ , Comment := "SF_Services.CreateScriptService error message\n" _ & "%1: An identifier\n" _ & "%2: A string\n" _ & "%3: A Basic library name\n" _ & "%4: A service (1 word) name" _ ) ' SF_Services.CreateScriptService .AddText( Context := "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" _ , Comment := "SF_Services.CreateScriptService error message\n" _ & "%1: An identifier\n" _ & "%2: A string\n" _ & "%3: A Basic library name" _ ) ' SF_Session.ExecuteCalcFunction .AddText( Context := "CALCFUNC" _ , MsgId := "The Calc '%1' function encountered an error. Either the given function does not exist or its arguments are invalid." _ , Comment := "SF_Session.ExecuteCalcFunction error message\n" _ & "'Calc' should not be translated" _ ) ' SF_Session._GetScript .AddText( Context := "NOSCRIPT" _ , MsgId := "The requested %1 script could not be located in the given libraries and modules.\n" _ & "« %2 » = %3\n" _ & "« %4 » = %5" _ , Comment := "SF_Session._GetScript error message\n" _ & "%1: 'Basic' or 'Python'\n" _ & "%2: An identifier\n" _ & "%3: A string\n" _ & "%2: An identifier\n" _ & "%3: A string" _ ) ' SF_Session.ExecuteBasicScript .AddText( Context := "SCRIPTEXEC" _ , MsgId := "An exception occurred during the execution of the Basic script.\n" _ & "Cause: %3\n" _ & "« %1 » = %2" _ , Comment := "SF_Session.ExecuteBasicScript error message\n" _ & "%1: An identifier\n" _ & "%2: A string\n" _ & "%3: A (long) string" _ ) ' SF_Session.SendMail .AddText( Context := "WRONGEMAIL" _ , MsgId := "One of the email addresses has been found invalid.\n" _ & "Invalid mail = « %1 »" _ , Comment := "SF_Session.SendMail error message\n" _ & "%1 = a mail address" _ ) ' SF_Session.SendMail .AddText( Context := "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." _ , Comment := "SF_Session.SendMail error message" _ ) ' SF_TextStream._IsFileOpen .AddText( Context := "FILENOTOPEN" _ , MsgId := "The requested file operation could not be executed because the file was closed previously.\n\n" _ & "File name = '%1'" _ , Comment := "SF_TextStream._IsFileOpen error message\n" _ & "%1: A file name" _ ) ' SF_TextStream._IsFileOpen .AddText( Context := "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" _ , Comment := "SF_TextStream._IsFileOpen error message\n" _ & "%1: A file name\n" _ & "%2: READ, WRITE or APPEND" _ ) ' SF_UI.Document .AddText( Context := "DOCUMENT" _ , MsgId := "The requested document could not be found.\n\n" _ & "%1 = '%2'" _ , Comment := "SF_UI.GetDocument error message\n" _ & "%1: An identifier\n" _ & "%2: A string" _ ) ' SF_UI.Create .AddText( Context := "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'" _ , Comment := "SF_UI.GetDocument error message\n" _ & "%1: An identifier\n" _ & "%2: A string\n" _ & "%3: An identifier\n" _ & "%4: A string" _ ) ' SF_UI.OpenDocument .AddText( Context := "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'" _ , Comment := "SF_UI.OpenDocument error message\n" _ & "%1: An identifier\n" _ & "%2: A string\n" _ & "%3: An identifier\n" _ & "%4: A string\n" _ & "%5: An identifier\n" _ & "%6: A string" _ ) ' SF_UI.OpenBaseDocument .AddText( Context := "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'" _ , Comment := "SF_UI.OpenDocument error message\n" _ & "%1: An identifier\n" _ & "%2: A string\n" _ & "%3: An identifier\n" _ & "%4: A string" _ ) ' SF_Document._IsStillAlive .AddText( Context := "DOCUMENTDEAD" _ , MsgId := "The requested action could not be executed because the document was closed inadvertently.\n\n" _ & "The concerned document is '%1'" _ , Comment := "SF_Document._IsStillAlive error message\n" _ & "%1: A file name" _ ) ' SF_Document.Save .AddText( Context := "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'" _ , Comment := "SF_Document.SaveAs error message\n" _ & "%1: An identifier\n" _ & "%2: A file name\n" _ ) ' SF_Document.SaveAs .AddText( Context := "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'" _ , Comment := "SF_Document.SaveAs error message\n" _ & "%1: An identifier\n" _ & "%2: A file name\n" _ & "%3: An identifier\n" _ & "%4: True or False\n" _ & "%5: An identifier\n" _ & "%6: A string" _ ) ' SF_Document.any update .AddText( Context := "DOCUMENTREADONLY" _ , MsgId := "You tried to edit a document which is not modifiable. The document has not been changed.\n\n" _ & "« %1 » = %2" _ , Comment := "SF_Document any update\n" _ & "%1: An identifier\n" _ & "%2: A file name" _ ) ' SF_Base.GetDatabase .AddText( Context := "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" _ , Comment := "SF_Base GetDatabase\n" _ & "%1: An identifier\n" _ & "%2: A user name\n" _ & "%3: An identifier\n" _ & "%4: A password\n" _ & "%5: A file name" _ ) ' SF_Calc._ParseAddress (sheet) .AddText( Context := "CALCADDRESS1" _ , MsgId := "The given address does not correspond with a valid sheet name.\n\n" _ & "« %1 » = %2\n" _ & "« %3 » = %4" _ , Comment := "SF_Calc _ParseAddress (sheet)\n" _ & "%1: An identifier\n" _ & "%2: A string\n" _ & "%3: An identifier\n" _ & "%4: A file name" _ ) ' SF_Calc._ParseAddress (range) .AddText( Context := "CALCADDRESS2" _ , MsgId := "The given address does not correspond with a valid range of cells.\n\n" _ & "« %1 » = %2\n" _ & "« %3 » = %4" _ , Comment := "SF_Calc _ParseAddress (range)\n" _ & "%1: An identifier\n" _ & "%2: A string\n" _ & "%3: An identifier\n" _ & "%4: A file name" _ ) ' SF_Calc.InsertSheet .AddText( Context := "DUPLICATESHEET" _ , MsgId := "There exists already in the document a sheet with the same name.\n\n" _ & "« %1 » = %2\n" _ & "« %3 » = %4" _ , Comment := "SF_Calc InsertSheet\n" _ & "%1: An identifier\n" _ & "%2: A string\n" _ & "%3: An identifier\n" _ & "%4: A file name" _ ) ' SF_Calc.Offset .AddText( Context := "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" _ , Comment := "SF_Calc Offset\n" _ & "%1: An identifier\n" _ & "%2: A Calc reference\n" _ & "%3: An identifier\n" _ & "%4: A number\n" _ & "%5: An identifier\n" _ & "%6: A number\n" _ & "%7: An identifier\n" _ & "%8: A number\n" _ & "%9: An identifier\n" _ & "%10: A number\n" _ & "%11: An identifier\n" _ & "%12: A file name" _ ) ' SF_Form._IsStillAlive .AddText( Context := "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'." _ , Comment := "SF_Dialog._IsStillAlive error message\n" _ & "%1: An identifier" _ & "%2: A file name" _ ) ' SF_Calc.Forms .AddText( Context := "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." _ , Comment := "SF_Form determination\n" _ & "%1: A number\n" _ & "%2: A sheet name\n" _ & "%3: A file name" _ ) ' SF_Document.Forms .AddText( Context := "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." _ , Comment := "SF_Form determination\n" _ & "%1: A number\n" _ & "%2: A file name" _ ) ' SF_Base.Forms .AddText( Context := "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." _ , Comment := "SF_Form determination\n" _ & "%1: A number\n" _ & "%2: A string\n" _ & "%3: A file name" _ ) ' SF_Form.Subforms .AddText( Context := "SUBFORMNOTFOUND" _ , MsgId := "The requested subform could not be found below the given main form.\n\n" _ & "The main form = '%2'.\n" _ & "The subform = '%1'." _ , Comment := "SF_Form determination\n" _ & "%1: A form name\n" _ & "%2: A form name" _ ) ' SF_FormControl._SetProperty .AddText( Context := "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." _ , Comment := "SF_FormControl property setting\n" _ & "%1: An identifier\n" _ & "%2: An identifier\n" _ & "%3: A string\n" _ & "%4: An identifier" _ ) ' SF_Dialog._NewDialog .AddText( Context := "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" _ , Comment := "SF_Dialog creation\n" _ & "%1: An identifier\n" _ & "%2: A string\n" _ & "%3: An identifier\n" _ & "%4: A file name\n" _ & "%5: An identifier\n" _ & "%6: A string\n" _ & "%7: An identifier\n" _ & "%8: A string" _ ) ' SF_Dialog._IsStillAlive .AddText( Context := "DIALOGDEAD" _ , MsgId := "The requested action could not be executed because the dialog was closed inadvertently.\n\n" _ & "The concerned dialog is '%1'." _ , Comment := "SF_Dialog._IsStillAlive error message\n" _ & "%1: An identifier" _ ) ' SF_DialogControl._SetProperty .AddText( Context := "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." _ , Comment := "SF_DialogControl property setting\n" _ & "%1: An identifier\n" _ & "%2: An identifier\n" _ & "%3: A string\n" _ & "%4: An identifier" _ ) ' SF_DialogControl.WriteLine .AddText( Context := "TEXTFIELD" _ , MsgId := "The control '%1' in dialog '%2' is not a multiline text field.\n" _ & "The requested method could not be executed." _ , Comment := "SF_DialogControl add line in textbox\n" _ & "%1: An identifier\n" _ & "%2: An identifier" _ ) ' SF_Database.RunSql .AddText( Context := "DBREADONLY" _ , MsgId := "The database has been opened in read-only mode.\n" _ & "The '%1' method must not be executed in this context." _ , Comment := "SF_Database when running update SQL statement\n" _ & "%1: The concerned method" _ ) ' SF_Database._ExecuteSql .AddText( Context := "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 »" _ , Comment := "SF_Database can't interpret SQL statement\n" _ & "%1: The statement" _ ) End With End If Finally: Exit Sub Catch: GoTo Finally End Sub ' ScriptForge.SF_Root._LoadLocalizedInterface REM ----------------------------------------------------------------------------- Public Function _Repr() As String ''' Convert the unique SF_Root instance to a readable string, typically for debugging purposes (DebugPrint ...) ''' Args: ''' Return: ''' "[Root] (MainFunction: xxx, Console: yyy lines, ServicesList)" Dim sRoot As String ' Return value Const cstRoot = "[Root] (" sRoot = cstRoot & "MainFunction: " & MainFunction & ", Console: " & UBound(ConsoleLines) + 1 & " lines" _ & ", Libraries:" & SF_Utils._Repr(ServicesList.Keys) _ & ")" _Repr = sRoot End Function ' ScriptForge.SF_Root._Repr REM ----------------------------------------------------------------------------- Public Sub _StackReset() ''' Reset private members after a fatal/abort error to leave ''' a stable persistent storage after an unwanted interrupt MainFunction = "" MainFunctionArgs = "" StackLevel = 0 End Sub ' ScriptForge.SF_Root._StackReset REM ================================================== END OF SCRIPTFORGE.SF_ROOT