diff --git a/wizards/Package_access2base.mk b/wizards/Package_access2base.mk index d47b90b41624..0689b748a086 100644 --- a/wizards/Package_access2base.mk +++ b/wizards/Package_access2base.mk @@ -56,4 +56,8 @@ $(eval $(call gb_Package_add_files,wizards_basicsrvaccess2base,$(LIBO_SHARE_FOLD Utils.xba \ )) +$(eval $(call gb_Package_add_files,wizards_basicsrvaccess2base,$(LIBO_LIB_PYUNO_FOLDER),\ + access2base.py \ +)) + # vim: set noet sw=4 ts=4: diff --git a/wizards/source/access2base/access2base.py b/wizards/source/access2base/access2base.py new file mode 100644 index 000000000000..ce20e70e210a --- /dev/null +++ b/wizards/source/access2base/access2base.py @@ -0,0 +1,1448 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- + +# Copyright 2012-2020 Jean-Pierre LEDURE + +# ===================================================================================================================== +# === The Access2Base library is a part of the LibreOffice project. === +# === Full documentation is available on http://www.access2base.com === +# ===================================================================================================================== + +# Access2Base 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. + +# Access2Base 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/ . + +""" +The access2base.py module implements an interface between Python (user) scripts and the Access2Base Basic library. + +Usage: + from access2base import * +Additionally, if Python and LibreOffice are started in separate processes: + If LibreOffice started from console ... (example for Linux) + ./soffice --accept='socket,host=localhost,port=2019;urp;' + then insert next statement + A2BConnect(hostname = 'localhost', port = 2019) + +Specific documentation about Access2Base and Python: + http://www.access2base.com/access2base.html#%5B%5BAccess2Base%20and_Python%5D%5D +""" + +from __future__ import unicode_literals + +import uno +XSCRIPTCONTEXT = uno + +from platform import system as _opsys +import datetime, os, sys, traceback + +_LIBRARY = '' # Should be 'Access2Base' or 'Access2BaseDev' +_VERSION = '6.4' # Actual version number +_WRAPPERMODULE = 'Python' # Module name in the Access2Base library containing Python interfaces + +# CallByName types +_vbGet, _vbLet, _vbMethod, _vbSet, _vbUNO = 2, 4, 1, 8, 16 + + +class _Singleton(type): + """ + A Singleton design pattern + Credits: « Python in a Nutshell » by Alex Martelli, O'Reilly + """ + instances = {} + def __call__(cls, *args, **kwargs): + if cls not in cls.instances: + cls.instances[cls] = super(_Singleton, cls).__call__(*args, **kwargs) + return cls.instances[cls] + + +class acConstants(object, metaclass = _Singleton): + """ + VBA constants used in the Access2Base API. + Values derived from MSAccess, except when conflicts + """ + # Python special constants (used in the protocol between Python and Basic) + # ----------------------------------------------------------------- + Empty = '+++EMPTY+++' + Null = '+++NULL+++' + FromIsoFormat = '%Y-%m-%d %H:%M:%S' # To be used with datetime.datetime.strptime() + + # AcCloseSave + # ----------------------------------------------------------------- + acSaveNo = 2 + acSavePrompt = 0 + acSaveYes = 1 + + # AcFormView + # ----------------------------------------------------------------- + acDesign = 1 + acNormal = 0 + acPreview = 2 + + # AcFormOpenDataMode + # ----------------------------------------------------------------- + acFormAdd = 0 + acFormEdit = 1 + acFormPropertySettings = -1 + acFormReadOnly = 2 + + # acView + # ----------------------------------------------------------------- + acViewDesign = 1 + acViewNormal = 0 + acViewPreview = 2 + + # acOpenDataMode + # ----------------------------------------------------------------- + acAdd = 0 + acEdit = 1 + acReadOnly = 2 + + # AcObjectType + # ----------------------------------------------------------------- + acDefault = -1 + acDiagram = 8 + acForm = 2 + acQuery = 1 + acReport = 3 + acTable = 0 + # Unexisting in MS/Access + acBasicIDE = 101 + acDatabaseWindow = 102 + acDocument = 111 + acWelcome = 112 + # Subtype if acDocument + docWriter = "Writer" + docCalc = "Calc" + docImpress = "Impress" + docDraw = "Draw" + docMath = "Math" + + # AcWindowMode + # ----------------------------------------------------------------- + acDialog = 3 + acHidden = 1 + acIcon = 2 + acWindowNormal = 0 + + # VarType constants + # ----------------------------------------------------------------- + vbEmpty = 0 + vbNull = 1 + vbInteger = 2 + vbLong = 3 + vbSingle = 4 + vbDouble = 5 + vbCurrency = 6 + vbDate = 7 + vbString = 8 + vbObject = 9 + vbBoolean = 11 + vbVariant = 12 + vbByte = 17 + vbUShort = 18 + vbULong = 19 + vbBigint = 35 + vbDecimal = 37 + vbArray = 8192 + + # MsgBox constants + # ----------------------------------------------------------------- + vbOKOnly = 0 # OK button only (default) + vbOKCancel = 1 # OK and Cancel buttons + vbAbortRetryIgnore = 2 # Abort, Retry, and Ignore buttons + vbYesNoCancel = 3 # Yes, No, and Cancel buttons + vbYesNo = 4 # Yes and No buttons + vbRetryCancel = 5 # Retry and Cancel buttons + vbCritical = 16 # Critical message + vbQuestion = 32 # Warning query + vbExclamation = 48 # Warning message + vbInformation = 64 # Information message + vbDefaultButton1 = 128 # First button is default (default) (VBA: 0) + vbDefaultButton2 = 256 # Second button is default + vbDefaultButton3 = 512 # Third button is default + vbApplicationModal = 0 # Application modal message box (default) + # MsgBox Return Values + # ----------------------------------------------------------------- + vbOK = 1 # OK button pressed + vbCancel = 2 # Cancel button pressed + vbAbort = 3 # Abort button pressed + vbRetry = 4 # Retry button pressed + vbIgnore = 5 # Ignore button pressed + vbYes = 6 # Yes button pressed + vbNo = 7 # No button pressed + + # Dialogs Return Values + # ------------------------------------------------------------------ + dlgOK = 1 # OK button pressed + dlgCancel = 0 # Cancel button pressed + + # Control Types + # ----------------------------------------------------------------- + acCheckBox = 5 + acComboBox = 7 + acCommandButton = 2 + acToggleButton = 122 + acCurrencyField = 18 + acDateField = 15 + acFileControl = 12 + acFixedLine = 24 # FREE ENTRY (USEFUL IN DIALOGS) + acFixedText = 10 + acLabel = 10 + acFormattedField = 1 # FREE ENTRY TAKEN TO NOT CONFUSE WITH acTextField + acGridControl = 11 + acGroupBox = 8 + acOptionGroup = 8 + acHiddenControl = 13 + acImageButton = 4 + acImageControl = 14 + acImage = 14 + acListBox = 6 + acNavigationBar = 22 + acNumericField = 17 + acPatternField = 19 + acProgressBar = 23 # FREE ENTRY (USEFUL IN DIALOGS) + acRadioButton = 3 + acOptionButton = 3 + acScrollBar = 20 + acSpinButton = 21 + acSubform = 112 + acTextField = 9 + acTextBox = 9 + acTimeField = 16 + + # AcRecord + # ----------------------------------------------------------------- + acFirst = 2 + acGoTo = 4 + acLast = 3 + acNewRec = 5 + acNext = 1 + acPrevious = 0 + + # FindRecord + # ----------------------------------------------------------------- + acAnywhere = 0 + acEntire = 1 + acStart = 2 + acDown = 1 + acSearchAll = 2 + acUp = 0 + acAll = 0 + acCurrent = -1 + + # AcDataObjectType + # ----------------------------------------------------------------- + acActiveDataObject = -1 + acDataForm = 2 + acDataQuery = 1 + acDataServerView = 7 + acDataStoredProcedure = 9 + acDataTable = 0 + + # AcQuitOption + # ----------------------------------------------------------------- + acQuitPrompt = 0 + acQuitSaveAll = 1 + acQuitSaveNone = 2 + + # AcCommand + # ----------------------------------------------------------------- + acCmdAboutMicrosoftAccess = 35 + acCmdAboutOpenOffice = 35 + acCmdAboutLibreOffice = 35 + acCmdVisualBasicEditor = 525 + acCmdBringToFront = 52 + acCmdClose = 58 + acCmdToolbarsCustomize = 165 + acCmdChangeToCommandButton = 501 + acCmdChangeToCheckBox = 231 + acCmdChangeToComboBox = 230 + acCmdChangeToTextBox = 227 + acCmdChangeToLabel = 228 + acCmdChangeToImage = 234 + acCmdChangeToListBox = 229 + acCmdChangeToOptionButton = 233 + acCmdCopy = 190 + acCmdCut = 189 + acCmdCreateRelationship = 150 + acCmdDelete = 337 + acCmdDatabaseProperties = 256 + acCmdSQLView = 184 + acCmdRemove = 366 + acCmdDesignView = 183 + acCmdFormView = 281 + acCmdNewObjectForm = 136 + acCmdNewObjectTable = 134 + acCmdNewObjectView = 350 + acCmdOpenDatabase = 25 + acCmdNewObjectQuery = 135 + acCmdShowAllRelationships = 149 + acCmdNewObjectReport = 137 + acCmdSelectAll = 333 + acCmdRemoveTable = 84 + acCmdOpenTable = 221 + acCmdRename = 143 + acCmdDeleteRecord = 223 + acCmdApplyFilterSort = 93 + acCmdSnapToGrid = 62 + acCmdViewGrid = 63 + acCmdInsertHyperlink = 259 + acCmdMaximumRecords = 508 + acCmdObjectBrowser = 200 + acCmdPaste = 191 + acCmdPasteSpecial = 64 + acCmdPrint = 340 + acCmdPrintPreview = 54 + acCmdSaveRecord = 97 + acCmdFind = 30 + acCmdUndo = 292 + acCmdRefresh = 18 + acCmdRemoveFilterSort = 144 + acCmdRunMacro = 31 + acCmdSave = 20 + acCmdSaveAs = 21 + acCmdSelectAllRecords = 109 + acCmdSendToBack = 53 + acCmdSortDescending = 164 + acCmdSortAscending = 163 + acCmdTabOrder = 41 + acCmdDatasheetView = 282 + acCmdZoomSelection = 371 + + # AcSendObjectType + # ----------------------------------------------------------------- + acSendForm = 2 + acSendNoObject = -1 + acSendQuery = 1 + acSendReport = 3 + acSendTable = 0 + + # AcOutputObjectType + # ----------------------------------------------------------------- + acOutputTable = 0 + acOutputQuery = 1 + acOutputForm = 2 + acOutputArray = -1 + + # AcEncoding + # ----------------------------------------------------------------- + acUTF8Encoding = 76 + + # AcFormat + # ----------------------------------------------------------------- + acFormatPDF = "writer_pdf_Export" + acFormatODT = "writer8" + acFormatDOC = "MS Word 97" + acFormatHTML = "HTML" + acFormatODS = "calc8" + acFormatXLS = "MS Excel 97" + acFormatXLSX = "Calc MS Excel 2007 XML" + acFormatTXT = "Text - txt - csv (StarCalc)" + + # AcExportQuality + # ----------------------------------------------------------------- + acExportQualityPrint = 0 + acExportQualityScreen = 1 + + # AcSysCmdAction + # ----------------------------------------------------------------- + acSysCmdAccessDir = 9 + acSysCmdAccessVer = 7 + acSysCmdClearHelpTopic = 11 + acSysCmdClearStatus = 5 + acSysCmdGetObjectState = 10 + acSysCmdGetWorkgroupFile = 13 + acSysCmdIniFile = 8 + acSysCmdInitMeter = 1 + acSysCmdProfile = 12 + acSysCmdRemoveMeter = 3 + acSysCmdRuntime = 6 + acSysCmdSetStatus = 4 + acSysCmdUpdateMeter = 2 + + # Type property + # ----------------------------------------------------------------- + dbBigInt = 16 + dbBinary = 9 + dbBoolean = 1 + dbByte = 2 + dbChar = 18 + dbCurrency = 5 + dbDate = 8 + dbDecimal = 20 + dbDouble = 7 + dbFloat = 21 + dbGUID = 15 + dbInteger = 3 + dbLong = 4 + dbLongBinary = 11 # (OLE Object) + dbMemo = 12 + dbNumeric = 19 + dbSingle = 6 + dbText = 10 + dbTime = 22 + dbTimeStamp = 23 + dbVarBinary = 17 + dbUndefined = -1 + + # Attributes property + # ----------------------------------------------------------------- + dbAutoIncrField = 16 + dbDescending = 1 + dbFixedField = 1 + dbHyperlinkField = 32768 + dbSystemField = 8192 + dbUpdatableField = 32 + dbVariableField = 2 + + # OpenRecordset + # ----------------------------------------------------------------- + dbOpenForwardOnly = 8 + dbSQLPassThrough = 64 + dbReadOnly = 4 + + # Query types + # ----------------------------------------------------------------- + dbQAction = 240 + dbQAppend = 64 + dbQDDL = 4 # 96 + dbQDelete = 32 + dbQMakeTable = 128 # 80 + dbQSelect = 0 + dbQSetOperation = 8 # 128 + dbQSQLPassThrough = 1 # 112 + dbQUpdate = 16 # 48 + + # Edit mode + # ----------------------------------------------------------------- + dbEditNone = 0 + dbEditInProgress = 1 + dbEditAdd = 2 + + # Toolbars + # ----------------------------------------------------------------- + msoBarTypeNormal = 0 # Usual toolbar + msoBarTypeMenuBar = 1 # Menu bar + msoBarTypePopup = 2 # Shortcut menu + msoBarTypeStatusBar = 11 # Status bar + msoBarTypeFloater = 12 # Floating window + + msoControlButton = 1 # Command button + msoControlPopup = 10 # Popup, submenu + + # New Lines + # ----------------------------------------------------------------- + vbCr = chr(13) + vbLf = chr(10) + + def _NewLine(): + if _opsys == 'Windows': return chr(13) + chr(10) + return chr(10) + + vbNewLine = _NewLine() + vbTab = chr(9) + + # Module types + # ----------------------------------------------------------------- + acClassModule = 1 + acStandardModule = 0 + + # (Module) procedure types + # ----------------------------------------------------------------- + vbext_pk_Get = 1 # A Property Get procedure + vbext_pk_Let = 2 # A Property Let procedure + vbext_pk_Proc = 0 # A Sub or Function procedure + vbext_pk_Set = 3 # A Property Set procedure + + +COMPONENTCONTEXT, DESKTOP, SCRIPTPROVIDER, THISDATABASEDOCUMENT = None, None, None, None + +def _ErrorHandler(type, value, tb): + ''' + Is the function to be set as new sys.excepthook to bypass the standard error handler + Derived from https://stackoverflow.com/questions/31949760/how-to-limit-python-traceback-to-specific-files + Handler removes traces pointing to methods located in access2base.py when error is due to a user programming error + sys.excepthook = _ErrorHandler + NOT APPLIED YET + ''' + + def check_file(name): + return 'access2base.py' not in name + + show = (fs for fs in traceback.extract_tb(tb) if check_file(fs.filename)) + fmt = traceback.format_list(show) + traceback.format_exception_only(type, value) + print(''.join(fmt), end = '', file = sys.stderr) + # Reset to standard handler + sys.excepthook = sys.__excepthook__ + + +def A2BConnect(hostname = '', port = 0): + """ + To be called explicitly by user scripts when Python process runs outside the LibreOffice process. + LibreOffice started as (Linux): + ./soffice --accept='socket,host=localhost,port=xxxx;urp;' + Otherwise called implicitly by the current module without arguments + Initializes COMPONENTCONTEXT, SCRIPTPROVIDER and DESKTOP + :param hostname: probably 'localhost' or '' + :param port: port number or 0 + :return: None + """ + global XSCRIPTCONTEXT, COMPONENTCONTEXT, DESKTOP, SCRIPTPROVIDER + # Determine COMPONENTCONTEXT, via socket or inside LibreOffice + if len(hostname) > 0 and port > 0: # Explicit connection request via socket + # Code derived from Bridge.py by Alain H. Romedenne + local_context = XSCRIPTCONTEXT.getComponentContext() + resolver = local_context.ServiceManager.createInstanceWithContext( + 'com.sun.star.bridge.UnoUrlResolver', local_context) + try: + conn = 'socket,host=%s,port=%d' % (hostname, port) + connection_url = 'uno:%s;urp;StarOffice.ComponentContext' % conn + established_context = resolver.resolve(connection_url) + except Exception: # thrown when LibreOffice specified instance isn't started + raise ConnectionError('Connection to LibreOffice failed (host = ' + hostname + ', port = ' + str(port) + ')') + COMPONENTCONTEXT = established_context + DESKTOP = None + elif len(hostname) == 0 and port == 0: # Usual interactive mode + COMPONENTCONTEXT = XSCRIPTCONTEXT.getComponentContext() + DESKTOP = COMPONENTCONTEXT.ServiceManager.createInstanceWithContext( 'com.sun.star.frame.Desktop', COMPONENTCONTEXT) + else: + raise SystemExit('The invocation of A2BConnect() has invalid arguments') + # Determine SCRIPTPROVIDER + servicemanager = COMPONENTCONTEXT.ServiceManager + masterscript = servicemanager.createInstanceWithContext("com.sun.star.script.provider.MasterScriptProviderFactory", COMPONENTCONTEXT) + SCRIPTPROVIDER = masterscript.createScriptProvider("") + Script = _A2B.xScript('TraceLog', 'Trace') # Don't use invokeMethod() to force reset of error stack + Script.invoke(('===>', 'Python wrapper loaded V.' + _VERSION, False), (), ()) + return None + + +class _A2B(object, metaclass = _Singleton): + """ + Collection of helper functions implementing the protocol between Python and Basic + Read comments in PythonWrapper Basic function + """ + + @classmethod + def BasicObject(cls, objectname): + objs = {'COLLECTION': _Collection + , 'COMMANDBAR': _CommandBar + , 'COMMANDBARCONTROL': _CommandBarControl + , 'CONTROL': _Control + , 'DATABASE': _Database + , 'DIALOG': _Dialog + , 'EVENT': _Event + , 'FIELD': _Field + , 'FORM': _Form + , 'MODULE': _Module + , 'OPTIONGROUP': _OptionGroup + , 'PROPERTY': _Property + , 'QUERYDEF': _QueryDef + , 'RECORDSET': _Recordset + , 'SUBFORM': _SubForm + , 'TABLEDEF': _TableDef + , 'TEMPVAR': _TempVar + } + return objs[objectname] + + @classmethod + def xScript(cls, script, module): + """ + At first call checks the existence of the Access2Base library + Initializes _LIBRARY with the found library name + First and next calls execute the given script in the given module of the _LIBRARY library + The script and module are presumed to exist + :param script: name of script + :param module: name of module + :return: the script object. NB: the execution is done with the invoke() method applied on the returned object + """ + global _LIBRARY + Script = None + def sScript(lib): + return 'vnd.sun.star.script:' + lib + '.' + module + '.' + script + '?language=Basic&location=application' + if _LIBRARY == '': + # Check the availability of the Access2Base library + for lib in ('Access2BaseDev', 'Access2Base'): + try: + if Script == None: + Script = SCRIPTPROVIDER.getScript(sScript(lib)) + _LIBRARY = lib + except Exception: + pass + if Script == None: + raise SystemExit('Access2Base basic library not found') + else: + Script = SCRIPTPROVIDER.getScript(sScript(_LIBRARY)) + return Script + + @classmethod + def A2BErrorCode(cls): + """ + Return the Access2Base error stack as a tuple + 0 => error code + 1 => severity level + 2 => short error message + 3 => long error message + """ + Script = cls.xScript('TraceErrorCode', 'Trace') + return Script.invoke((), (), ())[0] + + @classmethod + def invokeMethod(cls, script, module, *args): + """ + Direct call to a named script/module pair with their arguments + If the arguments do not match their definition at the Basic side, a TypeError is raised + :param script: name of script + :param module: name of module + :param args: list of arguments to be passed to the script + :return: the value returned by the script execution + """ + if COMPONENTCONTEXT == None: A2BConnect() # Connection from inside LibreOffice is done at first API invocation + Script = cls.xScript(script, module) + try: + Returned = Script.invoke((args), (), ())[0] + except: + raise TypeError("Access2Base error: method '" + script + "' in module '" + module + "' call error. Check its arguments.") + else: + if Returned == None: + if cls.VerifyNoError(): return None + return Returned + + @classmethod + def invokeWrapper(cls, action, basic, script, *args): + """ + Call the Basic wrapper to invite it to execute the proposed action on a Basic object + If the arguments do not match their definition at the Basic side, a TypeError is raised + After execution, a check is done if the execution has raised an error within Basic + If yes, a TypeError is raised + :param action: Property Get, Property Let, Property Set, invoke Method or return UNO object + :param basic: the reference of the Basic object, i.e. the index in the array caching the addresses of the objects + conventionally Application = -1 and DoCmd = -2 + :param script: the property or method name + :param args: the arguments of the method, if any + :return: the value returned by the execution of the Basic routine + """ + if COMPONENTCONTEXT == None: A2BConnect() # Connection from inside LibreOffice is done at first API invocation + # Intercept special call to Application.Events() + if basic == Application.basicmodule and script == 'Events': + Script = cls.xScript('PythonEventsWrapper', _WRAPPERMODULE) + Returned = Script.invoke((args[0],), (), ()) + else: + Script = cls.xScript('PythonWrapper', _WRAPPERMODULE) + NoArgs = '+++NOARGS+++' # Conventional notation for properties/methods without arguments + if len(args) == 0: + args = (action,) + (basic,) + (script,) + (NoArgs,) + else: + args = (action,) + (basic,) + (script,) + args + try: + Returned = Script.invoke((args), (), ()) + except: + raise TypeError("Access2Base error: method '" + script + "' call error. Check its arguments.") + + if isinstance(Returned[0], tuple): + # Is returned value a reference to a basic object, a scalar or a UNO object ? + if len(Returned[0]) in (3, 4): + if Returned[0][0] == 0: # scalar + return Returned[0][1] + elif Returned[0][0] == 1: # reference to objects cache + basicobject = cls.BasicObject(Returned[0][2]) + if len(Returned[0]) == 3: + return basicobject(Returned[0][1], Returned[0][2]) + else: + return basicobject(Returned[0][1], Returned[0][2], Returned[0][3]) + elif Returned[0][0] == 2: # Null value + return None + else: # Should not happen + return None + else: # UNO object + return Returned[0] + elif Returned[0] == None: + if cls.VerifyNoError(): return None + else: # Should not happen + return Returned[0] + + @classmethod + def VerifyNoError(cls): + # has Access2Base generated an error ? + errorstack = cls.A2BErrorCode() # 0 = code, 1 = severity, 2 = short text, 3 = long text + if errorstack[1] in ('ERROR', 'FATAL', 'ABORT'): + raise TypeError('Access2Base error: ' + errorstack[3]) + return True + + +class Application(object, metaclass = _Singleton): + """ Collection of methods located in the Application (Basic) module """ + W = _A2B.invokeWrapper + basicmodule = -1 + + @classmethod + def AllDialogs(cls, dialog = None): + return cls.W(_vbMethod, cls.basicmodule, 'AllDialogs', dialog) + @classmethod + def AllForms(cls, form = None): + return cls.W(_vbMethod, cls.basicmodule, 'AllForms', form) + @classmethod + def AllModules(cls, module = None): + return cls.W(_vbMethod, cls.basicmodule, 'AllModules', module) + @classmethod + def CloseConnection(cls): + return cls.W(_vbMethod, cls.basicmodule, 'CloseConnection') + @classmethod + def CommandBars(cls, bar = None): + return cls.W(_vbMethod, cls.basicmodule, 'CommandBars', bar) + @classmethod + def CurrentDb(cls): + return cls.W(_vbMethod, cls.basicmodule, 'CurrentDb') + @classmethod + def CurrentUser(cls): + return cls.W(_vbMethod, cls.basicmodule, 'CurrentUser') + @classmethod + def DAvg(cls, expression, domain, criteria = ''): + return cls.W(_vbMethod, cls.basicmodule, 'DAvg', expression, domain, criteria) + @classmethod + def DCount(cls, expression, domain, criteria = ''): + return cls.W(_vbMethod, cls.basicmodule, 'DCount', expression, domain, criteria) + @classmethod + def DLookup(cls, expression, domain, criteria = '', orderclause = ''): + return cls.W(_vbMethod, cls.basicmodule, 'DLookup', expression, domain, criteria, orderclause) + @classmethod + def DMax(cls, expression, domain, criteria = ''): + return cls.W(_vbMethod, cls.basicmodule, 'DMax', expression, domain, criteria) + @classmethod + def DMin(cls, expression, domain, criteria = ''): + return cls.W(_vbMethod, cls.basicmodule, 'DMin', expression, domain, criteria) + @classmethod + def DStDev(cls, expression, domain, criteria = ''): + return cls.W(_vbMethod, cls.basicmodule, 'DStDev', expression, domain, criteria) + @classmethod + def DStDevP(cls, expression, domain, criteria = ''): + return cls.W(_vbMethod, cls.basicmodule, 'DStDevP', expression, domain, criteria) + @classmethod + def DSum(cls, expression, domain, criteria = ''): + return cls.W(_vbMethod, cls.basicmodule, 'DSum', expression, domain, criteria) + @classmethod + def DVar(cls, expression, domain, criteria = ''): + return cls.W(_vbMethod, cls.basicmodule, 'DVar', expression, domain, criteria) + @classmethod + def DVarP(cls, expression, domain, criteria = ''): + return cls.W(_vbMethod, cls.basicmodule, 'DVarP', expression, domain, criteria) + @classmethod + def Events(cls, event): + return cls.W(_vbMethod, cls.basicmodule, 'Events', event) + @classmethod + def Forms(cls, form = None): + return cls.W(_vbMethod, cls.basicmodule, 'Forms', form) + @classmethod + def getObject(cls, shortcut): + return cls.W(_vbMethod, cls.basicmodule, 'getObject', shortcut) + GetObject = getObject + @classmethod + def getValue(cls, shortcut): + return cls.W(_vbMethod, cls.basicmodule, 'getValue', shortcut) + GetValue = getValue + @classmethod + def HtmlEncode(cls, string, length = 0): + return cls.W(_vbMethod, cls.basicmodule, 'HtmlEncode', string, length) + @classmethod + def OpenConnection(cls, thisdatabasedocument = None): + global THISDATABASEDOCUMENT + if COMPONENTCONTEXT == None: A2BConnect() # Connection from inside LibreOffice is done at first API invocation + if DESKTOP != None: + THISDATABASEDOCUMENT = DESKTOP.getCurrentComponent() + return _A2B.invokeMethod('OpenConnection', 'Application', THISDATABASEDOCUMENT) + @classmethod + def OpenDatabase(cls, connectionstring, username = '', password = '', readonly = False): + return cls.W(_vbMethod, cls.basicmodule, 'OpenDatabase', connectionstring, username + , password, readonly) + @classmethod + def ProductCode(cls): + return cls.W(_vbMethod, cls.basicmodule, 'ProductCode') + @classmethod + def setValue(cls, shortcut, value): + return cls.W(_vbMethod, cls.basicmodule, 'setValue', shortcut, value) + SetValue = setValue + @classmethod + def SysCmd(cls, action, text = '', value = -1): + return cls.W(_vbMethod, cls.basicmodule, 'SysCmd', action, text, value) + @classmethod + def TempVars(cls, var = None): + return cls.W(_vbMethod, cls.basicmodule, 'TempVars', var) + @classmethod + def Version(cls): + return cls.W(_vbMethod, cls.basicmodule, 'Version') + + +class DoCmd(object, metaclass = _Singleton): + """ Collection of methods located in the DoCmd (Basic) module """ + W = _A2B.invokeWrapper + basicmodule = -2 + + @classmethod + def ApplyFilter(cls, filter = '', sqlwhere = '', controlname = ''): + return cls.W(_vbMethod, cls.basicmodule, 'ApplyFilter', filter, sqlwhere, controlname) + @classmethod + def Close(cls, objecttype, objectname, save = acConstants.acSavePrompt): + return cls.W(_vbMethod, cls.basicmodule, 'Close', objecttype, objectname, save) + @classmethod + def CopyObject(cls, sourcedatabase, newname, sourceobjecttype, sourceobjectname): # 1st argument must be set + return cls.W(_vbMethod, cls.basicmodule, 'CopyObject', sourcedatabase, newname, sourceobjecttype + , sourceobjectname) + @classmethod + def FindNext(cls): + return cls.W(_vbMethod, cls.basicmodule, 'FindNext') + @classmethod + def FindRecord(cls, findwhat, match = acConstants.acEntire, matchcase = False, search = acConstants.acSearchAll + , searchasformatted = False, onlycurrentfield = acConstants.acCurrent, findfirst = True): + return cls.W(_vbMethod, cls.basicmodule, 'FindRecord', findwhat, match, matchcase, search + , searchasformatted, onlycurrentfield, findfirst) + @classmethod + def GetHiddenAttribute(cls, objecttype, objectname = ''): + return cls.W(_vbMethod, cls.basicmodule, 'GetHiddenAttribute', objecttype, objectname) + @classmethod + def GoToControl(cls, controlname): + return cls.W(_vbMethod, cls.basicmodule, 'GoToControl', controlname) + @classmethod + def GoToRecord(cls, objecttype = acConstants.acActiveDataObject, objectname = '', record = acConstants.acNext + , offset = 1): + return cls.W(_vbMethod, cls.basicmodule, 'GoToRecord', objecttype, objectname, record, offset) + @classmethod + def Maximize(cls): + return cls.W(_vbMethod, cls.basicmodule, 'Maximize') + @classmethod + def Minimize(cls): + return cls.W(_vbMethod, cls.basicmodule, 'Minimize') + @classmethod + def MoveSize(cls, left = -1, top = -1, width = -1, height = -1): + return cls.W(_vbMethod, cls.basicmodule, 'MoveSize', left, top, width, height) + @classmethod + def OpenForm(cls, formname, view = acConstants.acNormal, filter = '', wherecondition = '' + , datamode = acConstants.acFormEdit, windowmode = acConstants.acWindowNormal, openargs = ''): + return cls.W(_vbMethod, cls.basicmodule, 'OpenForm', formname, view, filter, wherecondition + , datamode, windowmode, openargs) + @classmethod + def OpenQuery(cls, queryname, view = acConstants.acNormal, datamode = acConstants.acEdit): + return cls.W(_vbMethod, cls.basicmodule, 'OpenQuery', queryname, view, datamode) + @classmethod + def OpenReport(cls, queryname, view = acConstants.acNormal): + return cls.W(_vbMethod, cls.basicmodule, 'OpenReport', queryname, view) + @classmethod + def OpenSQL(cls, sql, option = -1): + return cls.W(_vbMethod, cls.basicmodule, 'OpenSQL', sql, option) + @classmethod + def OpenTable(cls, tablename, view = acConstants.acNormal, datamode = acConstants.acEdit): + return cls.W(_vbMethod, cls.basicmodule, 'OpenTable', tablename, view, datamode) + @classmethod + def OutputTo(cls, objecttype, objectname = '', outputformat = '', outputfile = '', autostart = False, templatefile = '' + , encoding = acConstants.acUTF8Encoding, quality = acConstants.acExportQualityPrint): + if objecttype == acConstants.acOutputForm: encoding = 0 + return cls.W(_vbMethod, cls.basicmodule, 'OutputTo', objecttype, objectname, outputformat + , outputfile, autostart, templatefile, encoding, quality) + @classmethod + def Quit(cls): + return cls.W(_vbMethod, cls.basicmodule, 'Quit') + @classmethod + def RunApp(cls, commandline): + return cls.W(_vbMethod, cls.basicmodule, 'RunApp', commandline) + @classmethod + def RunCommand(cls, command): + return cls.W(_vbMethod, cls.basicmodule, 'RunCommand', command) + @classmethod + def RunSQL(cls, SQL, option = -1): + return cls.W(_vbMethod, cls.basicmodule, 'RunSQL', SQL, option) + @classmethod + def SelectObject(cls, objecttype, objectname = '', indatabasewindow = False): + return cls.W(_vbMethod, cls.basicmodule, 'SelectObject', objecttype, objectname, indatabasewindow) + @classmethod + def SendObject(cls, objecttype = acConstants.acSendNoObject, objectname = '', outputformat = '', to = '', cc = '' + , bcc = '', subject = '', messagetext = '', editmessage = True, templatefile = ''): + return cls.W(_vbMethod, cls.basicmodule, 'SendObject', objecttype, objectname, outputformat, to, cc + , bcc, subject, messagetext, editmessage, templatefile) + @classmethod + def SetHiddenAttribute(cls, objecttype, objectname = '', hidden = True): + return cls.W(_vbMethod, cls.basicmodule, 'SetHiddenAttribute', objecttype, objectname, hidden) + @classmethod + def SetOrderBy(cls, orderby = '', controlname = ''): + return cls.W(_vbMethod, cls.basicmodule, 'SetOrderBy', orderby, controlname) + @classmethod + def ShowAllRecords(cls): + return cls.W(_vbMethod, cls.basicmodule, 'ShowAllRecords') + + +class Basic(object, metaclass = _Singleton): + """ Collection of helper functions having the same behaviour as their Basic counterparts """ + M = _A2B.invokeMethod + + @classmethod + def ConvertFromUrl(cls, url): + return cls.M('PyConvertFromUrl', _WRAPPERMODULE, url) + + @classmethod + def ConvertToUrl(cls, file): + return cls.M('PyConvertToUrl', _WRAPPERMODULE, file) + + @classmethod + def CreateUnoService(cls, servicename): + return cls.M('PyCreateUnoService', _WRAPPERMODULE, servicename) + + @classmethod + def DateAdd(cls, add, count, datearg): + if isinstance(datearg, datetime.datetime): datearg = datearg.isoformat() + dateadd = cls.M('PyDateAdd', _WRAPPERMODULE, add, count, datearg) + return datetime.datetime.strptime(dateadd, acConstants.FromIsoFormat) + + @classmethod + def DateDiff(cls, add, date1, date2, weekstart = 1, yearstart = 1): + if isinstance(date1, datetime.datetime): date1 = date1.isoformat() + if isinstance(date2, datetime.datetime): date2 = date1.isoformat() + return cls.M('PyDateDiff', _WRAPPERMODULE, add, date1, date2, weekstart, yearstart) + + @classmethod + def DatePart(cls, add, datearg, weekstart = 1, yearstart = 1): + if isinstance(datearg, datetime.datetime): datearg = datearg.isoformat() + return cls.M('PyDatePart', _WRAPPERMODULE, add, datearg, weekstart, yearstart) + + @classmethod + def DateValue(cls, datestring): + datevalue = cls.M('PyDateValue', _WRAPPERMODULE, datestring) + return datetime.datetime.strptime(datevalue, acConstants.FromIsoFormat) + + @classmethod + def Format(cls, value, format = None): + if isinstance(value, (datetime.datetime, datetime.date, datetime.time, )): + value = value.isoformat() + return cls.M('PyFormat', _WRAPPERMODULE, value, format) + + @classmethod + def GetGUIType(cls): + return cls.M('PyGetGUIType', _WRAPPERMODULE) + + @staticmethod + def GetPathSeparator(): + return os.sep + + @classmethod + def GetSystemTicks(cls): + return cls.M('PyGetSystemTicks', _WRAPPERMODULE) + + @classmethod + def MsgBox(cls, text, type = None, dialogtitle = None): + return cls.M('PyMsgBox', _WRAPPERMODULE, text, type, dialogtitle) + + class GlobalScope(object, metaclass = _Singleton): + @classmethod + def BasicLibraries(cls): + return Basic.M('PyGlobalScope', _WRAPPERMODULE, 'Basic') + @classmethod + def DialogLibraries(self): + return Basic.M('PyGlobalScope', _WRAPPERMODULE, 'Dialog') + + @classmethod + def InputBox(cls, text, title = None, default = None, xpos = None, ypos = None): + return cls.M('PyInputBox', _WRAPPERMODULE, text, title, default, xpos, ypos) + + @staticmethod + def Now(): + return datetime.datetime.now() + + @staticmethod + def RGB(red, green, blue): + return int('%02x%02x%02x' % (red, green, blue), 16) + + @classmethod + def Timer(cls): + return cls.M('PyTimer', _WRAPPERMODULE) + + @staticmethod + def Xray(myObject): + xrayscript = 'vnd.sun.star.script:XrayTool._Main.Xray?language=Basic&location=application' + xScript = SCRIPTPROVIDER.getScript(xrayscript) + xScript.invoke((myObject,), (), ()) + return + + +class _BasicObject(object): + """ + Parent class of Basic objects + Each subclass is identified by its classProperties: + dictionary with keys = allowed properties, value = True if editable or False + Each instance is identified by its + - reference in the cache managed by Basic + - type ('DATABASE', 'COLLECTION', ...) + - name (form, control, ... name) - may be blank + Properties are got and set following next strategy: + 1. Property names are controlled strictly ('Value' and not 'value') + 2. Getting a property value for the first time is always done via a Basic call + 3. Next occurrences are fetched from the Python dictionary of the instance if the property is read-only, otherwise via a Basic call + 4. Methods output might force the deletion of a property from the dictionary ('MoveNext' changes 'BOF' and 'EOF' properties) + 5. Setting a property value is done via a Basic call, except if self.internal == True + """ + W = _A2B.invokeWrapper + internal_attributes = ('objectreference', 'objecttype', 'name', 'count', 'index', 'internal') + + def __init__(self, reference = -1, objtype = None, name = ''): + self.objectreference = reference # reference in the cache managed by Basic + self.objecttype = objtype # ('DATABASE', 'COLLECTION', ...) + self.name = name # '' when no name + self.internal = False # True to exceptionally allow assigning a new value to a read-only property + + def __getattr__(self, name): + if name == 'classProperties': + pass + elif name in self.classProperties: + # Get Property from Basic + return self.W(_vbGet, self.objectreference, name) + # Usual attributes getter + return super(_BasicObject, self).__getattribute__(name) + + def __setattr__(self, name, value): + if name == 'classProperties': + pass + elif name in self.classProperties: + if self.internal: # internal = True forces property setting even if property is read-only + pass + elif self.classProperties[name] == True: # True == Editable + self.W(_vbLet, self.objectreference, name, value) + else: + raise AttributeError("'" + self.objecttype + "' object : attribute '" + name + "' is not editable") + elif name[0:2] == '__' or name in self.internal_attributes: + pass + else: + raise AttributeError("'" + self.objecttype + " object has no attribute '" + name + "'") + object.__setattr__(self, name, value) + return + + def __repr__(self): + repr = "Basic object (type='" + self.objecttype + "', index=" + str(self.objectreference) + if len(self.name) > 0: repr += ", name='" + self.name + "'" + return repr + ")" + + def _Reset(self, propertyname, basicreturn = None): + """ force new value or erase properties from dictionary (done to optimize calls to Basic scripts) """ + if propertyname in ('BOF', 'EOF'): + # After a Move method invocation on a Recordset object, BOF or EOF likely to be got soon + if isinstance(basicreturn, int): + self.internal = True + # f.i. basicreturn = 0b10 means: BOF = True, EOF = False + self.BOF = basicreturn in (2, 3, -2, -3) + self.EOF = basicreturn in (1, 3, -1, -3) + self.internal = False + return ( basicreturn >= 0 ) + else: + # Suppress possibly invalid property values: e.g. RecordCount after Delete applied on Recordset object + if property in self.__dict__: + del(self.propertyname) + return basicreturn + + @property + def Name(self): return self.name + @property + def ObjectType(self): return self.objecttype + + def Dispose(self): + return self.W(_vbMethod, self.objectreference, 'Dispose') + def getProperty(self, propertyname, index = None): + return self.W(_vbMethod, self.objectreference, 'getProperty', propertyname, index) + GetProperty = getProperty + def hasProperty(self, propertyname): + return propertyname in tuple(self.classProperties.keys()) + HasProperty = hasProperty + def Properties(self, index = acConstants.Empty): + return self.W(_vbMethod, self.objectreference, 'Properties', index) + def setProperty(self, propertyname, value, index = None): + if self.hasProperty(propertyname): + if self.W(_vbMethod, self.objectreference, 'setProperty', propertyname, value, index): + return self.__setattr__(propertyname, value) + raise AttributeError("type object '" + self.objecttype + "' has no editable attribute '" + propertyname + "'") + SetProperty = setProperty + + +class _Collection(_BasicObject): + """ Collection object built as a Python iterator """ + classProperties = dict(Count = False) + def __init__(self, reference = -1, objtype = None): + super().__init__(reference, objtype) + self.count = self.Count + self.index = 0 + def __iter__(self): + self.index = 0 + return self + def __next__(self): + if self.index >= self.count: + raise StopIteration + next = self.Item(self.index) + self.index = self.index + 1 + return next + def __len__(self): + return self.count + + def Add(self, table, value = None): + if isinstance(table, _BasicObject): # Add method applied to a TABLEDEFS collection + return self.W(_vbMethod, self.objectreference, 'Add', table.objectreference) + else: # Add method applied to a TEMPVARS collection + add = self.W(_vbMethod, self.objectreference, 'Add', table, value) + self.count = self.Count + return add + def Delete(self, name): + return self.W(_vbMethod, self.objectreference, 'Delete', name) + def Item(self, index): + return self.W(_vbMethod, self.objectreference, 'Item', index) + def Remove(self, tempvarname): + remove = self.W(_vbMethod, self.objectreference, 'Remove', tempvarname) + self.count = self.Count + return remove + def RemoveAll(self): + remove = self.W(_vbMethod, self.objectreference, 'RemoveAll') + self.count = self.Count + return remove + + +class _CommandBar(_BasicObject): + classProperties = dict(BuiltIn = False, Parent = False, Visible = True) + + def CommandBarControls(self, index = acConstants.Empty): + return self.W(_vbMethod, self.objectreference, 'CommandBarControls', index) + def Reset(self): + return self.W(_vbMethod, self.objectreference, 'Reset') + + +class _CommandBarControl(_BasicObject): + classProperties = dict(BeginGroup = False, BuiltIn = False, Caption = True, Index = False, OnAction = True + , Parent = False, TooltipText = True, Type = False, Visible = True) + + def Execute(self): + return self.W(_vbMethod, self.objectreference, 'Execute') + + +class _Control(_BasicObject): + classProperties = dict(BackColor = True, BorderColor = True, BorderStyle = True, Cancel = True, Caption = True + , ControlSource = False, ControlTipText = True, ControlType = False, Default = True + , DefaultValue = True, Enabled = True, FontBold = True, FontItalic = True, FontName = True + , FontSize = True, FontUnderline = True, FontWeight = True, ForeColor = True, Form = False + , Format = True, ItemData = False, ListCount = False, ListIndex = True, Locked = True, MultiSelect = True + , OnActionPerformed = True, OnAdjustmentValueChanged = True, OnApproveAction = True + , OnApproveReset = True, OnApproveUpdate = True, OnChanged = True, OnErrorOccurred = True + , OnFocusGained = True, OnFocusLost = True, OnItemStateChanged = True, OnKeyPressed = True + , OnKeyReleased = True, OnMouseDragged = True, OnMouseEntered = True, OnMouseExited = True + , OnMouseMoved = True, OnMousePressed = True, OnMouseReleased = True, OnResetted = True, OnTextChanged = True + , OnUpdated = True, OptionValue = False, Page = False, Parent = False, Picture = True, Required = True + , RowSource = True, RowSourceType = True, Selected = True, SelLength = True, SelStart = True, SelText = True + , SubType = False, TabIndex = True, TabStop = True, Tag = True, Text = False, TextAlign = True + , TripleState = True, Value = True, Visible = True + ) + + @property + def BoundField(self): return self.W(_vbUNO, self.objectreference, 'BoundField') + @property + def ControlModel(self): return self.W(_vbUNO, self.objectreference, 'ControlModel') + @property + def ControlView(self): return self.W(_vbUNO, self.objectreference, 'ControlView') + @property + def LabelControl(self): return self.W(_vbUNO, self.objectreference, 'LabelControl') + + def AddItem(self, value, index = -1): + basicreturn = self.W(_vbMethod, self.objectreference, 'AddItem', value, index) + self._Reset('ItemData') + self._Reset('ListCount') + return basicreturn + def Controls(self, index = acConstants.Empty): + return self.W(_vbMethod, self.objectreference, 'Controls', index) + # Overrides method in parent class: list of properties is strongly control type dependent + def hasProperty(self, propertyname): + return self.W(_vbMethod, self.objectreference, 'hasProperty', propertyname) + HasProperty = hasProperty + def RemoveItem(self, index): + basicreturn = self.W(_vbMethod, self.objectreference, 'RemoveItem', index) + self._Reset('ItemData') + self._Reset('ListCount') + return basicreturn + def Requery(self): + return self.W(_vbMethod, self.objectreference, 'Requery') + def SetSelected(self, value, index): + return self.W(_vbMethod, self.objectreference, 'SetSelected', value, index) + def SetFocus(self): + return self.W(_vbMethod, self.objectreference, 'SetFocus') + + +class _Database(_BasicObject): + classProperties = dict(Connect = False, OnCreate = True + , OnFocus = True, OnLoad = True, OnLoadFinished = True, OnModifyChanged = True, OnNew = True + , OnPrepareUnload = True, OnPrepareViewClosing = True, OnSave = True, OnSaveAs = True + , OnSaveAsDone = True, OnSaveAsFailed = True, OnSaveDone = True, OnSaveFailed = True + , OnSubComponentClosed = True, OnSubComponentOpened = True, OnTitleChanged = True, OnUnfocus = True + , OnUnload = True, OnViewClosed = True, OnViewCreated = True, Version = False + ) + + @property + def Connection(self): return self.W(_vbUNO, self.objectreference, 'Connection') + @property + def Document(self): return self.W(_vbUNO, self.objectreference, 'Document') + @property + def MetaData(self): return self.W(_vbUNO, self.objectreference, 'MetaData') + + def Close(self): + return self.W(_vbMethod, self.objectreference, 'Close') + def CloseAllRecordsets(self): + return self.W(_vbMethod, self.objectreference, 'CloseAllRecordsets') + def CreateQueryDef(self, name, sqltext, option = -1): + return self.W(_vbMethod, self.objectreference, 'CreateQueryDef', name, sqltext, option) + def CreateTableDef(self, name): + return self.W(_vbMethod, self.objectreference, 'CreateTableDef', name) + def DAvg(self, expression, domain, criteria = ''): + return self.W(_vbMethod, self.objectreference, 'DAvg', expression, domain, criteria) + def DCount(self, expression, domain, criteria = ''): + return self.W(_vbMethod, self.objectreference, 'DCount', expression, domain, criteria) + def DLookup(self, expression, domain, criteria = '', orderclause = ''): + return self.W(_vbMethod, self.objectreference, 'DLookup', expression, domain, criteria, orderclause) + def DMax(self, expression, domain, criteria = ''): + return self.W(_vbMethod, self.objectreference, 'DMax', expression, domain, criteria) + def DMin(self, expression, domain, criteria = ''): + return self.W(_vbMethod, self.objectreference, 'DMin', expression, domain, criteria) + def DStDev(self, expression, domain, criteria = ''): + return self.W(_vbMethod, self.objectreference, 'DStDev', expression, domain, criteria) + def DStDevP(self, expression, domain, criteria = ''): + return self.W(_vbMethod, self.objectreference, 'DStDevP', expression, domain, criteria) + def DVar(self, expression, domain, criteria = ''): + return self.W(_vbMethod, self.objectreference, 'DVar', expression, domain, criteria) + def DVarP(self, expression, domain, criteria = ''): + return self.W(_vbMethod, self.objectreference, 'DVarP', expression, domain, criteria) + def OpenRecordset(self, source, type = -1, option = -1, lockedit = -1): + return self.W(_vbMethod, self.objectreference, 'OpenRecordset', source, type, option, lockedit) + def OpenSQL(self, SQL, option = -1): + return self.W(_vbMethod, self.objectreference, 'OpenSQL', SQL, option) + def OutputTo(self, objecttype, objectname = '', outputformat = '', outputfile = '', autostart = False, templatefile = '' + , encoding = acConstants.acUTF8Encoding, quality = acConstants.acExportQualityPrint): + if objecttype == acConstants.acOutputForm: encoding = 0 + return self.W(_vbMethod, self.objectreference, 'OutputTo', objecttype, objectname, outputformat, outputfile + , autostart, templatefile, encoding, quality) + def QueryDefs(self, index = acConstants.Empty): + return self.W(_vbMethod, self.objectreference, 'QueryDefs', index) + def Recordsets(self, index = acConstants.Empty): + return self.W(_vbMethod, self.objectreference, 'Recordsets', index) + def RunSQL(self, SQL, option = -1): + return self.W(_vbMethod, self.objectreference, 'RunSQL', SQL, option) + def TableDefs(self, index = acConstants.Empty): + return self.W(_vbMethod, self.objectreference, 'TableDefs', index) + + +class _Dialog(_BasicObject): + classProperties = dict(Caption = True, Height = True, IsLoaded = False, OnFocusGained = True + , OnFocusLost = True, OnKeyPressed = True, OnKeyReleased = True, OnMouseDragged = True + , OnMouseEntered = True, OnMouseExited = True, OnMouseMoved = True, OnMousePressed = True + , OnMouseReleased = True, Page = True, Parent = False, Visible = True, Width = True + ) + + @property + def UnoDialog(self): return self.W(_vbUNO, self.objectreference, 'UnoDialog') + + def EndExecute(self, returnvalue): + return self.W(_vbMethod, self.objectreference, 'EndExecute', returnvalue) + def Execute(self): + return self.W(_vbMethod, self.objectreference, 'Execute') + def Move(left = -1, top = -1, width = -1, height = -1): + return self.W(_vbMethod, self.objectreference, 'Move', left, top, width, height) + def OptionGroup(self, groupname): + return self.W(_vbMethod, self.objectreference, 'OptionGroup', groupname) + def Start(self): + return self.W(_vbMethod, self.objectreference, 'Start') + def Terminate(self): + return self.W(_vbMethod, self.objectreference, 'Terminate') + +class _Event(_BasicObject): + classProperties = dict(ButtonLeft = False, ButtonMiddle = False, ButtonRight = False, ClickCount = False + , ContextShortcut = False, EventName = False, EventType = False, FocusChangeTemporary = False + , KeyAlt = False, KeyChar = False, KeyCode = False, KeyCtrl = False, KeyFunction = False, KeyShift = False + , Recommendation = False, RowChangeAction = False, Source = False, SubComponentName = False + , SubComponentType = False, XPos = False, YPos = False + ) + + +class _Field(_BasicObject): + classProperties = dict(DataType = False, DataUpdatable = False, DbType = False, DefaultValue = True + , Description = True, FieldSize = False, Size = False, Source = False + , SourceField = False, SourceTable = False, TypeName = False, Value = True + ) + + @property + def Column(self): return self.W(_vbUNO, self.objectreference, 'Column') + + def AppendChunk(self, value): + return self.W(_vbMethod, self.objectreference, 'AppendChunk', value) + def GetChunk(self, offset, numbytes): + return self.W(_vbMethod, self.objectreference, 'GetChunk', offset, numbytes) + def ReadAllBytes(self, file): + return self.W(_vbMethod, self.objectreference, 'ReadAllBytes', file) + def ReadAllText(self, file): + return self.W(_vbMethod, self.objectreference, 'ReadAllText', file) + def WriteAllBytes(self, file): + return self.W(_vbMethod, self.objectreference, 'WriteAllBytes', file) + def WriteAllText(self, file): + return self.W(_vbMethod, self.objectreference, 'WriteAllText', file) + + +class _Form(_BasicObject): + classProperties = dict(AllowAdditions = True, AllowDeletions = True, AllowEdits = True, Bookmark = True + , Caption = True, CurrentRecord = True, Filter = True, FilterOn = True, Height = True + , IsLoaded = False, OnApproveCursorMove = True, OnApproveParameter = True, OnApproveReset = True + , OnApproveRowChange = True, OnApproveSubmit = True, OnConfirmDelete = True, OnCursorMoved = True + , OnErrorOccurred = True, OnLoaded = True, OnReloaded = True, OnReloading = True, OnResetted = True + , OnRowChanged = True, OnUnloaded = True, OnUnloading = True, OpenArgs = False, OrderBy = True + , OrderByOn = True, Parent = False, Recordset = False, RecordSource = True, Visible = True + , Width = True + ) + + @property + def Component(self): return self.W(_vbUNO, self.objectreference, 'Component') + @property + def ContainerWindow(self): return self.W(_vbUNO, self.objectreference, 'ContainerWindow') + @property + def DatabaseForm(self): return self.W(_vbUNO, self.objectreference, 'DatabaseForm') + + def Close(self): + return self.W(_vbMethod, self.objectreference, 'Close') + def Controls(self, index = acConstants.Empty): + return self.W(_vbMethod, self.objectreference, 'Controls', index) + def Move(self, left = -1, top = -1, width = -1, height = -1): + return self.W(_vbMethod, self.objectreference, 'Move', left, top, width, height) + def OptionGroup(self, groupname): + return self.W(_vbMethod, self.objectreference, 'OptionGroup', groupname) + def Refresh(self): + return self.W(_vbMethod, self.objectreference, 'Refresh') + def Requery(self): + return self.W(_vbMethod, self.objectreference, 'Requery') + def SetFocus(self): + return self.W(_vbMethod, self.objectreference, 'SetFocus') + + +class _Module(_BasicObject): + classProperties = dict(CountOfDeclarationLines = False, CountOfLines = False, Lines = False + , ProcBodyLine = False, ProcCountLines = False, ProcOfLine = False, ProcStartLine = False + , Type = False + ) + + def Find(self, target, startline, startcolumn, endline, endcolumn, wholeword = False + , matchcase = False, patternsearch = False): + return self.W(_vbMethod, self.objectreference, 'Find', target, startline, startcolumn, endline + , endcolumn, wholeword, matchcase, patternsearch) + + +class _OptionGroup(_BasicObject): + classProperties = dict(Count = False, Value = True) + + def Controls(self, index = acConstants.Empty): + return self.W(_vbMethod, self.objectreference, 'Controls', index) + + +class _Property(_BasicObject): + classProperties = dict(Value = True) + + +class _QueryDef(_BasicObject): + classProperties = dict(SQL = True, Type = False) + + @property + def Query(self): return self.W(_vbUNO, self.objectreference, 'Query') + + def Execute(self, options = acConstants.Empty): + return self.W(_vbMethod, self.objectreference, 'Execute', options) + def Fields(self, index = acConstants.Empty): + return self.W(_vbMethod, self.objectreference, 'Fields', index) + def OpenRecordset(self, type = -1, option = -1, lockedit = -1): + return self.W(_vbMethod, self.objectreference, 'OpenRecordset', type, option, lockedit) + + +class _Recordset(_BasicObject): + classProperties = dict(AbsolutePosition = True, BOF = False, Bookmark = True, Bookmarkable = False + , EditMode = False, EOF = False, Filter = True, RecordCount = False + ) + + @property + def RowSet(self): return self.W(_vbUNO, self.objectreference, 'RowSet') + + def AddNew(self): + return self.W(_vbMethod, self.objectreference, 'AddNew') + def CancelUpdate(self): + return self.W(_vbMethod, self.objectreference, 'CancelUpdate') + def Clone(self): + return self.W(_vbMethod, self.objectreference, 'Clone') + def Close(self): + return self.W(_vbMethod, self.objectreference, 'Close') + def Delete(self): + return self._Reset('RecordCount',self.W(_vbMethod, self.objectreference, 'Delete')) + def Edit(self): + return self.W(_vbMethod, self.objectreference, 'Edit') + def Fields(self, index = acConstants.Empty): + return self.W(_vbMethod, self.objectreference, 'Fields', index) + def GetRows(self, numrows): + return self.W(_vbMethod, self.objectreference, 'GetRows', numrows) + def Move(self, rows, startbookmark = acConstants.Empty): + return self._Reset('BOF', self.W(_vbMethod, self.objectreference, 'Move', rows, startbookmark)) + def MoveFirst(self): + return self._Reset('BOF', self.W(_vbMethod, self.objectreference, 'MoveFirst')) + def MoveLast(self): + return self._Reset('BOF', self.W(_vbMethod, self.objectreference, 'MoveLast')) + def MoveNext(self): + return self._Reset('BOF', self.W(_vbMethod, self.objectreference, 'MoveNext')) + def MovePrevious(self): + return self._Reset('BOF', self.W(_vbMethod, self.objectreference, 'MovePrevious')) + def OpenRecordset(self, type = -1, option = -1, lockedit = -1): + return self.W(_vbMethod, self.objectreference, 'OpenRecordset', type, option, lockedit) + def Update(self): + return self._Reset('RecordCount',self.W(_vbMethod, self.objectreference, 'Update')) + + +class _SubForm(_Form): + classProperties = dict(AllowAdditions = True, AllowDeletions = True, AllowEdits = True, CurrentRecord = True + , Filter = True, FilterOn = True, LinkChildFields = False, LinkMasterFields = False + , OnApproveCursorMove = True, OnApproveParameter = True, OnApproveReset = True + , OnApproveRowChange = True, OnApproveSubmit = True, OnConfirmDelete = True, OnCursorMoved = True + , OnErrorOccurred = True, OnLoaded = True, OnReloaded = True, OnReloading = True, OnResetted = True + , OnRowChanged = True, OnUnloaded = True, OnUnloading = True, OrderBy = True + , OrderByOn = True, Parent = False, Recordset = False, RecordSource = True, Visible = True + ) + + def SetFocus(self): + raise AttributeError("type object 'SubForm' has no method 'SetFocus'") + + +class _TableDef(_BasicObject): + classProperties = dict() + + @property + def Table(self): return self.W(_vbUNO, self.objectreference, 'Table') + + def CreateField(self, name, type, size = 0, attributes = 0): + return self.W(_vbMethod, self.objectreference, 'CreateField', name, type, size, attributes) + def Fields(self, index = acConstants.Empty): + return self.W(_vbMethod, self.objectreference, 'Fields', index) + def OpenRecordset(self, type = -1, option = -1, lockedit = -1): + return self.W(_vbMethod, self.objectreference, 'OpenRecordset', type, option, lockedit) + + +class _TempVar(_BasicObject): + classProperties = dict(Value = True) + +""" +Set of directly callable error handling methods +""" +def DebugPrint(*args): + dargs = () + for arg in args: + if isinstance(arg, _BasicObject): arg = '[OBJECT]' + dargs = dargs + (arg,) + return _A2B.invokeMethod('DebugPrint', _WRAPPERMODULE, *dargs) +def TraceConsole(): return _A2B.invokeMethod('TraceConsole', 'Trace') +def TraceError(tracelevel, errorcode, errorprocedure, errorline): + return _A2B.invokeMethod('TraceError', 'Trace', tracelevel, errorcode, errorprocedure, errorline) +def TraceLevel(newtracelevel = 'ERROR'): return _A2B.invokeMethod('TraceLevel', 'Trace', newtracelevel) +def TraceLog(tracelevel, text, messagebox = True): + return _A2B.invokeMethod('TraceLog', 'Trace', tracelevel, text, messagebox) +