diff --git a/.gitmodules b/.gitmodules index 95d46bf3d50..561e130e4c4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -21,8 +21,7 @@ ignore = untracked [submodule "include/comtypes"] path = include/comtypes - url = https://github.com/enthought/comtypes.git - ignore = untracked + url = https://github.com/nvaccess/comtypes-bin [submodule "include/scons"] path = include/scons url = https://github.com/SConsProject/scons @@ -38,3 +37,6 @@ [submodule "include/cldr-emoji-annotation"] path = include/cldr-emoji-annotation url = https://github.com/fujiwarat/cldr-emoji-annotation +[submodule "include/py2exe"] + path = include/py2exe + url = https://github.com/nvaccess/py2exe-bin diff --git a/appveyor.yml b/appveyor.yml index 9792491507d..e2d23a3e65d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -4,6 +4,7 @@ version: "{branch}-{build}" branches: only: - threshold + - threshold_py3_staging - master - beta - rc @@ -12,7 +13,7 @@ branches: - /release-.*/ environment: - PY_PYTHON: 2.7-32 + PY_PYTHON: 3.7-32 encFileKey: secure: ekOvuyywHuDdGZmRmoj+b3jfrq39A2xlx4RD5ZUGd/8= mozillaSymsAuthToken: @@ -150,7 +151,7 @@ test_script: $errorCode=0 $outDir = (Resolve-Path .\testOutput\unit\) $unitTestsXml = "$outDir\unitTests.xml" - py -m nose --with-xunit --xunit-file="$unitTestsXml" ./tests/unit + py -m nose -sv --with-xunit --xunit-file="$unitTestsXml" ./tests/unit if($LastExitCode -ne 0) { $errorCode=$LastExitCode } Push-AppveyorArtifact $unitTestsXml $wc = New-Object 'System.Net.WebClient' diff --git a/appveyor/mozillaSyms.py b/appveyor/mozillaSyms.py index 6adcfe68f46..f3d982a0803 100644 --- a/appveyor/mozillaSyms.py +++ b/appveyor/mozillaSyms.py @@ -6,7 +6,6 @@ To update the list of symbols uploaded to Mozilla, see the DLL_NAMES constant below. """ -from __future__ import print_function import argparse import os import subprocess @@ -43,7 +42,8 @@ def __init__(self, returncode, stderr): def check_output(command): proc = subprocess.Popen(command, stdout=subprocess.PIPE, - stderr=subprocess.PIPE) + stderr=subprocess.PIPE, + text=True) stdout, stderr = proc.communicate() if proc.returncode != 0: raise ProcError(proc.returncode, stderr) diff --git a/appx/sconscript b/appx/sconscript index bc165397444..da3e9672040 100644 --- a/appx/sconscript +++ b/appx/sconscript @@ -31,7 +31,7 @@ def getCertPublisher(env): return env['publisher'] certPassword=env.get('certPassword','') cmd=['certutil','-dump','-p',certPassword,File('#'+certFile).abspath.replace('/','\\')] - lines=subprocess.check_output(cmd).splitlines() + lines=subprocess.run(cmd,check=True,capture_output=True,text=True).stdout.splitlines() linePrefix='Subject: ' for line in lines: if line.startswith(linePrefix): diff --git a/cldrDict_sconscript b/cldrDict_sconscript index 8a9f55bb5a6..aba880c0ce0 100644 --- a/cldrDict_sconscript +++ b/cldrDict_sconscript @@ -29,7 +29,7 @@ def createCLDRAnnotationsDict(sources, dest): assert cldrDict, "cldrDict is empty" with codecs.open(dest, "w", "utf_8_sig", errors="replace") as dictFile: dictFile.write(u"symbols:\r\n") - for pattern, description in cldrDict.iteritems(): + for pattern, description in cldrDict.items(): dictFile.write(u"{pattern}\t{description}\tsome\r\n".format( pattern=pattern, description=description @@ -119,7 +119,7 @@ NVDAToCLDRLocales = { annotationsDir = env.Dir("include/cldr-emoji-annotation/annotations") annotationsDerivedDir = env.Dir("include/cldr-emoji-annotation/annotationsDerived") -for destLocale, sourceLocales in NVDAToCLDRLocales.iteritems(): +for destLocale, sourceLocales in NVDAToCLDRLocales.items(): cldrSources = [] # First add all annotations, then the derived ones. for sourceLocale in sourceLocales: diff --git a/include/comtypes b/include/comtypes index 1d3d38b2a61..8c45582fe49 160000 --- a/include/comtypes +++ b/include/comtypes @@ -1 +1 @@ -Subproject commit 1d3d38b2a616674309e7eabe6b5c581042caf32a +Subproject commit 8c45582fe497269594f127f93d1a786d6bc868fb diff --git a/include/py2exe b/include/py2exe new file mode 160000 index 00000000000..c496ae65e4c --- /dev/null +++ b/include/py2exe @@ -0,0 +1 @@ +Subproject commit c496ae65e4cb67fb5a1c17087ec33e4fd69be859 diff --git a/include/wxPython b/include/wxPython index 5d878c302f9..11de9371b6b 160000 --- a/include/wxPython +++ b/include/wxPython @@ -1 +1 @@ -Subproject commit 5d878c302f91caaa8970826e9c16d714efec50bd +Subproject commit 11de9371b6b737673ad5ea2703d214ada69a158a diff --git a/keyCommandsDoc.py b/keyCommandsDoc.py index 07f3cbcec6c..c37e56b9195 100644 --- a/keyCommandsDoc.py +++ b/keyCommandsDoc.py @@ -3,7 +3,7 @@ #A part of NonVisual Desktop Access (NVDA) #This file is covered by the GNU General Public License. #See the file COPYING for more details. -#Copyright (C) 2010-2015 NV Access Limited, Mesar Hameed +#Copyright (C) 2010-2019 NV Access Limited, Mesar Hameed, Takuya Nishimoto """Utilities related to NVDA Key Commands documents. """ @@ -213,7 +213,7 @@ def _heading(self, m): self._headings.append(m) self._kcLastHeadingLevel = min(self._kcLastHeadingLevel, level - 1) - RE_SETTING_SINGLE_KEY = re.compile(ur"^[^|]+?[::]\s*(.+?)\s*$") + RE_SETTING_SINGLE_KEY = re.compile(r"^[^|]+?[::]\s*(.+?)\s*$") def _handleSetting(self): if not self._settingsHeaderRow: raise KeyCommandsError("%d, setting command cannot be used before settingsSection command" % self._lineNum) @@ -237,7 +237,7 @@ def _handleSetting(self): # The next few lines should be table rows for each layout. # Alternatively, if the key is common to all layouts, there will be a single line of text specifying the key after a colon. keys = [] - for layout in xrange(self._settingsNumLayouts): + for layout in range(self._settingsNumLayouts): line = next(self._ug).strip() self._lineNum += 1 m = self.RE_SETTING_SINGLE_KEY.match(line) @@ -254,7 +254,7 @@ def _handleSetting(self): if 1 == len(keys) < self._settingsNumLayouts: # The key has only been specified once, so it is the same in all layouts. key = keys[0] - keys[1:] = (key for layout in xrange(self._settingsNumLayouts - 1)) + keys[1:] = (key for layout in range(self._settingsNumLayouts - 1)) # There should now be a blank line. line = next(self._ug).strip() diff --git a/miscDeps b/miscDeps index 3a0065301ec..e2049468258 160000 --- a/miscDeps +++ b/miscDeps @@ -1 +1 @@ -Subproject commit 3a0065301ec91c52ae5bebf2c4403ce429db078c +Subproject commit e20494682583ddb9ab466e9b5a6a5dcfb7a34bc8 diff --git a/nvdaHelper/archBuild_sconscript b/nvdaHelper/archBuild_sconscript index 111896e13f3..f6dfc30ab24 100644 --- a/nvdaHelper/archBuild_sconscript +++ b/nvdaHelper/archBuild_sconscript @@ -34,7 +34,7 @@ def clsidStringToCLSIDDefine(clsidString): "0x"+d[0:8], "0x"+d[8:12], "0x"+d[12:16], - "{%s}"%(",".join("0x"+d[x:x+2] for x in xrange(16,32,2))) + "{%s}"%(",".join("0x"+d[x:x+2] for x in range(16,32,2))) ) def COMProxyDllBuilder(env,target,source,proxyClsid): diff --git a/nvdaHelper/espeak/sconscript b/nvdaHelper/espeak/sconscript index f01d64ab2ff..2f8e8147bd2 100644 --- a/nvdaHelper/espeak/sconscript +++ b/nvdaHelper/espeak/sconscript @@ -59,7 +59,7 @@ def espeak_compilePhonemeData_buildAction(target,source,env): # Unfortunately, there's no way we can flush it or use a different stream # because our eSpeak statically links the CRT. espeak=AutoFreeCDLL(espeakLib[0].abspath) - espeak.espeak_ng_InitializePath(espeakRepo.abspath) + espeak.espeak_ng_InitializePath(os.fsencode(espeakRepo.abspath)) espeak.espeak_ng_CompileIntonation(None,None) espeak.espeak_ng_CompilePhonemeData(22050,None,None) espeak.espeak_Terminate() @@ -72,14 +72,14 @@ def espeak_compileDict_buildAction(target,source,env): # Unfortunately, there's no way we can flush it or use a different stream # because our eSpeak statically links the CRT. espeak=AutoFreeCDLL(espeakLib[0].abspath) - espeak.espeak_Initialize(0,0,target[0].Dir('..').abspath,0x8000) + espeak.espeak_Initialize(0,0,os.fsencode(target[0].Dir('..').abspath),0x8000) try: - lang=source[0].name.split('_')[0] - v=espeak_VOICE(languages=lang+'\x00') + lang=source[0].name.split('_')[0].encode() + v=espeak_VOICE(languages=lang+b'\x00') if espeak.espeak_SetVoiceByProperties(ctypes.byref(v))!=0: print("espeak_compileDict_action: failed to switch to language %s"%lang) return 1 - dictPath=os.path.split(source[0].abspath)[0]+'/' + dictPath=os.fsencode(os.path.split(source[0].abspath)[0]+'/') if espeak.espeak_ng_CompileDictionary(dictPath,None,0,None)!=0: print("espeak_compileDict_action: failed to compile dictionary for language %s"%lang) return diff --git a/nvdaHelper/liblouis/sconscript b/nvdaHelper/liblouis/sconscript index 21c81437efd..0f5a58c3dda 100644 --- a/nvdaHelper/liblouis/sconscript +++ b/nvdaHelper/liblouis/sconscript @@ -1,7 +1,7 @@ ### #This file is a part of the NVDA project. #URL: https://www.nvaccess.org/ -#Copyright 2011-2017 NV Access Limited, Joseph Lee +#Copyright 2011-2018 NV Access Limited, Joseph Lee, Babbage B.V. #This program is free software: you can redistribute it and/or modify #it under the terms of the GNU General Public License version 2.0, as published by #the Free Software Foundation. @@ -28,7 +28,7 @@ signExec=env['signExec'] if env['certFile'] else None RE_AC_INIT = re.compile(r"^AC_INIT\(\[(?P.*)\], \[(?P.*)\], \[(?P.*)\], \[(?P.*)\], \[(?P.*)\]\)") def getLouisVersion(): # Get the version from configure.ac. - with file(louisRootDir.File("configure.ac").abspath) as f: + with open(louisRootDir.File("configure.ac").abspath) as f: for line in f: m = RE_AC_INIT.match(line) if m: @@ -54,7 +54,7 @@ env.Append(CPPDEFINES=[ # variants that start with an '_'. This removes those deprecation warnings. */ "_CRT_NONSTDC_NO_DEPRECATE", ("PACKAGE_VERSION", r'\"%s\"' % getLouisVersion()), - ("UNICODE_BITS", 16), + "WIDECHARS_ARE_UCS4", # Tell liblouis.h that we're exporting liblouis dll functions, not importing them. "_EXPORTING", ]) @@ -64,7 +64,7 @@ env.Prepend(CPPPATH=[".", louisSourceDir]) env['CPPDEFINES'].remove("UNICODE") liblouisH = env.Substfile("liblouis.h", louisSourceDir.File("liblouis.h.in"), - SUBST_DICT={"@WIDECHAR_TYPE@": "unsigned short int"}) + SUBST_DICT={"@WIDECHAR_TYPE@": "unsigned int"}) sourceFiles = [ "compileTranslationTable.c", diff --git a/readme.md b/readme.md index dcd3fcc0a01..50843364c5f 100644 --- a/readme.md +++ b/readme.md @@ -57,31 +57,32 @@ If you didn't pass the `--recursive` option to git clone, you will need to run ` Whenever a required submodule commit changes (e.g. after git pull), you will need to run `git submodule update`. If you aren't sure, run `git submodule update` after every git pull, merge or checkout. -For reference, the following dependencies are included in Git submodules: +For reference, the following run time dependencies are included in Git submodules: * [comtypes](https://github.com/enthought/comtypes), version 1.1.7 * [wxPython](http://www.wxpython.org/), version 4.0.3 -* [Six](https://pypi.python.org/pypi/six), version 1.10.0, required by wxPython -* [Python Windows Extensions](http://sourceforge.net/projects/pywin32/ ), build 218 * [eSpeak NG](https://github.com/espeak-ng/espeak-ng), commit 86e67a * [Sonic](https://github.com/waywardgeek/sonic), commit 4f8c1d11 * [IAccessible2](http://www.linuxfoundation.org/collaborate/workgroups/accessibility/iaccessible2), commit 21bbb176 * [ConfigObj](https://github.com/DiffSK/configobj), commit 5b5de48 +* [Six](https://pypi.python.org/pypi/six), version 1.12.0, required by wxPython and ConfigObj * [liblouis](http://www.liblouis.org/), version 3.10.0 * [Unicode Common Locale Data Repository (CLDR)](http://cldr.unicode.org/) Emoji Annotations, version 35.0 * NVDA images and sounds -* System dlls not present on many systems: mfc90.dll, msvcp90.dll, msvcr90.dll, Microsoft.VC90.CRT.manifest * [Adobe Acrobat accessibility interface, version XI](http://download.macromedia.com/pub/developer/acrobat/AcrobatAccess.zip) * Adobe FlashAccessibility interface typelib -* [txt2tags](http://txt2tags.sourceforge.net/), version 2.5 * [MinHook](https://github.com/RaMMicHaeL/minhook), tagged version 1.2.2 -* [SCons](http://www.scons.org/), version 3.0.4 -* brlapi Python bindings, version 0.5.7 or later, distributed with [BRLTTY for Windows](http://brl.thefreecat.org/brltty/), version 4.2-2 -* ALVA BC6 generic dll, version 3.0.4.1 +* brlapi Python bindings, version 0.7.0 or later, distributed with [BRLTTY for Windows](http://brl.thefreecat.org/brltty/), version 4.2-2 * lilli.dll, version 2.1.0.0 * [pySerial](http://pypi.python.org/pypi/pyserial), version 3.4 * [Python interface to FTDI driver/chip](http://fluidmotion.dyndns.org/zenphoto/index.php?p=news&title=Python-interface-to-FTDI-driver-chip) -* [Py2Exe](http://sourceforge.net/projects/py2exe/), version 0.6.9 + +Additionally, the following build time dependencies are included in Git submodules: + +* [Py2Exe](http://github.com/albertosottile/py2exe/), version 0.9.3.2 commit b372a8e +* [Python Windows Extensions](http://sourceforge.net/projects/pywin32/ ), build 224, required by py2exe +* [txt2tags](http://txt2tags.sourceforge.net/), version 2.5 +* [SCons](http://www.scons.org/), version 3.0.4 * [Nulsoft Install System](http://nsis.sourceforge.net/), version 2.51 * [NSIS UAC plug-in](http://nsis.sourceforge.net/UAC_plug-in), version 0.2.4, ansi * xgettext and msgfmt from [GNU gettext](http://sourceforge.net/projects/cppcms/files/boost_locale/gettext_for_windows/) @@ -91,7 +92,7 @@ For reference, the following dependencies are included in Git submodules: ### Other Dependencies These dependencies are not included in Git submodules, but aren't needed by most people. -* To generate developer documentation for nvdaHelper: [Doxygen version 1.7.3 Windows installer](https://sourceforge.net/projects/doxygen/files/rel-1.7.3/doxygen-1.7.3-setup.exe) +* To generate developer documentation for nvdaHelper: [Doxygen Windows installer](http://www.doxygen.nl/download.html), version 1.8.15: ## Preparing the Source Tree Before you can run the NVDA source code, you must prepare the source tree. @@ -161,13 +162,14 @@ scons launcher The archive will be placed in the output directory. -To generate developer documentation, type: +To generate the NVDA developer guide, type: ``` -scons devDocs +scons developerGuide ``` -The developer docs will be placed in the `devDocs` folder in the output directory. +The developer guide will be placed in the `devDocs` folder in the output directory. +Note that the Python 3 sources of NVDA currently do not support building NVDA developer documentation using the `scons devDocs` command. To generate developer documentation for nvdaHelper (not included in the devDocs target): diff --git a/scons.bat b/scons.bat index 24dcec371c6..5c7001358e6 100644 --- a/scons.bat +++ b/scons.bat @@ -5,8 +5,8 @@ rem Instead, find the python launcher (installed by python 3) where py 1>nul 2>&1 if "%ERRORLEVEL%" == "0" ( rem Python launcher is present in the PATH - rem Call python 2.7 for 32 bits - py -2.7-32 "%~dp0\scons.py" %* + rem Call python 3.7 for 32 bits + py -3.7-32 "%~dp0\scons.py" %* ) else ( rem Python registers itself with the .py extension, so call scons.py. "%~dp0\scons.py" %* diff --git a/scons.py b/scons.py index a6fe33636a1..81d27c3d66f 100644 --- a/scons.py +++ b/scons.py @@ -5,7 +5,7 @@ import os import platform # Variables for storing required version of Python, and the version which is used to run this script. -requiredPythonMajor ="2" +requiredPythonMajor ="3" requiredPythonMinor = "7" requiredPythonArchitecture = "32bit" installedPythonMajor = str(sys.version_info.major) diff --git a/sconstruct b/sconstruct index 82107244f35..f7179eec952 100755 --- a/sconstruct +++ b/sconstruct @@ -1,7 +1,7 @@ ### #This file is a part of the NVDA project. #URL: https://www.nvaccess.org/ -#Copyright 2010-2017 NV Access Limited. +#Copyright 2010-2019 NV Access Limited, Babbage B.V. #This program is free software: you can redistribute it and/or modify #it under the terms of the GNU General Public License version 2.0, as published by #the Free Software Foundation. @@ -15,9 +15,10 @@ import sys import os import time -import _winreg from glob import glob import sourceEnv +from py2exe.dllfinder import pydll +import importlib.util def recursiveCopy(env,targetDir,sourceDir): targets=[] @@ -35,7 +36,7 @@ def recursiveCopy(env,targetDir,sourceDir): # Import NVDA's versionInfo module. import gettext -gettext.install("nvda", unicode=True) +gettext.install("nvda") sys.path.append("source") import versionInfo del sys.path[-1] @@ -72,14 +73,21 @@ vars.Add("certPassword", "The password for the private key in the signing certif vars.Add("certTimestampServer", "The URL of the timestamping server to use to timestamp authenticode signatures", "") vars.Add(PathVariable("outputDir", "The directory where the final built archives and such will be placed", "output",PathVariable.PathIsDirCreate)) vars.Add(ListVariable("nvdaHelperDebugFlags", "a list of debugging features you require", 'none', ["debugCRT","RTC","analyze"])) -vars.Add(EnumVariable('nvdaHelperLogLevel','The level of logging you wish to see, lower is more verbose','15',allowed_values=[str(x) for x in xrange(60)])) +vars.Add(EnumVariable('nvdaHelperLogLevel','The level of logging you wish to see, lower is more verbose','15',allowed_values=[str(x) for x in range(60)])) if "tests" in COMMAND_LINE_TARGETS: vars.Add("unitTests", "A list of unit tests to run", "") if "systemTests" in COMMAND_LINE_TARGETS: vars.Add("filter", "A filter for the name of the system test(s) to run. Wildcards accepted.", "") #Base environment for this and sub sconscripts -env = Environment(variables=vars,HOST_ARCH='x86',tools=["textfile","gettextTool","t2t",keyCommandsDocTool,'doxygen','recursiveInstall']) +env = Environment(variables=vars,HOST_ARCH='x86',tools=[ + "textfile", + "gettextTool", + "t2t" + ,keyCommandsDocTool, + "doxygen", + "recursiveInstall" +]) # speed up subsiquent runs by checking timestamps of targets and dependencies, and only using md5 if timestamps differ. env.Decider('MD5-timestamp') @@ -139,7 +147,7 @@ def signExec(target,source,env): #sys.exit(1) # #3795: signtool can quite commonly fail with timestamping, so allow it to try up to 3 times with a 1 second delay between each try. res=0 - for count in xrange(3): + for count in range(3): res=env.Execute([signExecCmd+[target[0].abspath]]) if not res: return 0 # success @@ -228,31 +236,46 @@ def NVDADistGenerator(target, source, env, for_signature): # We don't do this using normal scons mechanisms because we want it to be cleaned up immediately after this builder # and py2exe will cause bytecode files to be created for it which scons doesn't know about. updateVersionType = env["updateVersionType"] or None - action = [lambda target, source, env: file(buildVersionFn, "w").write( - 'version = {version!r}\r\n' - 'publisher = {publisher!r}\r\n' - 'updateVersionType = {updateVersionType!r}\r\n' - 'version_build = {version_build!r}\r\n' - .format(version=version, publisher=publisher, updateVersionType=updateVersionType,version_build=version_build))] + # Any '\n' characters written are translated to the system default line separator, os.linesep. + action = [lambda target, source, env: open(buildVersionFn, "w", encoding="utf-8").write( + 'version = {version!r}\n' + 'publisher = {publisher!r}\n' + 'updateVersionType = {updateVersionType!r}\n' + 'version_build = {version_build!r}\n' + .format(version=version, publisher=publisher, updateVersionType=updateVersionType,version_build=version_build) + ) + # In Python 3 write returns the number of characters written, + # which scons treats as an error code. + and None] buildCmd = ["cd", source[0].path, "&&", sys.executable] if release: buildCmd.append("-O") - buildCmd.extend(("setup.py", "build", "--build-base", buildDir.abspath, + # Issue errors about str(bytes_instance), str(bytearray_instance) + buildCmd.append("-bb") + buildCmd.extend(("setup.py", "-vv", "build", "--build-base", buildDir.abspath, "py2exe", "--dist-dir", target[0].abspath)) if release: buildCmd.append("-O1") - action.append(buildCmd) - if env.get("uiAccess"): buildCmd.append("--enable-uiAccess") + + action.append(buildCmd) + + # Python3 has started signing its main python dll. + # However, Py2exe currently tries to add a string resource to it, invalidating the signature and possibly currupting the certificate. + # Therefore, copy a fresh version of the dll one more time once py2exe has completed. + action.append(Copy(target[0],pydll)) + if certFile: for prog in "nvda_noUIAccess.exe", "nvda_uiAccess.exe", "nvda_slave.exe", "nvda_eoaProxy.exe": action.append(lambda target,source,env, progByVal=prog: signExec([target[0].File(progByVal)],source,env)) - for ext in "", "c", "o": - action.append(Delete(buildVersionFn + ext)) + action.extend(( + Delete(buildVersionFn), + Delete(importlib.util.cache_from_source(buildVersionFn)) + )) return action env["BUILDERS"]["NVDADist"] = Builder(generator=NVDADistGenerator, target_factory=Dir) @@ -353,7 +376,7 @@ def makePot(target, source, env): # Tweak the headers. potFn = str(target[0]) tmpFn = "%s.tmp" % potFn - with file(potFn, "rt") as inp, file(tmpFn, "wt") as out: + with open(potFn, "rt") as inp, open(tmpFn, "wt") as out: for lineNum, line in enumerate(inp): if lineNum == 1: line = "# %s\n" % versionInfo.copyright @@ -371,19 +394,19 @@ devDocs_nvdaHelper=env.Command(devDocsOutputDir.Dir('nvdaHelper'),devDocs_nvdaHe env.Alias('devDocs_nvdaHelper', devDocs_nvdaHelper) env.Clean('devDocs_nvdaHelper', devDocs_nvdaHelper) -devDocs_nvda = env.Command(devDocsOutputDir.Dir("nvda"), None, [[ - "cd", sourceDir.path, "&&", - sys.executable, "-c", "import sourceEnv; from epydoc.cli import cli; cli()", - "--output", "${TARGET.abspath}", - "--quiet", "--html", "--include-log", "--no-frames", - "--name", "NVDA", "--url", "https://www.nvaccess.org/", - "*.py", "appModules", "brailleDisplayDrivers", r"comInterfaces\__init__.py", - "config", "contentRecog", "extensionPoints", "globalPlugins", "gui", "mathPres", "NVDAObjects", - "speechDictHandler", "synthDrivers", "textInfos", "virtualBuffers", -]]) - -env.Alias('devDocs', [devGuide, devDocs_nvda]) -env.Clean('devDocs', [devGuide, devDocs_nvda]) +#devDocs_nvda = env.Command(devDocsOutputDir.Dir("nvda"), None, [[ +# "cd", sourceDir.path, "&&", +# sys.executable, "-c", "import sourceEnv; from epydoc.cli import cli; cli()", +# "--output", "${TARGET.abspath}", +# "--quiet", "--html", "--include-log", "--no-frames", +# "--name", "NVDA", "--url", "https://www.nvaccess.org/", +# "*.py", "appModules", "brailleDisplayDrivers", r"comInterfaces\__init__.py", +# "config", "contentRecog", "extensionPoints", "globalPlugins", "gui", "mathPres", "NVDAObjects", +# "speechDictHandler", "synthDrivers", "textInfos", "virtualBuffers", +#]]) + +#env.Alias('devDocs', [devGuide, devDocs_nvda]) +#env.Clean('devDocs', [devGuide, devDocs_nvda]) pot = env.Command(outputDir.File("%s.pot" % outFilePrefix), # Don't use sourceDir as the source, as this depends on comInterfaces and nvdaHelper. diff --git a/site_scons/site_tools/doxygen.py b/site_scons/site_tools/doxygen.py index cd2950ee73d..f99021dbfd6 100644 --- a/site_scons/site_tools/doxygen.py +++ b/site_scons/site_tools/doxygen.py @@ -23,10 +23,8 @@ import os.path import glob from fnmatch import fnmatch -try: - import _winreg as winreg # Python 2.7 import -except: - import winreg # python 3 import +from functools import reduce +import winreg def fetchDoxygenPath(): try: @@ -74,7 +72,7 @@ def append_data(data, key, new_data, token): key_token = False else: if token == "+=": - if not data.has_key(key): + if key not in data: data[key] = list() elif token == "=": data[key] = list() @@ -90,7 +88,8 @@ def append_data(data, key, new_data, token): append_data( data, key, new_data, '\\' ) # compress lists of len 1 into single strings - for (k, v) in data.items(): + # Wrap items into a list, since we're mutating the dictionary + for (k, v) in list(data.items()): if len(v) == 0: data.pop(k) @@ -121,7 +120,8 @@ def DoxySourceScan(node, env, path): sources = [] - data = DoxyfileParse(node.get_contents()) + with open(node.abspath) as contents: + data = DoxyfileParse(contents) if data.get("RECURSIVE", "NO") == "YES": recursive = True @@ -149,7 +149,7 @@ def DoxySourceScan(node, env, path): for pattern in file_patterns: sources.extend(glob.glob("/".join([node, pattern]))) - sources = map( lambda path: env.File(path), sources ) + sources = [env.File(path) for path in sources] return sources @@ -168,13 +168,14 @@ def DoxyEmitter(source, target, env): "XML": ("NO", "xml"), } - data = DoxyfileParse(source[0].get_contents()) + with open(source[0].abspath) as contents: + data = DoxyfileParse(contents) targets = [] out_dir = source[0].Dir(data.get("OUTPUT_DIRECTORY", ".")) # add our output locations - for (k, v) in output_formats.items(): + for (k, v) in list(output_formats.items()): if data.get("GENERATE_" + k, v[0]) == "YES": targets.append(out_dir.Dir(v[1])) diff --git a/source/IAccessibleHandler.py b/source/IAccessibleHandler.py index d56b86f43d1..49a76e9c881 100644 --- a/source/IAccessibleHandler.py +++ b/source/IAccessibleHandler.py @@ -111,7 +111,7 @@ def flushEvents(self): g=self._genericEventCache self._genericEventCache={} threadCounters={} - for k,v in sorted(g.iteritems(),key=lambda item: item[1],reverse=True): + for k,v in sorted(g.items(),key=lambda item: item[1],reverse=True): threadCount=threadCounters.get(k[-1],0) if threadCount>MAX_WINEVENTS_PER_THREAD: continue @@ -119,12 +119,12 @@ def flushEvents(self): threadCounters[k[-1]]=threadCount+1 f=self._focusEventCache self._focusEventCache={} - for k,v in sorted(f.iteritems(),key=lambda item: item[1])[0-self.maxFocusItems:]: + for k,v in sorted(f.items(),key=lambda item: item[1])[0-self.maxFocusItems:]: heapq.heappush(self._eventHeap,(v,)+k) e=self._eventHeap self._eventHeap=[] r=[] - for count in xrange(len(e)): + for count in range(len(e)): event=heapq.heappop(e)[1:-1] r.append(event) return r @@ -836,7 +836,7 @@ def initialize(): accPropServices=comtypes.client.CreateObject(CAccPropServices) except (WindowsError,COMError) as e: log.debugWarning("AccPropServices is not available: %s"%e) - for eventType in winEventIDsToNVDAEventNames.keys(): + for eventType in winEventIDsToNVDAEventNames: hookID=winUser.setWinEventHook(eventType,eventType,0,cWinEventCallback,0,0,0) if hookID: winEventHookIDs.append(hookID) @@ -995,8 +995,7 @@ def getRecursiveTextFromIAccessibleTextObject(obj,startOffset=0,endOffset=-1): except: return text textList=[] - for i in xrange(len(text)): - t=text[i] + for i, t in enumerate(text): if ord(t)==0xFFFC: try: childTextObject=hypertextObject.hyperlink(hypertextObject.hyperlinkIndex(i+startOffset)).QueryInterface(IAccessible) diff --git a/source/JABHandler.py b/source/JABHandler.py index 4a56ab2d86b..893afe36e83 100644 --- a/source/JABHandler.py +++ b/source/JABHandler.py @@ -1,14 +1,11 @@ # -*- coding: UTF-8 -*- #javaAccessBridgeHandler.py #A part of NonVisual Desktop Access (NVDA) -#Copyright (C) 2007-2017 NV Access Limited, Peter Vágner, Renaud Paquay, Babbage B.V. +#Copyright (C) 2007-2018 NV Access Limited, Peter Vágner, Renaud Paquay, Babbage B.V. #This file is covered by the GNU General Public License. #See the file COPYING for more details. -try: - import Queue as queue # Python 2.7 import -except ImportError: - import queue # Python 3 import +import queue from ctypes import * from ctypes.wintypes import * import time @@ -22,6 +19,7 @@ import controlTypes import NVDAObjects.JAB import core +import textUtils #Some utility functions to help with function defines @@ -350,6 +348,11 @@ def __eq__(self,jabContext): else: return False + # As __eq__ was defined on this class, we must provide __hash__ to remain hashable. + # The default hash implementation is fine for our purposes. + def __hash__(self): + return super().__hash__() + def __ne__(self,jabContext): if self.vmID!=jabContext.vmID or not bridgeDll.isSameObject(self.vmID,self.accContext,jabContext.accContext): return True @@ -388,9 +391,10 @@ def getAccessibleTextRange(self,start,end): length=((end+1)-start) if length<=0: return u"" - text=create_unicode_buffer(length+1) - bridgeDll.getAccessibleTextRange(self.vmID,self.accContext,start,end,text,length) - return text.value + # Use a string buffer, as from an unicode buffer, we can't get the raw data. + buf = create_string_buffer((length +1) * 2) + bridgeDll.getAccessibleTextRange(self.vmID, self.accContext, start, end, buf, length) + return textUtils.getTextFromRawBytes(buf.raw, numChars=length, encoding=textUtils.WCHAR_ENCODING) def getAccessibleTextLineBounds(self,index): index=max(index,0) @@ -716,7 +720,7 @@ def initialize(): if ChangeWindowMessageFilter: if not ChangeWindowMessageFilter(winUser.WM_COPYDATA,1): raise WinError() - for msg in xrange(winUser.WM_USER+1,65535): + for msg in range(winUser.WM_USER+1,65535): if not ChangeWindowMessageFilter(msg,1): raise WinError() #Register java events diff --git a/source/NVDAHelper.py b/source/NVDAHelper.py index b74d032908c..822d1020151 100755 --- a/source/NVDAHelper.py +++ b/source/NVDAHelper.py @@ -6,10 +6,7 @@ import os import sys -try: - import _winreg as winreg # Python 2.7 import -except ImportError: - import winreg # Python 3 import +import winreg import msvcrt import versionInfo import winKernel @@ -304,7 +301,7 @@ def handleInputConversionModeUpdate(oldFlags,newFlags,lcid): if msg: textList.append(msg) else: - for x in xrange(32): + for x in range(32): x=2**x msgs=inputConversionModeMessages.get(x) if not msgs: continue @@ -430,7 +427,9 @@ def __init__(self): pipeRead = self._duplicateAsInheritable(pipeReadOrig) winKernel.closeHandle(pipeReadOrig) # stdout/stderr of the loader process should go to nul. - with file("nul", "w") as nul: + # Though we aren't using pythonic functions to write to nul, + # open it in binary mode as opening it in text mode (the default) doesn't make sense. + with open("nul", "wb") as nul: nulHandle = self._duplicateAsInheritable(msvcrt.get_osfhandle(nul.fileno())) # Set the process to start with the appropriate std* handles. si = winKernel.STARTUPINFO(dwFlags=winKernel.STARTF_USESTDHANDLES, hSTDInput=pipeRead, hSTDOutput=nulHandle, hSTDError=nulHandle) diff --git a/source/NVDAObjects/IAccessible/MSHTML.py b/source/NVDAObjects/IAccessible/MSHTML.py index dd71569cde3..a2cb7b443a5 100644 --- a/source/NVDAObjects/IAccessible/MSHTML.py +++ b/source/NVDAObjects/IAccessible/MSHTML.py @@ -156,7 +156,7 @@ def getZoomFactorsFromHTMLDocument(HTMLDocument): except (COMError,NameError,AttributeError,TypeError): log.debugWarning("unable to fetch DPI factors") return (1,1) - return (devX/logX,devY/logY) + return (devX // logX, devY // logY) def IAccessibleFromHTMLNode(HTMLNode): try: @@ -483,7 +483,7 @@ def kwargsFromSuper(cls,kwargs,relation=None): # #3494: MSHTML's internal coordinates are always at a hardcoded DPI (usually 96) no matter the system DPI or zoom level. xFactor,yFactor=getZoomFactorsFromHTMLDocument(HTMLNode.document) try: - HTMLNode=HTMLNode.document.elementFromPoint(p.x/xFactor,p.y/yFactor) + HTMLNode=HTMLNode.document.elementFromPoint(p.x // xFactor, p.y // yFactor) except: HTMLNode=None if not HTMLNode: @@ -670,7 +670,7 @@ def _get_name(self): title=self.HTMLAttributes['title'] # #2121: MSHTML sometimes returns a node for the title attribute. # This doesn't make any sense, so ignore it. - if title and isinstance(title,basestring): + if title and isinstance(title,str): return title return "" return super(MSHTML,self).name @@ -1139,7 +1139,7 @@ def findExtraIAccessibleOverlayClasses(obj, clsList): clsList.append(MSAATextLeaf) return - if iaRole == oleacc.ROLE_SYSTEM_WINDOW and obj.event_objectID > 0: + if iaRole == oleacc.ROLE_SYSTEM_WINDOW and obj.event_objectID is not None and obj.event_objectID > 0: clsList.append(PluginWindow) elif iaRole == oleacc.ROLE_SYSTEM_CLIENT and obj.event_objectID == winUser.OBJID_CLIENT: clsList.append(RootClient) diff --git a/source/NVDAObjects/IAccessible/__init__.py b/source/NVDAObjects/IAccessible/__init__.py index 8ec9162b47f..d238d1e40cd 100644 --- a/source/NVDAObjects/IAccessible/__init__.py +++ b/source/NVDAObjects/IAccessible/__init__.py @@ -10,10 +10,12 @@ import os import re import itertools +import importlib from comInterfaces.tom import ITextDocument import tones import languageHandler import textInfos.offsets +import textUtils import colors import time import displayModel @@ -116,6 +118,9 @@ class IA2TextTextInfo(textInfos.offsets.OffsetsTextInfo): detectFormattingAfterCursorMaybeSlow=False + def _get_encoding(self): + return super().encoding + def _getOffsetFromPoint(self,x,y): if self.obj.IAccessibleTextObject.nCharacters>0: offset = self.obj.IAccessibleTextObject.OffsetAtPoint(x,y,IAccessibleHandler.IA2_COORDTYPE_SCREEN_RELATIVE) @@ -198,7 +203,7 @@ def _getSelectionOffsets(self): return [min(start,end),max(start,end)] def _setSelectionOffsets(self,start,end): - for selIndex in xrange(self.obj.IAccessibleTextObject.NSelections): + for selIndex in range(self.obj.IAccessibleTextObject.NSelections): self.obj.IAccessibleTextObject.RemoveSelection(selIndex) if start!=end: self.obj.IAccessibleTextObject.AddSelection(start,end) @@ -253,9 +258,14 @@ def _getCharacterOffsets(self,offset): except COMError: pass try: - return self.obj.IAccessibleTextObject.TextAtOffset(offset,IAccessibleHandler.IA2_TEXT_BOUNDARY_CHAR)[0:2] + start,end,text = self.obj.IAccessibleTextObject.TextAtOffset(offset,IAccessibleHandler.IA2_TEXT_BOUNDARY_CHAR) except COMError: return super(IA2TextTextInfo,self)._getCharacterOffsets(offset) + if textUtils.isHighSurrogate(text) or textUtils.isLowSurrogate(text): + # #8953: Some IA2 implementations, including Gecko and Chromium, + # erroneously report one offset for surrogates. + return super(IA2TextTextInfo,self)._getCharacterOffsets(offset) + return start, end def _getWordOffsets(self,offset): try: @@ -325,7 +335,7 @@ def _iterTextWithEmbeddedObjects(self, withFields, formatConfig=None): items = [self.text] offset = self._startOffset for item in items: - if not isinstance(item, basestring): + if not isinstance(item, str): # This is a field. yield item continue @@ -438,7 +448,8 @@ def findOverlayClasses(self,clsList): if classString and classString.find('.')>0: modString,classString=os.path.splitext(classString) classString=classString[1:] - mod=__import__(modString,globals(),locals(),[]) + # #8712: Python 3 wants a dot (.) when loading a module from the same folder via relative imports, and this is done via package argument. + mod=importlib.import_module("NVDAObjects.IAccessible.%s"%modString, package="NVDAObjects.IAccessible") newCls=getattr(mod,classString) elif classString: newCls=globals()[classString] @@ -449,14 +460,14 @@ def findOverlayClasses(self,clsList): if windowClassName=="Frame Notification Bar" and role==oleacc.ROLE_SYSTEM_CLIENT: clsList.append(IEFrameNotificationBar) elif self.event_objectID==winUser.OBJID_CLIENT and self.event_childID==0 and windowClassName=="_WwG": - from winword import WordDocument + from .winword import WordDocument clsList.append(WordDocument) elif self.event_objectID==winUser.OBJID_CLIENT and self.event_childID==0 and windowClassName in ("_WwN","_WwO"): if self.windowControlID==18: - from winword import SpellCheckErrorField + from .winword import SpellCheckErrorField clsList.append(SpellCheckErrorField) else: - from winword import WordDocument_WwN + from .winword import WordDocument_WwN clsList.append(WordDocument_WwN) elif windowClassName=="DirectUIHWND" and role==oleacc.ROLE_SYSTEM_TOOLBAR: parentWindow=winUser.getAncestor(self.windowHandle,winUser.GA_PARENT) @@ -471,13 +482,13 @@ def findOverlayClasses(self,clsList): from . import mscandui mscandui.findExtraOverlayClasses(self,clsList) elif windowClassName=="GeckoPluginWindow" and self.event_objectID==0 and self.IAccessibleChildID==0: - from mozilla import GeckoPluginWindowRoot + from .mozilla import GeckoPluginWindowRoot clsList.append(GeckoPluginWindowRoot) maybeFlash = False if ((windowClassName in ("MozillaWindowClass", "GeckoPluginWindow") and not isinstance(self.IAccessibleObject, IAccessibleHandler.IAccessible2)) or windowClassName in ("MacromediaFlashPlayerActiveX", "ApolloRuntimeContentWindow", "ShockwaveFlash", "ShockwaveFlashLibrary", "ShockwaveFlashFullScreen", "GeckoFPSandboxChildWindow")): maybeFlash = True - elif windowClassName == "Internet Explorer_Server" and self.event_objectID > 0: + elif windowClassName == "Internet Explorer_Server" and self.event_objectID is not None and self.event_objectID > 0: # #2454: In Windows 8 IE, Flash is exposed in the same HWND as web content. from .MSHTML import MSHTML # This is only possibly Flash if it isn't MSHTML. @@ -611,7 +622,7 @@ def __init__(self,windowHandle=None,IAccessibleObject=None,IAccessibleChildID=No try: left,top,width,height = IAccessibleObject.accLocation(0) windowHandle=winUser.user32.WindowFromPoint(winUser.POINT(left,top)) - except COMError, e: + except COMError as e: log.debugWarning("accLocation failed: %s" % e) if not windowHandle: raise InvalidNVDAObject("Can't get a window handle from IAccessible") @@ -744,14 +755,14 @@ def _get_name(self): res=self.IAccessibleObject.accName(self.IAccessibleChildID) except COMError: res=None - return res if isinstance(res,basestring) and not res.isspace() else None + return res if isinstance(res,str) and not res.isspace() else None def _get_value(self): try: res=self.IAccessibleObject.accValue(self.IAccessibleChildID) except COMError: res=None - return res if isinstance(res,basestring) and not res.isspace() else None + return res if isinstance(res,str) and not res.isspace() else None def _get_actionCount(self): if hasattr(self,'IAccessibleActionObject'): @@ -827,7 +838,7 @@ def _get_role(self): superRole=super(IAccessible,self).role if superRole!=controlTypes.ROLE_WINDOW: return superRole - if isinstance(IARole,basestring): + if isinstance(IARole,str): IARole=IARole.split(',')[0].lower() log.debug("IARole: %s"%IARole) return IAccessibleHandler.IAccessibleRolesToNVDARoles.get(IARole,controlTypes.ROLE_UNKNOWN) @@ -851,12 +862,12 @@ def _get_states(self): except COMError: log.debugWarning("could not get IAccessible states",exc_info=True) else: - states.update(IAccessibleHandler.IAccessibleStatesToNVDAStates[x] for x in (y for y in (1<0: indexInGroup=self.IAccessibleChildID parent=self.parent @@ -1508,7 +1520,7 @@ def _get_devInfo(self): info.append("IAccessible accName: %s" % ret) try: ret = iaObj.accRole(childID) - for name, const in oleacc.__dict__.iteritems(): + for name, const in oleacc.__dict__.items(): if not name.startswith("ROLE_"): continue if ret == const: @@ -1522,7 +1534,7 @@ def _get_devInfo(self): try: temp = iaObj.accState(childID) ret = ", ".join( - name for name, const in oleacc.__dict__.iteritems() + name for name, const in oleacc.__dict__.items() if name.startswith("STATE_") and temp & const ) + " (%d)" % temp except Exception as e: @@ -1551,7 +1563,7 @@ def _get_devInfo(self): info.append("IAccessible2 uniqueID: %s" % ret) try: ret = iaObj.role() - for name, const in itertools.chain(oleacc.__dict__.iteritems(), IAccessibleHandler.__dict__.iteritems()): + for name, const in itertools.chain(oleacc.__dict__.items(), IAccessibleHandler.__dict__.items()): if not name.startswith("ROLE_") and not name.startswith("IA2_ROLE_"): continue if ret == const: @@ -1565,7 +1577,7 @@ def _get_devInfo(self): try: temp = iaObj.states ret = ", ".join( - name for name, const in IAccessibleHandler.__dict__.iteritems() + name for name, const in IAccessibleHandler.__dict__.items() if name.startswith("IA2_STATE_") and temp & const ) + " (%d)" % temp except Exception as e: diff --git a/source/NVDAObjects/IAccessible/adobeAcrobat.py b/source/NVDAObjects/IAccessible/adobeAcrobat.py index 13240e3417c..15acf0eefaa 100644 --- a/source/NVDAObjects/IAccessible/adobeAcrobat.py +++ b/source/NVDAObjects/IAccessible/adobeAcrobat.py @@ -39,7 +39,7 @@ } def normalizeStdName(stdName): - if "H1" <= stdName <= "H6": + if stdName and "H1" <= stdName <= "H6": return controlTypes.ROLE_HEADING, stdName[1] try: @@ -58,9 +58,9 @@ def initOverlayClass(self): log.debugWarning("Could not get IServiceProvider") return - if self.event_objectID > 0: + if self.event_objectID is not None and self.event_objectID > 0: self.accID = self.event_objectID - elif self.event_childID > 0: + elif self.event_childID is not None and self.event_childID > 0: self.accID = self.event_childID else: try: @@ -118,7 +118,7 @@ def _getNodeMathMl(self, node): if val: yield val else: - for childNum in xrange(node.GetChildCount()): + for childNum in range(node.GetChildCount()): try: subNode = node.GetChild(childNum).QueryInterface(IPDDomElement) except COMError: @@ -129,7 +129,7 @@ def _getNodeMathMl(self, node): def _get_mathMl(self): # There could be other stuff before the math element. Ug. - for childNum in xrange(self.pdDomNode.GetChildCount()): + for childNum in range(self.pdDomNode.GetChildCount()): try: child = self.pdDomNode.GetChild(childNum).QueryInterface(IPDDomElement) except COMError: diff --git a/source/NVDAObjects/IAccessible/adobeFlash.py b/source/NVDAObjects/IAccessible/adobeFlash.py index 159b02921b6..64c0bf5ae5c 100644 --- a/source/NVDAObjects/IAccessible/adobeFlash.py +++ b/source/NVDAObjects/IAccessible/adobeFlash.py @@ -21,7 +21,7 @@ def _getStoryText(self): def _getRawSelectionOffsets(self): try: return self.obj.ISimpleTextSelectionObject.GetSelection() - except COMError, e: + except COMError as e: if e.hresult == hresult.E_FAIL: # The documentation says that an empty field should return 0 for both values, but instead, we seem to get E_FAIL. # An empty field still has a valid caret. diff --git a/source/NVDAObjects/IAccessible/ia2TextMozilla.py b/source/NVDAObjects/IAccessible/ia2TextMozilla.py index 03930c51202..c2d214f6461 100644 --- a/source/NVDAObjects/IAccessible/ia2TextMozilla.py +++ b/source/NVDAObjects/IAccessible/ia2TextMozilla.py @@ -8,7 +8,6 @@ This is now used by other applications as well. """ -import itertools from comtypes import COMError import winUser import textInfos @@ -21,12 +20,13 @@ import locationHelper class FakeEmbeddingTextInfo(textInfos.offsets.OffsetsTextInfo): + encoding = None def _getStoryLength(self): return self.obj.childCount def _iterTextWithEmbeddedObjects(self, withFields, formatConfig=None): - return xrange(self._startOffset, self._endOffset) + return range(self._startOffset, self._endOffset) def _getUnitOffsets(self,unit,offset): if unit in (textInfos.UNIT_WORD,textInfos.UNIT_LINE): @@ -232,7 +232,7 @@ def _iterRecursiveText(self, ti, controlStack, formatConfig): for item in ti._iterTextWithEmbeddedObjects(controlStack is not None, formatConfig=formatConfig): if item is None: yield u"" - elif isinstance(item, basestring): + elif isinstance(item, str): yield item elif isinstance(item, int): # Embedded object. embedded = _getEmbedded(ti.obj, item) @@ -628,7 +628,7 @@ def compareEndPoints(self, other, which): otherAncs = self._getAncestors(otherTi, otherObj) # Find the first common ancestor. maxAncIndex = min(len(selfAncs), len(otherAncs)) - 1 - for (selfAncTi, selfAncObj), (otherAncTi, otherAncObj) in itertools.izip(selfAncs[maxAncIndex::-1], otherAncs[maxAncIndex::-1]): + for (selfAncTi, selfAncObj), (otherAncTi, otherAncObj) in zip(selfAncs[maxAncIndex::-1], otherAncs[maxAncIndex::-1]): if selfAncObj == otherAncObj: break else: diff --git a/source/NVDAObjects/IAccessible/mozilla.py b/source/NVDAObjects/IAccessible/mozilla.py index 690a2c75cc9..55f899f75db 100755 --- a/source/NVDAObjects/IAccessible/mozilla.py +++ b/source/NVDAObjects/IAccessible/mozilla.py @@ -88,7 +88,7 @@ class Gecko1_9(Mozilla): def _get_description(self): rawDescription=super(Mozilla,self).description - if isinstance(rawDescription,basestring) and rawDescription.startswith('Description: '): + if isinstance(rawDescription,str) and rawDescription.startswith('Description: '): return rawDescription[13:] else: return "" diff --git a/source/NVDAObjects/IAccessible/qt.py b/source/NVDAObjects/IAccessible/qt.py index 1822fb0c806..78cd4c15658 100644 --- a/source/NVDAObjects/IAccessible/qt.py +++ b/source/NVDAObjects/IAccessible/qt.py @@ -13,7 +13,7 @@ def _getActiveChild(obj): # QT doesn't do accFocus properly, so find the active child ourselves. child = obj.firstChild - for i in xrange(obj.childCount): + for i in range(obj.childCount): states = child.states if controlTypes.STATE_FOCUSED in states or controlTypes.STATE_SELECTED in states: return child diff --git a/source/NVDAObjects/IAccessible/sysListView32.py b/source/NVDAObjects/IAccessible/sysListView32.py index 802e5f3a154..ae535fe3427 100644 --- a/source/NVDAObjects/IAccessible/sysListView32.py +++ b/source/NVDAObjects/IAccessible/sysListView32.py @@ -404,7 +404,7 @@ def _get_name(self): return self.displayText return name textList = [] - for col in xrange(1, self.childCount + 1): + for col in range(1, self.childCount + 1): content = self._getColumnContent(col) if not content: continue diff --git a/source/NVDAObjects/IAccessible/winword.py b/source/NVDAObjects/IAccessible/winword.py index c446c76b7ca..612237ecebb 100644 --- a/source/NVDAObjects/IAccessible/winword.py +++ b/source/NVDAObjects/IAccessible/winword.py @@ -63,7 +63,7 @@ def _get_states(self): def populateHeaderCellTrackerFromHeaderRows(self,headerCellTracker,table): rows=table.rows numHeaderRows=0 - for rowIndex in xrange(rows.count): + for rowIndex in range(rows.count): try: row=rows.item(rowIndex+1) except COMError: @@ -175,7 +175,7 @@ def fetchAssociatedHeaderCellText(self,cell,columnHeader=False): for info in headerCellTracker.iterPossibleHeaderCellInfosFor(rowNumber,columnNumber,columnHeader=columnHeader): textList=[] if columnHeader: - for headerRowNumber in xrange(info.rowNumber,info.rowNumber+info.rowSpan): + for headerRowNumber in range(info.rowNumber,info.rowNumber+info.rowSpan): tempColumnNumber=columnNumber while tempColumnNumber>=1: try: @@ -186,7 +186,7 @@ def fetchAssociatedHeaderCellText(self,cell,columnHeader=False): break textList.append(headerCell.range.text) else: - for headerColumnNumber in xrange(info.columnNumber,info.columnNumber+info.colSpan): + for headerColumnNumber in range(info.columnNumber,info.columnNumber+info.colSpan): tempRowNumber=rowNumber while tempRowNumber>=1: try: @@ -281,9 +281,9 @@ def script_reportCurrentComment(self,gesture): commentReference=field.field.get('comment') if commentReference: offset=int(commentReference) - range=self.WinwordDocumentObject.range(offset,offset+1) + textRange=self.WinwordDocumentObject.range(offset, offset + 1) try: - text=range.comments[1].range.text + text = textRange.comments[1].range.text except COMError: break if text: @@ -410,7 +410,7 @@ def _get_errorText(self): inBold=False textList=[] for field in fields: - if isinstance(field,basestring): + if isinstance(field,str): if inBold: textList.append(field) elif field.field: inBold=field.field.get('bold',False) diff --git a/source/NVDAObjects/JAB/__init__.py b/source/NVDAObjects/JAB/__init__.py index 51130f8dc96..edba41b4cdd 100644 --- a/source/NVDAObjects/JAB/__init__.py +++ b/source/NVDAObjects/JAB/__init__.py @@ -240,7 +240,7 @@ def _get_keyboardShortcut(self): if not bindings or bindings.keyBindingsCount<1: return None shortcutsList=[] - for index in xrange(bindings.keyBindingsCount): + for index in range(bindings.keyBindingsCount): binding=bindings.keyBindingInfo[index] # We don't support these modifiers if binding.modifiers&(JABHandler.ACCESSIBLE_META_KEYSTROKE|JABHandler.ACCESSIBLE_ALT_GRAPH_KEYSTROKE|JABHandler.ACCESSIBLE_BUTTON1_KEYSTROKE|JABHandler.ACCESSIBLE_BUTTON2_KEYSTROKE|JABHandler.ACCESSIBLE_BUTTON3_KEYSTROKE): @@ -284,7 +284,7 @@ def _get_states(self): stateString=self.JABStates stateStrings=stateString.split(',') for state in stateStrings: - if JABStatesToNVDAStates.has_key(state): + if state in JABStatesToNVDAStates: stateSet.add(JABStatesToNVDAStates[state]) if "visible" not in stateStrings: stateSet.add(controlTypes.STATE_INVISIBLE) @@ -431,7 +431,7 @@ def _get_childCount(self): def _get_children(self): children=[] - for index in xrange(self._JABAccContextInfo.childrenCount): + for index in range(self._JABAccContextInfo.childrenCount): jabContext=self.jabContext.getAccessibleChildFromContext(index) if jabContext: obj=JAB(jabContext=jabContext) @@ -599,7 +599,7 @@ def _get_rowHeaderText(self): if headerTableInfo and headerTableInfo.jabTable: textList=[] row=self.rowNumber-1 - for col in xrange(headerTableInfo.columnCount): + for col in range(headerTableInfo.columnCount): cellInfo=headerTableInfo.jabTable.getAccessibleTableCellInfo(row,col) if cellInfo and cellInfo.jabContext: obj=JAB(jabContext=cellInfo.jabContext) @@ -617,7 +617,7 @@ def _get_columnHeaderText(self): if headerTableInfo and headerTableInfo.jabTable: textList=[] col=self.columnNumber-1 - for row in xrange(headerTableInfo.rowCount): + for row in range(headerTableInfo.rowCount): cellInfo=headerTableInfo.jabTable.getAccessibleTableCellInfo(row,col) if cellInfo and cellInfo.jabContext: obj=JAB(jabContext=cellInfo.jabContext) diff --git a/source/NVDAObjects/UIA/__init__.py b/source/NVDAObjects/UIA/__init__.py index 44e3407a589..695b1a811fe 100644 --- a/source/NVDAObjects/UIA/__init__.py +++ b/source/NVDAObjects/UIA/__init__.py @@ -235,8 +235,10 @@ def _getFormatFieldAtRange(self,textRange,formatConfig,ignoreMixedValues=False): formatField['link']=True if formatConfig["reportHeadings"]: styleIDValue=fetcher.getValue(UIAHandler.UIA_StyleIdAttributeId,ignoreMixedValues=ignoreMixedValues) - if UIAHandler.StyleId_Heading1<=styleIDValue<=UIAHandler.StyleId_Heading9: - formatField["heading-level"]=(styleIDValue-UIAHandler.StyleId_Heading1)+1 + # #9842: styleIDValue can sometimes be a pointer to IUnknown. + # In Python 3, comparing an int with a pointer raises a TypeError. + if isinstance(styleIDValue, int) and UIAHandler.StyleId_Heading1 <= styleIDValue <= UIAHandler.StyleId_Heading9: + formatField["heading-level"] = (styleIDValue - UIAHandler.StyleId_Heading1) + 1 if fetchAnnotationTypes: annotationTypes=fetcher.getValue(UIAHandler.UIA_AnnotationTypesAttributeId,ignoreMixedValues=ignoreMixedValues) # Some UIA implementations return a single value rather than a tuple. @@ -321,6 +323,11 @@ def __eq__(self,other): if self.__class__ is not other.__class__: return False return bool(self._rangeObj.compare(other._rangeObj)) + # As __eq__ was defined on this class, we must provide __hash__ to remain hashable. + # The default hash implementation is fine for our purposes. + def __hash__(self): + return super().__hash__() + def _get_NVDAObjectAtStart(self): e=self.UIAElementAtStart if e: @@ -416,12 +423,12 @@ def _getControlFieldForObject(self, obj,isEmbedded=False,startOfNode=False,endOf pass return field - def _getTextFromUIARange(self,range): + def _getTextFromUIARange(self, textRange): """ Fetches plain text from the given UI Automation text range. Just calls getText(-1). This only exists to be overridden for filtering. """ - return range.getText(-1) + return textRange.getText(-1) def _getTextWithFields_text(self,textRange,formatConfig,UIAFormatUnits=None): """ @@ -569,7 +576,7 @@ def _getTextWithFieldsForUIARange(self,rootElement,textRange,formatConfig,includ lastChildEndDelta=0 documentTextPattern=self.obj.UIATextPattern rootElementControlType=rootElement.cachedControlType - for index in xrange(childCount): + for index in range(childCount): childElement=childElements.getElement(index) if not childElement or UIAHandler.handler.clientObject.compareElements(childElement,enclosingElement): log.debug("NULL childElement. Skipping") @@ -645,7 +652,7 @@ def getTextWithFields(self,formatConfig=None): def _get_text(self): return self._getTextFromUIARange(self._rangeObj) - def _getBoundingRectsFromUIARange(self,range): + def _getBoundingRectsFromUIARange(self, textRange): """ Fetches per line bounding rectangles from the given UI Automation text range. Note that if the range object doesn't cover a whole line (e.g. a character), @@ -653,10 +660,10 @@ def _getBoundingRectsFromUIARange(self,range): @rtype: [locationHelper.RectLTWH] """ rects = [] - rectArray = range.GetBoundingRectangles() + rectArray = textRange.GetBoundingRectangles() if not rectArray: return rects - rectIndexes = xrange(0, len(rectArray), 4) + rectIndexes = range(0, len(rectArray), 4) rectGen = (locationHelper.RectLTWH.fromFloatCollection(*rectArray[i:i+4]) for i in rectIndexes) rects.extend(rectGen) return rects @@ -1038,11 +1045,11 @@ def _get_devInfo(self): info.append("UIA className: %s"%ret) patternsAvailable = [] patternAvailableConsts = dict( - (const, name) for name, const in UIAHandler.__dict__.iteritems() + (const, name) for name, const in UIAHandler.__dict__.items() if name.startswith("UIA_Is") and name.endswith("PatternAvailablePropertyId") ) self._prefetchUIACacheForPropertyIDs(list(patternAvailableConsts)) - for const, name in patternAvailableConsts.iteritems(): + for const, name in patternAvailableConsts.items(): try: res = self._getUIACacheablePropertyValue(const) except COMError: @@ -1259,7 +1266,7 @@ def _get_children(self): if not cachedChildren: # GetCachedChildren returns null if there are no children. return children - for index in xrange(cachedChildren.length): + for index in range(cachedChildren.length): e=cachedChildren.getElement(index) windowHandle=self.windowHandle children.append(self.correctAPIForRelation(UIA(windowHandle=windowHandle,UIAElement=e))) @@ -1283,7 +1290,7 @@ def _get_rowHeaderText(self): raise NotImplementedError val=val.QueryInterface(UIAHandler.IUIAutomationElementArray) textList=[] - for i in xrange(val.length): + for i in range(val.length): e=val.getElement(i) if UIAHandler.handler.clientObject.compareElements(e,self.UIAElement): continue @@ -1311,7 +1318,7 @@ def _get_columnHeaderText(self): raise NotImplementedError val=val.QueryInterface(UIAHandler.IUIAutomationElementArray) textList=[] - for i in xrange(val.length): + for i in range(val.length): e=val.getElement(i) if UIAHandler.handler.clientObject.compareElements(e,self.UIAElement): continue @@ -1438,7 +1445,7 @@ def _get_controllerFor(self): return None a=e.QueryInterface(UIAHandler.IUIAutomationElementArray) objList=[] - for index in xrange(a.length): + for index in range(a.length): e=a.getElement(index) e=e.buildUpdatedCache(UIAHandler.handler.baseCacheRequest) obj=UIA(UIAElement=e) @@ -1697,7 +1704,7 @@ class PlaceholderNetUITWMenuItem(UIA): def _get_focusRedirect(self): # Locate the containing menu and focus that instead. parent=self.parent - for count in xrange(4): + for count in range(4): if not parent: return if parent.role==controlTypes.ROLE_POPUPMENU: diff --git a/source/NVDAObjects/UIA/edge.py b/source/NVDAObjects/UIA/edge.py index 84755b7b9d6..0f37ae3dddc 100644 --- a/source/NVDAObjects/UIA/edge.py +++ b/source/NVDAObjects/UIA/edge.py @@ -80,10 +80,10 @@ def _get_UIAElementAtStartWithReplacedContent(self): if ('label=' in ariaProperties) or ('labelledby=' in ariaProperties): return element try: - range=self.obj.UIATextPattern.rangeFromChild(element) + textRange=self.obj.UIATextPattern.rangeFromChild(element) except COMError: return - text=range.getText(-1) + text = textRange.getText(-1) if not text or text.isspace(): return element element=walker.getParentElementBuildCache(element,cacheRequest) @@ -94,15 +94,15 @@ def _moveToEdgeOfReplacedContent(self,back=False): if not element: return try: - range=self.obj.UIATextPattern.rangeFromChild(element) + textRange=self.obj.UIATextPattern.rangeFromChild(element) except COMError: return if not back: - range.MoveEndpointByRange(UIAHandler.TextPatternRangeEndpoint_Start,range,UIAHandler.TextPatternRangeEndpoint_End) - range.move(UIAHandler.TextUnit_Character,-1) + textRange.MoveEndpointByRange(UIAHandler.TextPatternRangeEndpoint_Start, textRange, UIAHandler.TextPatternRangeEndpoint_End) + textRange.move(UIAHandler.TextUnit_Character, -1) else: - range.MoveEndpointByRange(UIAHandler.TextPatternRangeEndpoint_End,range,UIAHandler.TextPatternRangeEndpoint_Start) - self._rangeObj=range + textRange.MoveEndpointByRange(UIAHandler.TextPatternRangeEndpoint_End, textRange, UIAHandler.TextPatternRangeEndpoint_Start) + self._rangeObj=textRange def _collapsedMove(self,unit,direction,skipReplacedContent): """A simple collapsed move (i.e. both ends move together), but whether it classes replaced content as one character stop can be configured via the skipReplacedContent argument.""" @@ -202,7 +202,7 @@ def getTextWithFields(self,formatConfig=None): index=0 while index1 and isinstance(field,basestring) and field.isspace(): + if index>1 and isinstance(field,str) and field.isspace(): prevField=fields[index-2] if isinstance(prevField,textInfos.FieldCommand) and prevField.command=="controlEnd": del fields[index-1:index+1] @@ -212,9 +212,9 @@ def getTextWithFields(self,formatConfig=None): startCount=0 lastStartIndex=None numFields=len(fields) - for index in xrange(numFields-1,-1,-1): + for index in range(numFields-1,-1,-1): field=fields[index] - if isinstance(field,basestring): + if isinstance(field,str): break elif isinstance(field,textInfos.FieldCommand) and field.command=="controlStart" and not field.field.get('embedded'): startCount+=1 @@ -224,7 +224,7 @@ def getTextWithFields(self,formatConfig=None): # Remove any content from fields with a content attribute numFields=len(fields) curField=None - for index in xrange(numFields-1,-1,-1): + for index in range(numFields-1,-1,-1): field=fields[index] if not curField and isinstance(field,textInfos.FieldCommand) and field.command=="controlEnd" and field.field.get('content'): curField=field.field @@ -413,13 +413,13 @@ class EdgeNode(UIA): _TextInfo=EdgeTextInfo_preGapRemoval if _edgeIsPreGapRemoval else EdgeTextInfo def getNormalizedUIATextRangeFromElement(self,UIAElement): - range=super(EdgeNode,self).getNormalizedUIATextRangeFromElement(UIAElement) - if not range or not self._edgeIsPreGapRemoval: - return range + textRange = super().getNormalizedUIATextRangeFromElement(UIAElement) + if not textRange or not self._edgeIsPreGapRemoval: + return textRange #Move the start of a UIA text range past any element start character stops - lastCharInfo=EdgeTextInfo_preGapRemoval(self,None,_rangeObj=range) - lastCharInfo._rangeObj=range - charInfo=lastCharInfo.copy() + lastCharInfo = EdgeTextInfo_preGapRemoval(self,None, _rangeObj=textRange) + lastCharInfo._rangeObj = textRange + charInfo = lastCharInfo.copy() charInfo.collapse() while super(EdgeTextInfo,charInfo).move(textInfos.UNIT_CHARACTER,1)!=0: charInfo.setEndPoint(lastCharInfo,"startToStart") @@ -427,7 +427,7 @@ def getNormalizedUIATextRangeFromElement(self,UIAElement): break lastCharInfo.setEndPoint(charInfo,"startToEnd") charInfo.collapse(True) - return range + return textRange def _get_role(self): role=super(EdgeNode,self).role @@ -555,7 +555,8 @@ def EdgeHeadingQuicknavIterator(itemType,document,position,direction="next"): # However, sometimes when ARIA is used, the level on the element may not match the level in the text attributes. # Therefore we need to search for all levels 1 through 6, even if a specific level is specified. # Though this is still much faster than searching text attributes alone - levels=range(1,7) + # #9078: this must be wrapped inside a list, as Python 3 will treat this as iteration. + levels=list(range(1,7)) condition=createUIAMultiPropertyCondition({UIAHandler.UIA_ControlTypePropertyId:UIAHandler.UIA_TextControlTypeId,UIAHandler.UIA_LevelPropertyId:levels}) levelString=itemType[7:] for item in UIAControlQuicknavIterator(itemType,document,position,condition,direction=direction,itemClass=EdgeHeadingQuickNavItem): diff --git a/source/NVDAObjects/UIA/winConsoleUIA.py b/source/NVDAObjects/UIA/winConsoleUIA.py index cae4c4f8417..41b379717bd 100644 --- a/source/NVDAObjects/UIA/winConsoleUIA.py +++ b/source/NVDAObjects/UIA/winConsoleUIA.py @@ -244,17 +244,14 @@ def _reportNewText(self, line): if len(line.strip()) < max(len(speech.curWordChars) + 1, 3): return if self._hasNewLines: - # Clear the typed word buffer for new text lines. - # This will need to be changed once #8110 is merged. - speech.curWordChars = [] + # Clear the queued characters buffer for new text lines. self._queuedChars = [] super(WinConsoleUIA, self)._reportNewText(line) def event_typedCharacter(self, ch): if ch == '\t': # Clear the typed word buffer for tab completion. - # This will need to be changed once #8110 is merged. - speech.curWordChars = [] + speech.clearTypedWordBuffer() if ( ( config.conf['keyboard']['speakTypedCharacters'] @@ -288,7 +285,7 @@ def script_flush_queuedChars(self, gesture): """ gesture.send() self._queuedChars = [] - speech.curWordChars = [] + speech.clearTypedWordBuffer() def _getTextLines(self): # Filter out extraneous empty lines from UIA diff --git a/source/NVDAObjects/UIA/wordDocument.py b/source/NVDAObjects/UIA/wordDocument.py index 1f9424fc9e1..3347a62f5a2 100644 --- a/source/NVDAObjects/UIA/wordDocument.py +++ b/source/NVDAObjects/UIA/wordDocument.py @@ -64,7 +64,7 @@ def getCommentInfoFromPosition(position): UIAElementArray=val.QueryInterface(UIAHandler.IUIAutomationElementArray) except COMError: return - for index in xrange(UIAElementArray.length): + for index in range(UIAElementArray.length): UIAElement=UIAElementArray.getElement(index) UIAElement=UIAElement.buildUpdatedCache(UIAHandler.handler.baseCacheRequest) obj=UIA(UIAElement=UIAElement) @@ -140,8 +140,8 @@ def _getControlFieldForObject(self,obj,isEmbedded=False,startOfNode=False,endOfN field['value']=field.pop('description',None) or obj.description or field.pop('name',None) or obj.name return field - def _getTextFromUIARange(self,range): - t=super(WordDocumentTextInfo,self)._getTextFromUIARange(range) + def _getTextFromUIARange(self, textRange): + t=super(WordDocumentTextInfo,self)._getTextFromUIARange(textRange) if t: # HTML emails expose a lot of vertical tab chars in their text # Really better as carage returns @@ -189,7 +189,7 @@ def getTextWithFields(self,formatConfig=None): # Sometimes embedded objects and graphics In MS Word can cause a controlStart then a controlEnd with no actual formatChange / text in the middle. # SpeakTextInfo always expects that the first lot of controlStarts will always contain some text. # Therefore ensure that the first lot of controlStarts does contain some text by inserting a blank formatChange and empty string in this case. - for index in xrange(len(fields)): + for index in range(len(fields)): field=fields[index] if isinstance(field,textInfos.FieldCommand) and field.command=="controlStart": continue @@ -203,7 +203,7 @@ def getTextWithFields(self,formatConfig=None): # Therefore, detect when at the start of a list, and strip the bullet from the text string, placing it in the text's formatField as line-prefix. listItemStarted=False lastFormatField=None - for index in xrange(len(fields)): + for index in range(len(fields)): field=fields[index] if isinstance(field,textInfos.FieldCommand) and field.command=="controlStart": if field.field.get('role')==controlTypes.ROLE_LISTITEM and field.field.get('_startOfNode'): @@ -212,7 +212,7 @@ def getTextWithFields(self,formatConfig=None): elif isinstance(field,textInfos.FieldCommand) and field.command=="formatChange": # This is the most recent formatField we have seen. lastFormatField=field.field - elif listItemStarted and isinstance(field,basestring): + elif listItemStarted and isinstance(field,str): # This is the first text string within the list. # Remove the text up to the first space, and store it as line-prefix which NVDA will appropriately speak/braille as a bullet. try: @@ -330,7 +330,7 @@ def script_reportCurrentComment(self,gesture): UIAElementArray=val.QueryInterface(UIAHandler.IUIAutomationElementArray) except COMError: return - for index in xrange(UIAElementArray.length): + for index in range(UIAElementArray.length): UIAElement=UIAElementArray.getElement(index) UIAElement=UIAElement.buildUpdatedCache(UIAHandler.handler.baseCacheRequest) obj=UIA(UIAElement=UIAElement) diff --git a/source/NVDAObjects/__init__.py b/source/NVDAObjects/__init__.py index 74422175da8..5df553520ca 100644 --- a/source/NVDAObjects/__init__.py +++ b/source/NVDAObjects/__init__.py @@ -7,7 +7,6 @@ """Module that contains the base NVDA object type""" -from six import with_metaclass import time import re import weakref @@ -36,6 +35,8 @@ class NVDAObjectTextInfo(textInfos.offsets.OffsetsTextInfo): """ locationText=None + # Do not use encoded text. + encoding = None def _get_unit_mouseChunk(self): return textInfos.UNIT_STORY @@ -46,10 +47,6 @@ def _getStoryText(self): def _getStoryLength(self): return len(self._getStoryText()) - def _getTextRange(self,start,end): - text=self._getStoryText() - return text[start:end] - def _get_boundingRects(self): if self.obj.hasIrrelevantLocation: raise LookupError("Object is off screen, invisible or has no location") @@ -99,7 +96,7 @@ def __call__(self,chooseBestAPI=True,**kwargs): # Determine the bases for the new class. bases=[] - for index in xrange(len(clsList)): + for index in range(len(clsList)): # A class doesn't need to be a base if it is already implicitly included by being a superclass of a previous base. if index==0 or not issubclass(clsList[index-1],clsList[index]): bases.append(clsList[index]) @@ -147,7 +144,7 @@ def clearDynamicClassCache(cls): """ cls._dynamicClassCache.clear() -class NVDAObject(with_metaclass(DynamicNVDAObjectType, documentBase.TextContainerObject,baseObject.ScriptableObject)): +class NVDAObject(documentBase.TextContainerObject, baseObject.ScriptableObject, metaclass=DynamicNVDAObjectType): """NVDA's representation of a single control/widget. Every widget, regardless of how it is exposed by an application or the operating system, is represented by a single NVDAObject instance. This allows NVDA to work with all widgets in a uniform way. @@ -320,6 +317,11 @@ def __eq__(self,other): return False return self._isEqual(other) + # As __eq__ was defined on this class, we must provide __hash__ to remain hashable. + # The default hash implementation is fine for our purposes. + def __hash__(self): + return super().__hash__() + def __ne__(self,other): """The opposite to L{NVDAObject.__eq__} """ @@ -387,7 +389,7 @@ def _get_appModule(self): def _get_name(self): """The name or label of this object (example: the text of a button). - @rtype: basestring + @rtype: str """ return "" @@ -408,13 +410,13 @@ def _get_roleText(self): def _get_value(self): """The value of this object (example: the current percentage of a scrollbar, the selected option in a combo box). - @rtype: basestring + @rtype: str """ return "" def _get_description(self): """The description or help text of this object. - @rtype: basestring + @rtype: str """ return "" @@ -432,7 +434,7 @@ def getActionName(self,index=None): @param index: the optional 0-based index of the wanted action. @type index: int @return: the action's name - @rtype: basestring + @rtype: str """ raise NotImplementedError @@ -448,7 +450,7 @@ def _get_defaultActionIndex(self): def _get_keyboardShortcut(self): """The shortcut key that activates this object(example: alt+t). - @rtype: basestring + @rtype: str """ return "" @@ -1098,7 +1100,7 @@ def _get_basicText(self): newTime=time.time() oldTime=getattr(self,'_basicTextTime',0) if newTime-oldTime>0.5: - self._basicText=u" ".join([x for x in self.name, self.value, self.description if isinstance(x, basestring) and len(x) > 0 and not x.isspace()]) + self._basicText=u" ".join(x for x in (self.name, self.value, self.description) if isinstance(x, str) and len(x) > 0 and not x.isspace()) if len(self._basicText)==0: self._basicText=u"" else: @@ -1120,13 +1122,13 @@ def _formatLongDevInfoString(string, truncateLen=250): If the string is too long to be useful, it will be truncated. This string should be included as returned. There is no need to call repr. @param string: The string to format. - @type string: nbasestring + @type string: str @param truncateLen: The length at which to truncate the string. @type truncateLen: int @return: The formatted string. - @rtype: basestring + @rtype: str """ - if isinstance(string, basestring) and len(string) > truncateLen: + if isinstance(string, str) and len(string) > truncateLen: return "%r (truncated)" % string[:truncateLen] return repr(string) @@ -1144,7 +1146,7 @@ def _get_devInfo(self): info.append("name: %s" % ret) try: ret = self.role - for name, const in controlTypes.__dict__.iteritems(): + for name, const in controlTypes.__dict__.items(): if name.startswith("ROLE_") and ret == const: ret = name break @@ -1152,7 +1154,7 @@ def _get_devInfo(self): ret = "exception: %s" % e info.append("role: %s" % ret) try: - stateConsts = dict((const, name) for name, const in controlTypes.__dict__.iteritems() if name.startswith("STATE_")) + stateConsts = dict((const, name) for name, const in controlTypes.__dict__.items() if name.startswith("STATE_")) ret = ", ".join( stateConsts.get(state) or str(state) for state in self.states) @@ -1238,7 +1240,7 @@ def _get_mathMl(self): raise NotImplementedError #: The language/locale of this object. - #: @type: basestring + #: @type: str language = None def _get__hasNavigableText(self): diff --git a/source/NVDAObjects/behaviors.py b/source/NVDAObjects/behaviors.py index ddfc57eab26..312ef21b289 100755 --- a/source/NVDAObjects/behaviors.py +++ b/source/NVDAObjects/behaviors.py @@ -51,8 +51,8 @@ def event_valueChange(self): left,top,width,height=self.location except: left=top=width=height=0 - x=left+(width/2) - y=top+(height/2) + x = left + (width // 2) + y = top+ (height // 2) lastBeepProgressValue=self.progressValueCache.get("beep,%d,%d"%(x,y),None) if pbConf["progressBarOutputMode"] in ("beep","both") and (lastBeepProgressValue is None or abs(percentage-lastBeepProgressValue)>=pbConf["beepPercentageInterval"]): tones.beep(pbConf["beepMinHZ"]*2**(percentage/25.0),40) @@ -77,7 +77,7 @@ def getDialogText(cls,obj,allowFocusedDescendants=True): children=obj.children textList=[] childCount=len(children) - for index in xrange(childCount): + for index in range(childCount): child=children[index] childStates=child.states childRole=child.role @@ -323,7 +323,7 @@ def _calculateNewText(self, newLines, oldLines): textLen = len(text) prevTextLen = len(prevText) # Find the first character that differs between the two lines. - for pos in xrange(min(textLen, prevTextLen)): + for pos in range(min(textLen, prevTextLen)): if text[pos] != prevText[pos]: start = pos break @@ -336,7 +336,7 @@ def _calculateNewText(self, newLines, oldLines): # The lines are different lengths, so assume the rest of the line changed. end = textLen else: - for pos in xrange(textLen - 1, start - 1, -1): + for pos in range(textLen - 1, start - 1, -1): if text[pos] != prevText[pos]: end = pos + 1 break @@ -363,6 +363,7 @@ def event_gainFocus(self): self.startMonitoring() def event_loseFocus(self): + super(Terminal, self).event_loseFocus() self.stopMonitoring() class CandidateItem(NVDAObject): @@ -554,7 +555,7 @@ def _get_firstChild(self): return self._makeCell(1) def _get_children(self): - return [self._makeCell(column) for column in xrange(1, self.childCount + 1)] + return [self._makeCell(column) for column in range(1, self.childCount + 1)] def getChild(self, index): return self._makeCell(index + 1) diff --git a/source/NVDAObjects/inputComposition.py b/source/NVDAObjects/inputComposition.py index 769a2107eaa..03474ecbdd6 100644 --- a/source/NVDAObjects/inputComposition.py +++ b/source/NVDAObjects/inputComposition.py @@ -14,11 +14,11 @@ def calculateInsertedChars(oldComp,newComp): minLen=min(oldLen,newLen) diffStart=0 diffEnd=newLen - for index in xrange(minLen): + for index in range(minLen): if newComp[index]!=oldComp[index]: break diffStart=index+1 - for index in xrange(minLen,0,-1): + for index in range(minLen,0,-1): backIndex=index-minLen-1 if newComp[backIndex]!=oldComp[backIndex]: break @@ -27,6 +27,7 @@ def calculateInsertedChars(oldComp,newComp): return newComp[diffStart:diffEnd] class InputCompositionTextInfo(OffsetsTextInfo): + encoding = None def _getSelectionOffsets(self): return self.obj.readingSelectionOffsets if self.obj.isReading else self.obj.compositionSelectionOffsets diff --git a/source/NVDAObjects/window/_msOfficeChart.py b/source/NVDAObjects/window/_msOfficeChart.py index 0583f50d4ce..f783ded232e 100644 --- a/source/NVDAObjects/window/_msOfficeChart.py +++ b/source/NVDAObjects/window/_msOfficeChart.py @@ -530,7 +530,7 @@ def __init__(self,windowHandle, officeApplicationObject, officeChartObject, init except: seriesCount=None if seriesCount: - for i in xrange(seriesCount): + for i in range(seriesCount): self.addElement( OfficeChartElementSeries(windowHandle=self.windowHandle, officeChartObject = self.officeChartObject , elementID = xlSeries , arg1 = i +1 ) , self) self.addElement( OfficeChartElementCollection(windowHandle=self.windowHandle, officeChartObject = self.officeChartObject ) , self ) @@ -563,7 +563,7 @@ def _get_description(self): else: # Translators: Indicates the number of series in a chart where there are multiple series. seriesValueString = _( "There are total %d series in this chart" ) %(count) - for i in xrange(1, count+1): + for i in range(1, count+1): # Translators: Specifies the number and name of a series when listing series in a chart. seriesValueString += ", " + _("series {number} {name}").format(number=i, name=self.officeChartObject.SeriesCollection(i).Name) text += seriesValueString @@ -620,7 +620,7 @@ def __init__(self, windowHandle=None , officeChartObject=None , elementID=None self.addElement(OfficeChartElementLegend(windowHandle=self.windowHandle, officeChartObject = officeChartObject ) , self ) self.legendEntryCount = self.officeChartObject.Legend.LegendEntries().Count - for legendEntryIndex in xrange( 1 , self.legendEntryCount + 1 ) : + for legendEntryIndex in range( 1 , self.legendEntryCount + 1 ) : legendEntry = OfficeChartElementLegendEntry(windowHandle=self.windowHandle, officeChartObject = self.officeChartObject , elementID= xlLegendEntry , arg1 = legendEntryIndex , arg2 = self.legendEntryCount ) legendEntry.eventDriven = False self.addElement ( legendEntry , self ) @@ -649,11 +649,11 @@ def __init__(self,windowHandle, officeChartObject , elementID , arg1 = None , ar self.pointsCollection=self.officeChartObject.SeriesCollection(self.seriesIndex).Points() self.pointsCount=self.pointsCollection.Count - for pointIndex in xrange(1,self.pointsCount +1) : + for pointIndex in range(1,self.pointsCount +1) : self.addElement ( OfficeChartElementPoint(windowHandle=self.windowHandle, officeChartObject = self.officeChartObject , elementID= xlSeries, arg1 =self.seriesIndex, arg2 =pointIndex) , self ) self.trendlinesCount = self.officeChartObject.SeriesCollection(self.seriesIndex).Trendlines().Count - for trendlineIndex in xrange( 1 , self.trendlinesCount + 1 ) : + for trendlineIndex in range( 1 , self.trendlinesCount + 1 ) : self.addElement ( OfficeChartElementTrendline(windowHandle=self.windowHandle, officeChartObject = self.officeChartObject , elementID= xlTrendline , arg1 = self.seriesIndex , arg2 = trendlineIndex ) , self ) def _get_name(self): diff --git a/source/NVDAObjects/window/edit.py b/source/NVDAObjects/window/edit.py index dc4b9c5ba8a..f59b99b6e7f 100644 --- a/source/NVDAObjects/window/edit.py +++ b/source/NVDAObjects/window/edit.py @@ -32,6 +32,7 @@ import braille import watchdog import locationHelper +import textUtils selOffsetsAtLastCaretEvent=None @@ -67,13 +68,7 @@ class CharRangeStruct(ctypes.Structure): ('cpMax',ctypes.c_long), ] -class TextRangeUStruct(ctypes.Structure): - _fields_=[ - ('chrg',CharRangeStruct), - ('lpstrText',ctypes.c_wchar_p), - ] - -class TextRangeAStruct(ctypes.Structure): +class TextRangeStruct(ctypes.Structure): _fields_=[ ('chrg',CharRangeStruct), ('lpstrText',ctypes.c_char_p), @@ -130,6 +125,10 @@ class getTextExStruct(ctypes.Structure): ] class getTextLengthExStruct(ctypes.Structure): + """ + For documentation, see: + https://docs.microsoft.com/en-us/windows/desktop/api/richedit/ns-richedit-_gettextlengthex + """ _fields_=[ ('flags',ctypes.wintypes.DWORD), ('codepage',ctypes.c_uint), @@ -257,7 +256,8 @@ def _getFormatFieldAndOffsets(self,offset,formatConfig,calculateOffsets=True): formatField["font-name"]=charFormat.szFaceName if formatConfig["reportFontSize"]: if charFormat is None: charFormat=self._getCharFormat(offset) - formatField["font-size"]="%spt"%(charFormat.yHeight/20) + # Font size is supposed to be an integral value + formatField["font-size"]="%spt"%(charFormat.yHeight//20) if formatConfig["reportFontAttributes"]: if charFormat is None: charFormat=self._getCharFormat(offset) formatField["bold"]=bool(charFormat.dwEffects&CFE_BOLD) @@ -321,7 +321,7 @@ def _setCaretOffset(self,offset): def _getStoryText(self): if controlTypes.STATE_PROTECTED in self.obj.states: - return u'*'*(self._getStoryLength()-1) + return u'*' * (self._getStoryLength() - 1) return self.obj.windowText def _getStoryLength(self): @@ -339,47 +339,68 @@ def _getStoryLength(self): textLen=watchdog.cancellableSendMessage(self.obj.windowHandle,EM_GETTEXTLENGTHEX,internalInfo,0) finally: winKernel.virtualFreeEx(processHandle,internalInfo,0,winKernel.MEM_RELEASE) + # Py3 review: investigation with Python 2 NVDA revealed that + # adding 1 to this creates an off by one error. + # Tested using Wordpad, enforcing EditTextInfo as the textInfo implementation. return textLen+1 else: + # ForWM_GETTEXTLENGTH documentation, see + # https://docs.microsoft.com/en-us/windows/desktop/winmsg/wm-gettextlength + # It determines the length, in characters, of the text associated with a window. + # Py3 review: investigation with Python 2 NVDA revealed that + # adding 1 to this created an off by one error. + # Tested using Notepad return watchdog.cancellableSendMessage(self.obj.windowHandle,winUser.WM_GETTEXTLENGTH,0,0)+1 def _getLineCount(self): return self.obj.windowTextLineCount def _getTextRange(self,start,end): - if self.obj.editAPIVersion>=2: - bufLen=((end-start)+1)*2 - if self.obj.isWindowUnicode: - textRange=TextRangeUStruct() - else: - textRange=TextRangeAStruct() - textRange.chrg.cpMin=start - textRange.chrg.cpMax=end - processHandle=self.obj.processHandle - internalBuf=winKernel.virtualAllocEx(processHandle,None,bufLen,winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE) + if self.obj.editAPIVersion >= 2: + # Calculate a buffer size that is twice the size of the text range and a NULL terminating character. + # As unicode characters are two bytes in size, + # this ensures that our buffer can hold both ANSI and unicode character strings. + bufLen = ((end - start) + 1) * 2 + # Even though this can return unicode text, we use the ANSI version of the structure. + # Using the unicode structure isn't strictly necessary and saves us some confusion + textRange = TextRangeStruct() + textRange.chrg.cpMin = start + textRange.chrg.cpMax = end + processHandle = self.obj.processHandle + internalBuf = winKernel.virtualAllocEx(processHandle, None, bufLen, winKernel.MEM_COMMIT, winKernel.PAGE_READWRITE) try: - textRange.lpstrText=internalBuf - internalTextRange=winKernel.virtualAllocEx(processHandle,None,ctypes.sizeof(textRange),winKernel.MEM_COMMIT,winKernel.PAGE_READWRITE) + textRange.lpstrText = internalBuf + internalTextRange = winKernel.virtualAllocEx(processHandle, None, ctypes.sizeof(textRange), winKernel.MEM_COMMIT, winKernel.PAGE_READWRITE) try: - winKernel.writeProcessMemory(processHandle,internalTextRange,ctypes.byref(textRange),ctypes.sizeof(textRange),None) - res=watchdog.cancellableSendMessage(self.obj.windowHandle,EM_GETTEXTRANGE,0,internalTextRange) + winKernel.writeProcessMemory(processHandle, internalTextRange, ctypes.byref(textRange), ctypes.sizeof(textRange), None) + # EM_GETTEXTRANGE returns the number of characters copied, + # not including the terminating null character. + # See https://docs.microsoft.com/en-us/windows/desktop/controls/em-gettextrange + numChars = watchdog.cancellableSendMessage(self.obj.windowHandle, EM_GETTEXTRANGE, 0, internalTextRange) finally: - winKernel.virtualFreeEx(processHandle,internalTextRange,0,winKernel.MEM_RELEASE) - buf=(ctypes.c_byte*bufLen)() + winKernel.virtualFreeEx(processHandle, internalTextRange, 0, winKernel.MEM_RELEASE) + buf = ctypes.create_string_buffer(bufLen) + # Copy the text in the text range to our own buffer. winKernel.readProcessMemory(processHandle,internalBuf,buf,bufLen,None) finally: - winKernel.virtualFreeEx(processHandle,internalBuf,0,winKernel.MEM_RELEASE) - if self.obj.isWindowUnicode or (res>1 and (buf[res]!=0 or buf[res+1]!=0)): - text=ctypes.cast(buf,ctypes.c_wchar_p).value + winKernel.virtualFreeEx(processHandle, internalBuf, 0, winKernel.MEM_RELEASE) + # Find out which encoding to use to decode the bytes in the buffer. + if ( + # The window is unicode, the text range contains multi byte characters. + self.obj.isWindowUnicode + ): + encoding = textUtils.WCHAR_ENCODING else: - text=unicode(ctypes.cast(buf,ctypes.c_char_p).value, errors="replace", encoding=locale.getlocale()[1]) + # De encoding will be determined by L{textUtils.getTextFromRawBytes} + encoding = None + text = textUtils.getTextFromRawBytes(buf.raw, numChars, encoding) # #4095: Some protected richEdit controls do not hide their password characters. # We do this specifically. # Note that protected standard edit controls get characters hidden in _getStoryText. if text and controlTypes.STATE_PROTECTED in self.obj.states: text=u'*'*len(text) else: - text=self._getStoryText()[start:end] + text = super(EditTextInfo, self)._getTextRange(start, end) return text def _getWordOffsets(self,offset): @@ -396,7 +417,6 @@ def _getWordOffsets(self,offset): else: return super(EditTextInfo,self)._getWordOffsets(offset) - def _getLineNumFromOffset(self,offset): if self.obj.editAPIVersion>=1: res=watchdog.cancellableSendMessage(self.obj.windowHandle,EM_EXLINEFROMCHAR,0,offset) @@ -452,12 +472,13 @@ def _get_pointAtStart(self): else: raise NotImplementedError - def _getFormatFieldAtRange(self,range,formatConfig): + def _getFormatFieldAtRange(self, textRange, formatConfig): formatField=textInfos.FormatField() fontObj=None paraFormatObj=None if formatConfig["reportAlignment"]: - if not paraFormatObj: paraFormatObj=range.para + if not paraFormatObj: + paraFormatObj = textRange.para alignment=paraFormatObj.alignment if alignment==comInterfaces.tom.tomAlignLeft: formatField["text-align"]="left" @@ -468,15 +489,18 @@ def _getFormatFieldAtRange(self,range,formatConfig): elif alignment==comInterfaces.tom.tomAlignJustify: formatField["text-align"]="justify" if formatConfig["reportLineNumber"]: - formatField["line-number"]=range.getIndex(comInterfaces.tom.tomLine) + formatField["line-number"] = textRange.getIndex(comInterfaces.tom.tomLine) if formatConfig["reportFontName"]: - if not fontObj: fontObj=range.font + if not fontObj: + fontObj = textRange.font formatField["font-name"]=fontObj.name if formatConfig["reportFontSize"]: - if not fontObj: fontObj=range.font + if not fontObj: + fontObj = textRange.font formatField["font-size"]="%spt"%fontObj.size if formatConfig["reportFontAttributes"]: - if not fontObj: fontObj=range.font + if not fontObj: + fontObj = textRange.font formatField["bold"]=bool(fontObj.bold) formatField["italic"]=bool(fontObj.italic) formatField["underline"]=bool(fontObj.underline) @@ -486,11 +510,12 @@ def _getFormatFieldAtRange(self,range,formatConfig): elif fontObj.subscript: formatField["text-position"]="sub" if formatConfig["reportLinks"]: - linkRange=range.Duplicate + linkRange = textRange.Duplicate linkRange.Collapse(comInterfaces.tom.tomStart) formatField["link"]=linkRange.Expand(comInterfaces.tom.tomLink)>0 if formatConfig["reportColor"]: - if not fontObj: fontObj=range.font + if not fontObj: + fontObj = textRange.font fgColor=fontObj.foreColor if fgColor==comInterfaces.tom.tomAutoColor: # Translators: The default color of text when a color has not been set by the author. @@ -511,7 +536,8 @@ def _getFormatFieldAtRange(self,range,formatConfig): formatField['background-color']=_("Unknown color") else: formatField["background-color"]=colors.RGB.fromCOLORREF(bkColor) - if not fontObj: fontObj=range.font + if not fontObj: + fontObj = textRange.font try: langId = fontObj.languageID if langId: @@ -521,10 +547,10 @@ def _getFormatFieldAtRange(self,range,formatConfig): pass return formatField - def _expandFormatRange(self,range,formatConfig): + def _expandFormatRange(self, textRange, formatConfig): startLimit=self._rangeObj.start endLimit=self._rangeObj.end - chunkRange=range.duplicate + chunkRange = textRange.duplicate if formatConfig["reportLineNumber"]: chunkRange.expand(comInterfaces.tom.tomLine) else: @@ -535,12 +561,12 @@ def _expandFormatRange(self,range,formatConfig): startLimit=chunkStart if endLimit>chunkEnd: endLimit=chunkEnd - #range.moveEnd(comInterfaces.tom.tomCharFormat,1) - range.expand(comInterfaces.tom.tomCharFormat) - if range.end>endLimit: - range.end=endLimit - if range.start endLimit: + textRange.end = endLimit + if textRange.start < startLimit: + textRange.start = startLimit def _getEmbeddedObjectLabel(self,embedRangeObj): label=None @@ -599,7 +625,7 @@ def _getTextAtRange(self,rangeObj): return u'*'*len(bufText) newTextList=[] start=rangeObj.start - for offset in xrange(len(bufText)): + for offset in range(len(bufText)): if ord(bufText[offset])==0xfffc: if embedRangeObj is None: embedRangeObj=rangeObj.duplicate embedRangeObj.setRange(start+offset,start+offset+1) @@ -641,22 +667,22 @@ def __init__(self,obj,position,_rangeObj=None): def getTextWithFields(self,formatConfig=None): if not formatConfig: formatConfig=config.conf["documentFormatting"] - range=self._rangeObj.duplicate - range.collapse(True) + textRange=self._rangeObj.duplicate + textRange.collapse(True) if not formatConfig["detectFormatAfterCursor"]: - range.expand(comInterfaces.tom.tomCharacter) - return [textInfos.FieldCommand("formatChange",self._getFormatFieldAtRange(range,formatConfig)), + textRange.expand(comInterfaces.tom.tomCharacter) + return [textInfos.FieldCommand("formatChange",self._getFormatFieldAtRange(textRange, formatConfig)), self._getTextAtRange(self._rangeObj)] commandList=[] endLimit=self._rangeObj.end - while range.end0 and isinstance(item,basestring) and item.isspace(): + elif index>0 and isinstance(item,str) and item.isspace(): #2047: don't expose language for whitespace as its incorrect for east-asian languages lastItem=commandList[index-1] if isinstance(lastItem,textInfos.FieldCommand) and isinstance(lastItem.field,textInfos.FormatField): @@ -1033,9 +1034,9 @@ def getMathMl(self, field): import mathType except: raise LookupError("MathType not installed") - range = self._rangeObj.Duplicate - range.Start = int(field["shapeoffset"]) - obj = range.InlineShapes[0].OLEFormat + rangeObj = self._rangeObj.Duplicate + rangeObj.Start = int(field["shapeoffset"]) + obj = rangeObj.InlineShapes[0].OLEFormat try: return mathType.getMathMl(obj) except: diff --git a/source/UIABrowseMode.py b/source/UIABrowseMode.py index 86c285ab194..d7e305cabdc 100644 --- a/source/UIABrowseMode.py +++ b/source/UIABrowseMode.py @@ -156,9 +156,11 @@ def UIAHeadingQuicknavIterator(itemType,document,position,direction="next"): tempInfo=curPosition.copy() tempInfo.expand(textInfos.UNIT_CHARACTER) styleIDValue=getUIATextAttributeValueFromRange(tempInfo._rangeObj,UIAHandler.UIA_StyleIdAttributeId,ignoreMixedValues=True) - if (UIAHandler.StyleId_Heading1<=styleIDValue<=UIAHandler.StyleId_Heading9): - foundLevel=(styleIDValue-UIAHandler.StyleId_Heading1)+1 - wantedLevel=int(itemType[7:]) if len(itemType)>7 else None + # #9842: styleIDValue can sometimes be a pointer to IUnknown. + # In Python 3, comparing an int with a pointer raises a TypeError. + if isinstance(styleIDValue, int) and UIAHandler.StyleId_Heading1 <= styleIDValue <= UIAHandler.StyleId_Heading9: + foundLevel = (styleIDValue - UIAHandler.StyleId_Heading1) + 1 + wantedLevel = int(itemType[7:]) if len(itemType) > 7 else None if not wantedLevel or wantedLevel==foundLevel: if not firstLoop or not position: tempInfo.expand(textInfos.UNIT_PARAGRAPH) @@ -175,7 +177,7 @@ def UIAControlQuicknavIterator(itemType,document,position,UIACondition,direction # All items are requested (such as for elements list) elements=document.rootNVDAObject.UIAElement.findAll(UIAHandler.TreeScope_Descendants,UIACondition) if elements: - for index in xrange(elements.length): + for index in range(elements.length): element=elements.getElement(index) try: elementRange=document.rootNVDAObject.UIATextPattern.rangeFromChild(element) diff --git a/source/UIAUtils.py b/source/UIAUtils.py index 7704b12aa2d..b2e6e1c2f5e 100644 --- a/source/UIAUtils.py +++ b/source/UIAUtils.py @@ -19,7 +19,7 @@ def createUIAMultiPropertyCondition(*dicts): outerOrList=[] for dict in dicts: andList=[] - for key,values in dict.iteritems(): + for key,values in dict.items(): innerOrList=[] if not isinstance(values,(list,set)): values=[values] @@ -84,12 +84,12 @@ class UIAMixedAttributeError(ValueError): """Raised when a function would return a UIAutomation text attribute value that is mixed.""" pass -def getUIATextAttributeValueFromRange(range,attrib,ignoreMixedValues=False): +def getUIATextAttributeValueFromRange(rangeObj,attrib,ignoreMixedValues=False): """ Wraps IUIAutomationTextRange::getAttributeValue, returning UIAutomation's reservedNotSupportedValue on COMError, and raising UIAMixedAttributeError if a mixed value would be returned and ignoreMixedValues is False. """ try: - val=range.GetAttributeValue(attrib) + val = rangeObj.GetAttributeValue(attrib) except COMError: return UIAHandler.handler.reservedNotSupportedValue if val==UIAHandler.handler.ReservedMixedAttributeValue: @@ -195,7 +195,7 @@ def __init__(self,textRange,IDs): super(BulkUIATextRangeAttributeValueFetcher,self).__init__(textRange) IDsArray=(ctypes.c_long*len(IDs))(*IDs) values=textRange.GetAttributeValues(IDsArray,len(IDsArray)) - self.IDsToValues={IDs[x]:values[x] for x in xrange(len(IDs))} + self.IDsToValues={IDs[x]:values[x] for x in range(len(IDs))} def getValue(self,ID,ignoreMixedValues=False): val=self.IDsToValues[ID] diff --git a/source/XMLFormatting.py b/source/XMLFormatting.py index af294b53170..73fe805d56a 100755 --- a/source/XMLFormatting.py +++ b/source/XMLFormatting.py @@ -1,6 +1,13 @@ +#XMLFormatting.py +#A part of NonVisual Desktop Access (NVDA) +#Copyright (C) 2008-2019 NV Access Limited, Babbage B.V. +#This file is covered by the GNU General Public License. +#See the file COPYING for more details. + from xml.parsers import expat import textInfos from logHandler import log +from textUtils import WCHAR_ENCODING, isLowSurrogate class XMLTextParser(object): @@ -16,10 +23,10 @@ def _startElementHandler(self,tagName,attrs): data=attrs.get('value',None) if data is not None: try: - data=unichr(int(data)) + data=chr(int(data)) except ValueError: data=u'\ufffd' - self._CharacterDataHandler(data) + self._CharacterDataHandler(data, processBufferedSurrogates=isLowSurrogate(data)) return elif tagName=='control': newAttrs=textInfos.ControlField(attrs) @@ -48,16 +55,18 @@ def _EndElementHandler(self,tagName): else: raise ValueError("unknown tag name: %s"%tagName) - def _CharacterDataHandler(self,data): + def _CharacterDataHandler(self,data, processBufferedSurrogates=False): cmdList=self._commandList - if cmdList and isinstance(cmdList[-1],basestring): - cmdList[-1]+=data + if cmdList and isinstance(cmdList[-1],str): + cmdList[-1] += data + if processBufferedSurrogates: + cmdList[-1] = cmdList[-1].encode(WCHAR_ENCODING, errors="surrogatepass").decode(WCHAR_ENCODING) else: cmdList.append(data) def parse(self,XMLText): try: - self.parser.Parse(XMLText.encode('utf-8')) + self.parser.Parse(XMLText) except: log.error("XML: %s"%XMLText,exc_info=True) return self._commandList diff --git a/source/_UIAHandler.py b/source/_UIAHandler.py index 543242ab41a..5f72a243ae0 100644 --- a/source/_UIAHandler.py +++ b/source/_UIAHandler.py @@ -158,7 +158,7 @@ ignoreWinEventsMap = { UIA_AutomationPropertyChangedEventId: list(UIAPropertyIdsToNVDAEventNames.keys()), } -for id in UIAEventIdsToNVDAEventNames.iterkeys(): +for id in UIAEventIdsToNVDAEventNames.keys(): ignoreWinEventsMap[id] = [0] class UIAHandler(COMObject): @@ -197,10 +197,10 @@ def MTAThreadFunc(self): # #7345: Instruct UIA to never map MSAA winEvents to UIA propertyChange events. # These events are not needed by NVDA, and they can cause the UI Automation client library to become unresponsive if an application firing winEvents has a slow message pump. pfm=self.clientObject.proxyFactoryMapping - for index in xrange(pfm.count): + for index in range(pfm.count): e=pfm.getEntry(index) entryChanged = False - for eventId, propertyIds in ignoreWinEventsMap.iteritems(): + for eventId, propertyIds in ignoreWinEventsMap.items(): for propertyId in propertyIds: # Check if this proxy has mapped any winEvents to the UIA propertyChange event for this property ID try: @@ -248,8 +248,9 @@ def MTAThreadFunc(self): self.reservedNotSupportedValue=self.clientObject.ReservedNotSupportedValue self.ReservedMixedAttributeValue=self.clientObject.ReservedMixedAttributeValue self.clientObject.AddFocusChangedEventHandler(self.baseCacheRequest,self) - self.clientObject.AddPropertyChangedEventHandler(self.rootElement,TreeScope_Subtree,self.baseCacheRequest,self,UIAPropertyIdsToNVDAEventNames.keys()) - for x in UIAEventIdsToNVDAEventNames.iterkeys(): + # Use a list of keys as AddPropertyChangedEventHandler expects a sequence. + self.clientObject.AddPropertyChangedEventHandler(self.rootElement,TreeScope_Subtree,self.baseCacheRequest,self,list(UIAPropertyIdsToNVDAEventNames)) + for x in UIAEventIdsToNVDAEventNames.keys(): self.clientObject.addAutomationEventHandler(x,self.rootElement,TreeScope_Subtree,self.baseCacheRequest,self) # #7984: add support for notification event (IUIAutomation5, part of Windows 10 build 16299 and later). if isinstance(self.clientObject, IUIAutomation5): diff --git a/source/addonHandler/__init__.py b/source/addonHandler/__init__.py index 7dd532acd0c..10f95c8549b 100644 --- a/source/addonHandler/__init__.py +++ b/source/addonHandler/__init__.py @@ -14,7 +14,8 @@ import collections import pkgutil import shutil -from six.moves import cStringIO as StringIO, cPickle +from io import StringIO +import pickle from six import string_types import globalVars import zipfile @@ -47,7 +48,9 @@ def loadState(): global state statePath=os.path.join(globalVars.appArgs.configPath,stateFilename) try: - state = cPickle.load(file(statePath, "r")) + # #9038: Python 3 requires binary format when working with pickles. + with open(statePath, "rb") as f: + state = pickle.load(f) if "disabledAddons" not in state: state["disabledAddons"] = set() if "pendingDisableSet" not in state: @@ -67,7 +70,9 @@ def loadState(): def saveState(): statePath=os.path.join(globalVars.appArgs.configPath,stateFilename) try: - cPickle.dump(state, file(statePath, "wb")) + # #9038: Python 3 requires binary format when working with pickles. + with open(statePath, "wb") as f: + pickle.dump(state, f) except: log.debugWarning("Error saving state", exc_info=True) @@ -223,7 +228,7 @@ def getAvailableAddons(refresh=False, filterFunc=None): generators = [_getAvailableAddonsFromPath(path) for path in _getDefaultAddonPaths()] for addon in itertools.chain(*generators): _availableAddons[addon.path] = addon - return (addon for addon in _availableAddons.itervalues() if not filterFunc or filterFunc(addon)) + return (addon for addon in _availableAddons.values() if not filterFunc or filterFunc(addon)) def installAddonBundle(bundle): """Extracts an Addon bundle in to a unique subdirectory of the user addons directory, marking the addon as needing install completion on NVDA restart.""" @@ -278,13 +283,13 @@ def __init__(self, path): self.path = os.path.abspath(path) self._extendedPackages = set() manifest_path = os.path.join(path, MANIFEST_FILENAME) - with open(manifest_path) as f: + with open(manifest_path, 'r', encoding="utf_8") as f: translatedInput = None for translatedPath in _translatedManifestPaths(): p = os.path.join(self.path, translatedPath) if os.path.exists(p): log.debug("Using manifest translation from %s", p) - translatedInput = open(p, 'r') + translatedInput = open(p, 'r', encoding="utf_8") break self.manifest = AddonManifest(f, translatedInput) @@ -359,7 +364,6 @@ def addToPackagePath(self, package): if not os.path.isdir(extension_path): # This addon does not have extension points for this package return - # Python 2.x doesn't properly handle unicode import paths, so convert them before adding. converted_path = self._getPathForInclusionInPackage(package) package.__path__.insert(0, converted_path) self._extendedPackages.add(package) @@ -418,7 +422,7 @@ def isPendingDisable(self): def _getPathForInclusionInPackage(self, package): extension_path = os.path.join(self.path, package.__name__) - return extension_path.encode("mbcs") + return extension_path def loadModule(self, name): """ loads a python module from the addon directory @@ -470,9 +474,9 @@ def getDocFilePath(self, fileName=None): An add-on can specify a default documentation file name via the docFileName parameter in its manifest. @param fileName: The requested file name or C{None} for the add-on's default. - @type fileName: basestring + @type fileName: str @return: The path to the requested file or C{None} if it wasn't found. - @rtype: basestring + @rtype: str """ if not fileName: fileName = self.manifest["docFileName"] @@ -503,7 +507,7 @@ def getCodeAddon(obj=None, frameDist=1): if obj is None: obj = sys._getframe(frameDist) fileName = inspect.getfile(obj) - dir= unicode(os.path.abspath(os.path.dirname(fileName)), "mbcs") + dir= os.path.abspath(os.path.dirname(fileName)) # if fileName is not a subdir of one of the addon paths # It does not belong to an addon. for p in _getDefaultAddonPaths(): @@ -513,7 +517,7 @@ def getCodeAddon(obj=None, frameDist=1): raise AddonError("Code does not belong to an addon package.") curdir = dir while curdir not in _getDefaultAddonPaths(): - if curdir in _availableAddons.keys(): + if curdir in _availableAddons: return _availableAddons[curdir] curdir = os.path.abspath(os.path.join(curdir, "..")) # Not found! @@ -526,7 +530,7 @@ def initTranslation(): # FIXME: shall we retrieve the caller module object explicitly? try: callerFrame = inspect.currentframe().f_back - callerFrame.f_globals['_'] = translations.ugettext + callerFrame.f_globals['_'] = translations.gettext # Install our pgettext function. callerFrame.f_globals['pgettext'] = languageHandler.makePgettext(translations) finally: @@ -552,17 +556,24 @@ def __init__(self, bundlePath): """ Constructs an L{AddonBundle} from a filename. @param bundlePath: The path for the bundle file. """ - self._path = bundlePath if isinstance(bundlePath, unicode) else unicode(bundlePath, "mbcs") + self._path = bundlePath # Read manifest: translatedInput=None with zipfile.ZipFile(self._path, 'r') as z: for translationPath in _translatedManifestPaths(forBundle=True): try: + # ZipFile.open opens every file in binary mode. + # decoding is handled by configobj. translatedInput = z.open(translationPath, 'r') break except KeyError: pass - self._manifest = AddonManifest(z.open(MANIFEST_FILENAME), translatedInput=translatedInput) + self._manifest = AddonManifest( + # ZipFile.open opens every file in binary mode. + # decoding is handled by configobj. + z.open(MANIFEST_FILENAME, 'r'), + translatedInput=translatedInput + ) if self.manifest.errors is not None: _report_manifest_errors(self.manifest) raise AddonError("Manifest file has errors.") @@ -575,7 +586,7 @@ def extract(self, addonPath): """ with zipfile.ZipFile(self._path, 'r') as z: for info in z.infolist(): - if isinstance(info.filename, str): + if isinstance(info.filename, bytes): # #2505: Handle non-Unicode file names. # Most archivers seem to use the local OEM code page, even though the spec says only cp437. # HACK: Overriding info.filename is a bit ugly, but it avoids a lot of code duplication. @@ -603,7 +614,7 @@ def createAddonBundleFromPath(path, destDir=None): manifest_path = os.path.join(basedir, MANIFEST_FILENAME) if not os.path.isfile(manifest_path): raise AddonError("Can't find %s manifest file." % manifest_path) - with open(manifest_path) as f: + with open(manifest_path, 'r', encoding="utf_8") as f: manifest = AddonManifest(f) if manifest.errors is not None: _report_manifest_errors(manifest) diff --git a/source/api.py b/source/api.py index d75d87ca27b..821095a2736 100644 --- a/source/api.py +++ b/source/api.py @@ -84,7 +84,7 @@ def setFocusObject(obj): pass tempObj=getDesktopObject() # Scan backwards through the old ancestors looking for a match. - for index in xrange(oldFocusLineLength-1,-1,-1): + for index in range(oldFocusLineLength-1,-1,-1): watchdog.alive() if tempObj==oldFocusLine[index]: # Match! The old and new focus ancestors converge at this point. @@ -251,17 +251,14 @@ def isTypingProtected(): def createStateList(states): """Breaks down the given integer in to a list of numbers that are 2 to the power of their position.""" - return [x for x in [1<=1: api.processPendingEvents(processEventQueue=False) if eventHandler.isPendingEvents("gainFocus"): diff --git a/source/appModules/kindle.py b/source/appModules/kindle.py index 79e0446de5d..b32f80a6a2b 100644 --- a/source/appModules/kindle.py +++ b/source/appModules/kindle.py @@ -156,7 +156,7 @@ def _iterEmbeddedObjs(self, hypertext, startIndex, direction): """Recursively iterate through all embedded objects in a given direction starting at a given hyperlink index. """ log.debug("Starting at hyperlink index %d" % startIndex) - for index in xrange(startIndex, hypertext.nHyperlinks if direction == "next" else -1, 1 if direction == "next" else -1): + for index in range(startIndex, hypertext.nHyperlinks if direction == "next" else -1, 1 if direction == "next" else -1): hl = hypertext.hyperlink(index) obj = IAccessible(IAccessibleObject=hl.QueryInterface(IAccessibleHandler.IAccessible2), IAccessibleChildID=0) log.debug("Yielding object at index %d" % index) diff --git a/source/appModules/lockapp.py b/source/appModules/lockapp.py index 4d66e930b61..020109426b7 100644 --- a/source/appModules/lockapp.py +++ b/source/appModules/lockapp.py @@ -34,54 +34,55 @@ def event_NVDAObject_init(self, obj): obj.parent = None SAFE_SCRIPTS = { - GlobalCommands.script_reportCurrentFocus.__func__, - GlobalCommands.script_title.__func__, - GlobalCommands.script_dateTime.__func__, - GlobalCommands.script_say_battery_status.__func__, - GlobalCommands.script_navigatorObject_current.__func__, - GlobalCommands.script_navigatorObject_currentDimensions.__func__, - GlobalCommands.script_navigatorObject_toFocus.__func__, - GlobalCommands.script_navigatorObject_moveFocus.__func__, - GlobalCommands.script_navigatorObject_parent.__func__, - GlobalCommands.script_navigatorObject_next.__func__, - GlobalCommands.script_navigatorObject_previous.__func__, - GlobalCommands.script_navigatorObject_firstChild.__func__, - GlobalCommands.script_review_activate.__func__, - GlobalCommands.script_review_top.__func__, - GlobalCommands.script_review_previousLine.__func__, - GlobalCommands.script_review_currentLine.__func__, - GlobalCommands.script_review_nextLine.__func__, - GlobalCommands.script_review_bottom.__func__, - GlobalCommands.script_review_previousWord.__func__, - GlobalCommands.script_review_currentWord.__func__, - GlobalCommands.script_review_nextWord.__func__, - GlobalCommands.script_review_startOfLine.__func__, - GlobalCommands.script_review_previousCharacter.__func__, - GlobalCommands.script_review_currentCharacter.__func__, - GlobalCommands.script_review_nextCharacter.__func__, - GlobalCommands.script_review_endOfLine.__func__, - GlobalCommands.script_review_sayAll.__func__, - GlobalCommands.script_braille_scrollBack.__func__, - GlobalCommands.script_braille_scrollForward.__func__, - GlobalCommands.script_braille_routeTo.__func__, - GlobalCommands.script_braille_previousLine.__func__, - GlobalCommands.script_braille_nextLine.__func__, - GlobalCommands.script_navigatorObject_nextInFlow.__func__, - GlobalCommands.script_navigatorObject_previousInFlow.__func__, - GlobalCommands.script_touch_changeMode.__func__, - GlobalCommands.script_touch_newExplore.__func__, - GlobalCommands.script_touch_explore.__func__, - GlobalCommands.script_touch_hoverUp.__func__, - GlobalCommands.script_moveMouseToNavigatorObject.__func__, - GlobalCommands.script_moveNavigatorObjectToMouse.__func__, - GlobalCommands.script_leftMouseClick.__func__, - GlobalCommands.script_rightMouseClick.__func__, + GlobalCommands.script_reportCurrentFocus, + GlobalCommands.script_title, + GlobalCommands.script_dateTime, + GlobalCommands.script_say_battery_status, + GlobalCommands.script_navigatorObject_current, + GlobalCommands.script_navigatorObject_currentDimensions, + GlobalCommands.script_navigatorObject_toFocus, + GlobalCommands.script_navigatorObject_moveFocus, + GlobalCommands.script_navigatorObject_parent, + GlobalCommands.script_navigatorObject_next, + GlobalCommands.script_navigatorObject_previous, + GlobalCommands.script_navigatorObject_firstChild, + GlobalCommands.script_review_activate, + GlobalCommands.script_review_top, + GlobalCommands.script_review_previousLine, + GlobalCommands.script_review_currentLine, + GlobalCommands.script_review_nextLine, + GlobalCommands.script_review_bottom, + GlobalCommands.script_review_previousWord, + GlobalCommands.script_review_currentWord, + GlobalCommands.script_review_nextWord, + GlobalCommands.script_review_startOfLine, + GlobalCommands.script_review_previousCharacter, + GlobalCommands.script_review_currentCharacter, + GlobalCommands.script_review_nextCharacter, + GlobalCommands.script_review_endOfLine, + GlobalCommands.script_review_sayAll, + GlobalCommands.script_braille_scrollBack, + GlobalCommands.script_braille_scrollForward, + GlobalCommands.script_braille_routeTo, + GlobalCommands.script_braille_previousLine, + GlobalCommands.script_braille_nextLine, + GlobalCommands.script_navigatorObject_nextInFlow, + GlobalCommands.script_navigatorObject_previousInFlow, + GlobalCommands.script_touch_changeMode, + GlobalCommands.script_touch_newExplore, + GlobalCommands.script_touch_explore, + GlobalCommands.script_touch_hoverUp, + GlobalCommands.script_moveMouseToNavigatorObject, + GlobalCommands.script_moveNavigatorObjectToMouse, + GlobalCommands.script_leftMouseClick, + GlobalCommands.script_rightMouseClick, } def _inputCaptor(self, gesture): script = gesture.script if not script: return True # Only allow specific scripts so people can't touch the clipboard, change NVDA config, etc. + # #9883: script is a bound method, __func__ gives us the underlying function. return script.__func__ in self.SAFE_SCRIPTS def event_appModule_gainFocus(self): diff --git a/source/appModules/miranda32.py b/source/appModules/miranda32.py index 8a3f5535919..54e83fb1950 100644 --- a/source/appModules/miranda32.py +++ b/source/appModules/miranda32.py @@ -122,7 +122,7 @@ def script_readMessage(self,gesture): def __init__(self, *args, **kwargs): super(AppModule, self).__init__(*args, **kwargs) - for n in xrange(1, self.MessageHistoryLength + 1): + for n in range(1, self.MessageHistoryLength + 1): self.bindGesture("kb:NVDA+control+%s" % n, "readMessage") class mirandaIMContactList(IAccessible): @@ -225,7 +225,7 @@ def _get_name(self): tc=None if tc and tc.role==controlTypes.ROLE_TABCONTROL: children=tc.children - for index in xrange(len(children)): + for index in range(len(children)): if (children[index].role==controlTypes.ROLE_TAB) and (controlTypes.STATE_SELECTED in children[index].states): name=children[index].name break diff --git a/source/appModules/msimn.py b/source/appModules/msimn.py index a8052bf557b..591a1e03745 100644 --- a/source/appModules/msimn.py +++ b/source/appModules/msimn.py @@ -65,7 +65,7 @@ def event_NVDAObject_init(self,obj): parentClassName=winUser.getClassName(parentWindow) #If this object is an email header field, and we have a custom label for it, #Then set the object's name to the label - if parentClassName=="OE_Envelope" and isinstance(obj,IAccessible) and obj.IAccessibleChildID==0 and envelopeNames.has_key(controlID): + if parentClassName=="OE_Envelope" and isinstance(obj,IAccessible) and obj.IAccessibleChildID==0 and controlID in envelopeNames: obj.name=envelopeNames[controlID] obj.useITextDocumentSupport=True obj.editValueUnit=textInfos.UNIT_STORY diff --git a/source/appModules/msnmsgr.py b/source/appModules/msnmsgr.py index cefca969d55..5ec21fccf84 100755 --- a/source/appModules/msnmsgr.py +++ b/source/appModules/msnmsgr.py @@ -52,7 +52,7 @@ def _get_basicText(self): def _get_value(self): value=super(OldMSNHistory,self).value - if not isinstance(value,basestring): + if not isinstance(value,str): value="" return value diff --git a/source/appModules/nlnotes.py b/source/appModules/nlnotes.py index 3c71adfc2b8..3a8f87b387f 100644 --- a/source/appModules/nlnotes.py +++ b/source/appModules/nlnotes.py @@ -15,8 +15,7 @@ class IrisTedit(IAccessible): def _get_name(self): - left,top,width,height=self.location - label=api.getDesktopObject().objectFromPoint(left+(width/2),top+(height/2)) + label=api.getDesktopObject().objectFromPoint(*self.location.center) if label: return label.name diff --git a/source/appModules/outlook.py b/source/appModules/outlook.py index 9dc00b39ec0..772ce3245c2 100644 --- a/source/appModules/outlook.py +++ b/source/appModules/outlook.py @@ -445,7 +445,7 @@ def _get_name(self): # This is unexpected here. log.debugWarning("Unable to get relevant children for UIAGridRow", stack_info=True) return super(UIAGridRow, self).name - for index in xrange(cachedChildren.length): + for index in range(cachedChildren.length): e=cachedChildren.getElement(index) UIAControlType=e.cachedControlType UIAClassName=e.cachedClassName @@ -475,7 +475,7 @@ def _get_name(self): columnHeaderItems=None if columnHeaderItems: columnHeaderItems=columnHeaderItems.QueryInterface(UIAHandler.IUIAutomationElementArray) - for index in xrange(columnHeaderItems.length): + for index in range(columnHeaderItems.length): columnHeaderItem=columnHeaderItems.getElement(index) columnHeaderTextList.append(columnHeaderItem.currentName) columnHeaderText=" ".join(columnHeaderTextList) diff --git a/source/appModules/powerpnt.py b/source/appModules/powerpnt.py index 627d8870e9c..84cf11fc14b 100644 --- a/source/appModules/powerpnt.py +++ b/source/appModules/powerpnt.py @@ -244,7 +244,7 @@ def getBulletText(ppBulletFormat): if t==ppBulletNumbered: return "%d."%ppBulletFormat.number #(ppBulletFormat.startValue+(ppBulletFormat.number-1)) elif t: - return unichr(ppBulletFormat.character) + return chr(ppBulletFormat.character) def walkPpShapeRange(ppShapeRange): for ppShape in ppShapeRange: diff --git a/source/appModules/soffice.py b/source/appModules/soffice.py index 4aa10c775ae..478a84c2ddc 100755 --- a/source/appModules/soffice.py +++ b/source/appModules/soffice.py @@ -220,7 +220,7 @@ def _get_states(self): # #8988: Cells in Libre Office do not have the selected state when a single cell is selected (i.e. has focus). # Since #8898, the negative selected state is announced for table cells with the selectable state. states.add(controlTypes.STATE_SELECTED) - if self.IA2Attributes.get('Formula'): + if self.IA2Attributes.get('Formula'): # #860: Recent versions of Calc expose has formula state via IAccessible 2. states.add(controlTypes.STATE_HASFORMULA) return states diff --git a/source/appModules/vipmud.py b/source/appModules/vipmud.py index 7f921656ffa..b7a251d438f 100644 --- a/source/appModules/vipmud.py +++ b/source/appModules/vipmud.py @@ -23,7 +23,7 @@ def chooseNVDAObjectOverlayClasses(self, obj, clsList): clsList.insert(0, MudText) def __init__(self, *args, **kwargs): super(AppModule, self).__init__(*args, **kwargs) - for n in xrange(1, self.historyLength +1): + for n in range(1, self.historyLength +1): self.bindGesture("kb:control+%s" % n, "readMessage") def script_readMessage(self,gesture): num=int(gesture.mainKeyName[-1]) diff --git a/source/appModules/winamp.py b/source/appModules/winamp.py index 5e252b7c373..a155fc8b766 100644 --- a/source/appModules/winamp.py +++ b/source/appModules/winamp.py @@ -115,7 +115,11 @@ def _get_name(self): winKernel.readProcessMemory(self.processHandle,internalInfo,byref(info),sizeof(info),None) finally: winKernel.virtualFreeEx(self.processHandle,internalInfo,0,winKernel.MEM_RELEASE) - return unicode("%d.\t%s\t%s"%(curIndex+1,info.filetitle,info.filelength), errors="replace", encoding=locale.getlocale()[1]) + # file title is fetched in the current locale encoding. + # We need to decode it to unicode first. + encoding=locale.getlocale()[1] + fileTitle=info.filetitle.decode(encoding,errors="replace") + return "%d.\t%s\t%s"%(curIndex+1,fileTitle,info.filelength) def _get_role(self): return controlTypes.ROLE_LISTITEM diff --git a/source/baseObject.py b/source/baseObject.py index 3f04cdc93e0..8cdcc1551d1 100755 --- a/source/baseObject.py +++ b/source/baseObject.py @@ -10,7 +10,6 @@ import weakref from logHandler import log from abc import ABCMeta, abstractproperty -from six import with_metaclass class Getter(object): @@ -69,7 +68,7 @@ def __init__(self,name,bases,dict): s=dict.get('_set_%s'%x,None) d=dict.get('_del_%s'%x,None) if x in dict: - methodsString=",".join([str(i) for i in g,s,d if i]) + methodsString=",".join(str(i) for i in (g,s,d) if i) raise TypeError("%s is already a class attribute, cannot create descriptor with methods %s"%(x,methodsString)) if not g: # There's a setter or deleter, but no getter. @@ -104,7 +103,7 @@ def __init__(self,name,bases,dict): # The __abstractmethods__ set is frozen, therefore we ought to override it. self.__abstractmethods__=(self.__abstractmethods__|newAbstractProps)-oldAbstractProps -class AutoPropertyObject(with_metaclass(AutoPropertyType, object)): +class AutoPropertyObject(object, metaclass=AutoPropertyType): """A class that dynamically supports properties, by looking up _get_*, _set_*, and _del_* methods at runtime. _get_x will make property x with a getter (you can get its value). _set_x will make a property x with a setter (you can set its value). @@ -141,9 +140,12 @@ def __new__(cls, *args, **kwargs): def _getPropertyViaCache(self,getterMethod=None): if not getterMethod: raise ValueError("getterMethod is None") + missing=False try: val=self._propertyCache[getterMethod] except KeyError: + missing=True + if missing: val=getterMethod(self) self._propertyCache[getterMethod]=val return val @@ -155,9 +157,9 @@ def invalidateCache(self): def invalidateCaches(cls): """Invalidate the caches for all current instances. """ - # We use keys() here instead of iterkeys(), as invalidating the cache on an object may cause instances to disappear, + # We use a list here, as invalidating the cache on an object may cause instances to disappear, # which would in turn cause an exception due to the dictionary changing size during iteration. - for instance in cls.__instances.keys(): + for instance in list(cls.__instances): instance.invalidateCache() class ScriptableType(AutoPropertyType): @@ -173,8 +175,7 @@ def __new__(meta, name, bases, dict): # This class currently has no gestures dictionary, # because no custom __gestures dictionary has been defined. gestures = {} - # Python 3 incompatible. - for name, script in dict.iteritems(): + for name, script in dict.items(): if not name.startswith('script_'): continue scriptName = name[len("script_"):] @@ -185,7 +186,7 @@ def __new__(meta, name, bases, dict): setattr(cls, gesturesDictName, gestures) return cls -class ScriptableObject(with_metaclass(ScriptableType, AutoPropertyObject)): +class ScriptableObject(AutoPropertyObject, metaclass=ScriptableType): """A class that implements NVDA's scripting interface. Input gestures are bound to scripts such that the script will be executed when the appropriate input gesture is received. Scripts are methods named with a prefix of C{script_}; e.g. C{script_foo}. @@ -197,7 +198,7 @@ class ScriptableObject(with_metaclass(ScriptableType, AutoPropertyObject)): e.g. in the Input Gestures dialog. This can be overridden for individual scripts by setting a C{category} attribute on the script method. - @type scriptCategory: basestring + @type scriptCategory: str """ def __init__(self): @@ -261,7 +262,7 @@ def bindGestures(self, gestureMap): @param gestureMap: A mapping of gesture identifiers to script names. @type gestureMap: dict of str to str """ - for gestureIdentifier, scriptName in gestureMap.iteritems(): + for gestureIdentifier, scriptName in gestureMap.items(): if scriptName: try: self.bindGesture(gestureIdentifier, scriptName) diff --git a/source/bdDetect.py b/source/bdDetect.py index 195a2c67b58..bfca01e50ff 100644 --- a/source/bdDetect.py +++ b/source/bdDetect.py @@ -16,6 +16,8 @@ import itertools from collections import namedtuple, defaultdict, OrderedDict import threading +from typing import Iterable + import wx import hwPortUtils import braille @@ -26,7 +28,6 @@ from logHandler import log import config import time -import thread import appModuleHandler from baseObject import AutoPropertyObject import re @@ -41,9 +42,9 @@ class DeviceMatch( ): """Represents a detected device. @ivar id: The identifier of the device. - @type id: unicode + @type id: str @ivar port: The port that can be used by a driver to communicate with a device. - @type port: unicode + @type port: str @ivar deviceInfo: all known information about a device. @type deviceInfo: dict """ @@ -84,10 +85,10 @@ def addUsbDevices(driver, type, ids): @type ids: set of str @raise ValueError: When one of the provided IDs is malformed. """ - malformedIds = [id for id in ids if not isinstance(id, basestring) or not USB_ID_REGEX.match(id)] + malformedIds = [id for id in ids if not isinstance(id, str) or not USB_ID_REGEX.match(id)] if malformedIds: raise ValueError("Invalid IDs provided for driver %s, type %s: %s" - % (driver, type, ", ".join(wrongIds))) + % (driver, type, u", ".join(malformedIds))) devs = _getDriver(driver) driverUsb = devs[type] driverUsb.update(ids) @@ -118,8 +119,8 @@ def getDriversForConnectedUsbDevices(): for port in deviceInfoFetcher.comPorts if "usbID" in port) ) for match in usbDevs: - for driver, devs in _driverDevices.iteritems(): - for type, ids in devs.iteritems(): + for driver, devs in _driverDevices.items(): + for type, ids in devs.items(): if match.type==type and match.id in ids: yield driver, match @@ -136,7 +137,7 @@ def getDriversForPossibleBluetoothDevices(): for port in deviceInfoFetcher.hidDevices if port["provider"]=="bluetooth"), ) for match in btDevs: - for driver, devs in _driverDevices.iteritems(): + for driver, devs in _driverDevices.items(): matchFunc = devs[KEY_BLUETOOTH] if not callable(matchFunc): continue @@ -316,12 +317,11 @@ def terminate(self): core.post_windowMessageReceipt.unregister(self.handleWindowMessage) self._stopBgScan() -def getConnectedUsbDevicesForDriver(driver): +def getConnectedUsbDevicesForDriver(driver) -> Iterable[DeviceMatch]: """Get any connected USB devices associated with a particular driver. @param driver: The name of the driver. @type driver: str @return: Device information for each device. - @rtype: generator of L{DeviceMatch} @raise LookupError: If there is no detection data for this driver. """ devs = _driverDevices[driver] @@ -334,16 +334,15 @@ def getConnectedUsbDevicesForDriver(driver): for port in deviceInfoFetcher.comPorts if "usbID" in port) ) for match in usbDevs: - for type, ids in devs.iteritems(): + for type, ids in devs.items(): if match.type==type and match.id in ids: yield match -def getPossibleBluetoothDevicesForDriver(driver): +def getPossibleBluetoothDevicesForDriver(driver) -> Iterable[DeviceMatch]: """Get any possible Bluetooth devices associated with a particular driver. @param driver: The name of the driver. @type driver: str @return: Port information for each port. - @rtype: generator of L{DeviceMatch} @raise LookupError: If there is no detection data for this driver. """ matchFunc = _driverDevices[driver][KEY_BLUETOOTH] diff --git a/source/braille.py b/source/braille.py index 927c8fabe49..76344b437c5 100644 --- a/source/braille.py +++ b/source/braille.py @@ -5,11 +5,13 @@ #See the file COPYING for more details. #Copyright (C) 2008-2018 NV Access Limited, Joseph Lee, Babbage B.V., Davy Kager, Bram Duvigneau -import sys import itertools import os +from typing import Iterable, Union, Tuple, List, Optional + import driverHandler import pkgutil +import importlib import ctypes.wintypes import threading import time @@ -313,23 +315,22 @@ def NVDAObjectHasUsefulText(obj): def _getDisplayDriver(moduleName, caseSensitive=True): try: - return __import__("brailleDisplayDrivers.%s" % moduleName, globals(), locals(), ("brailleDisplayDrivers",)).BrailleDisplayDriver + return importlib.import_module("brailleDisplayDrivers.%s" % moduleName, package="brailleDisplayDrivers").BrailleDisplayDriver except ImportError as initialException: if caseSensitive: raise initialException for loader, name, isPkg in pkgutil.iter_modules(brailleDisplayDrivers.__path__): if name.startswith('_') or name.lower() != moduleName.lower(): continue - return __import__("brailleDisplayDrivers.%s" % name, globals(), locals(), ("brailleDisplayDrivers",)).BrailleDisplayDriver + return importlib.import_module("brailleDisplayDrivers.%s" % name, package="brailleDisplayDrivers").BrailleDisplayDriver else: raise initialException -def getDisplayList(excludeNegativeChecks=True): +def getDisplayList(excludeNegativeChecks=True) -> List[Tuple[str, str]]: """Gets a list of available display driver names with their descriptions. @param excludeNegativeChecks: excludes all drivers for which the check method returns C{False}. @type excludeNegativeChecks: bool @return: list of tuples with driver names and descriptions. - @rtype: [(str,unicode)] """ displayList = [] # The display that should be placed at the end of the list. @@ -435,7 +436,7 @@ def update(self): self.brailleSelectionEnd = len(self.brailleCells) else: self.brailleSelectionEnd = self.rawToBraillePos[self.selectionEnd] - for pos in xrange(self.brailleSelectionStart, self.brailleSelectionEnd): + for pos in range(self.brailleSelectionStart, self.brailleSelectionEnd): self.brailleCells[pos] |= SELECTION_SHAPE except IndexError: pass @@ -479,8 +480,11 @@ def getBrailleTextForProperties(**propertyValues): cellCoordsText=propertyValues.get('cellCoordsText') rowNumber = propertyValues.get("rowNumber") columnNumber = propertyValues.get("columnNumber") - rowSpan = propertyValues.get("rowSpan") - columnSpan = propertyValues.get("columnSpan") + # When fetching row and column span + # default the values to 1 to make further checks a lot simpler. + # After all, a table cell that has no rowspan implemented is assumed to span one row. + rowSpan = propertyValues.get("rowSpan") or 1 + columnSpan = propertyValues.get("columnSpan") or 1 includeTableCellCoords = propertyValues.get("includeTableCellCoords", True) if role is not None and not roleText: if role == controlTypes.ROLE_HEADING and level: @@ -809,7 +813,7 @@ def _addTextWithFields(self, info, formatConfig, isSelection=False): # When true, we are inside a clickable field, and should therefore not report any more new clickable fields inClickable=False for command in info.getTextWithFields(formatConfig=formatConfig): - if isinstance(command, basestring): + if isinstance(command, str): # Text should break a run of clickables inClickable=False self._isFormatFieldAtStart = False @@ -833,7 +837,7 @@ def _addTextWithFields(self, info, formatConfig, isSelection=False): commandLen = len(command) self.rawTextTypeforms.extend((typeform,) * commandLen) endPos = self._currentContentPos + commandLen - self._rawToContentPos.extend(xrange(self._currentContentPos, endPos)) + self._rawToContentPos.extend(range(self._currentContentPos, endPos)) self._currentContentPos = endPos if isSelection: # The last time this is set will be the end of the content. @@ -1116,7 +1120,7 @@ def _setCursor(self, info): api.setReviewPosition(info) def rindex(seq, item, start, end): - for index in xrange(end - 1, start - 1, -1): + for index in range(end - 1, start - 1, -1): if seq[index] == item: return index raise ValueError("%r is not in sequence" % item) @@ -1272,7 +1276,7 @@ def _set_windowEndPos(self, endPos): # Search from 1 cell before in case startPos is just after a space. startPos = self.brailleCells.index(0, startPos - 1, endPos) # Skip past spaces. - for startPos in xrange(startPos, endPos): + for startPos in range(startPos, endPos): if self.brailleCells[startPos] != 0: break except ValueError: @@ -1433,7 +1437,7 @@ def getFocusContextRegions(obj, oldFocusRegions=None): # We only want the ancestors of the buffer's root NVDAObject. if obj != api.getFocusObject(): # Search backwards through the focus ancestors to find the index of obj. - for index, ancestor in itertools.izip(xrange(len(ancestors) - 1, 0, -1), reversed(ancestors)): + for index, ancestor in zip(range(len(ancestors) - 1, 0, -1), reversed(ancestors)): if obj == ancestor: ancestorsEnd = index break @@ -1445,7 +1449,7 @@ def getFocusContextRegions(obj, oldFocusRegions=None): # Also, we don't ever want to fetch ancestor 0 (the desktop). newAncestorsStart = max(min(_cachedFocusAncestorsEnd, ancestorsEnd), 1) # Search backwards through the old regions to find the last common region. - for index, region in itertools.izip(xrange(len(oldFocusRegions) - 1, -1, -1), reversed(oldFocusRegions)): + for index, region in zip(range(len(oldFocusRegions) - 1, -1, -1), reversed(oldFocusRegions)): ancestorIndex = getattr(region, "_focusAncestorIndex", None) if ancestorIndex is None: continue @@ -1519,20 +1523,18 @@ def getFocusRegions(obj, review=False): region2.update() yield region2 -def formatCellsForLog(cells): +def formatCellsForLog(cells: List[int]) -> str: """Formats a sequence of braille cells so that it is suitable for logging. The output contains the dot numbers for each cell, with each cell separated by a space. A C{-} indicates an empty cell. @param cells: The cells to format. - @type cells: sequence of int @return: The formatted cells. - @rtype: str """ # optimisation: This gets called a lot, so needs to be as efficient as possible. # List comprehensions without function calls are faster than loops. # For str.join, list comprehensions are faster than generator comprehensions. return TEXT_SEPARATOR.join([ - "".join([str(dot + 1) for dot in xrange(8) if cell & (1 << dot)]) + "".join([str(dot + 1) for dot in range(8) if cell & (1 << dot)]) if cell else "-" for cell in cells]) @@ -1552,7 +1554,7 @@ class BrailleHandler(baseObject.AutoPropertyObject): def __init__(self): louisHelper.initialize() - self.display = None + self.display: Optional[BrailleDisplayDriver] = None self.displaySize = 0 self.mainBuffer = BrailleBuffer(self) self.messageBuffer = BrailleBuffer(self) @@ -2108,6 +2110,8 @@ def func(cls): "alvaBC6":"alva" } +handler: BrailleHandler + def initialize(): global handler config.addConfigDirsToPythonPackagePath(brailleDisplayDrivers) @@ -2268,7 +2272,7 @@ def getPossiblePorts(cls): return ports @classmethod - def _getAutoPorts(cls, usb=True, bluetooth=True): + def _getAutoPorts(cls, usb=True, bluetooth=True) -> Iterable[bdDetect.DeviceMatch]: """Returns possible ports to connect to using L{bdDetect} automatic detection data. @param usb: Whether to search for USB devices. @type usb: bool @@ -2290,27 +2294,26 @@ def _getAutoPorts(cls, usb=True, bluetooth=True): pass @classmethod - def getManualPorts(cls): + def getManualPorts(cls) -> Iterable[str]: """Get possible manual hardware ports for this driver. This is for ports which cannot be detected automatically such as serial ports. @return: The name and description for each port. - @rtype: iterable of basestring, basestring """ raise NotImplementedError @classmethod - def _getTryPorts(cls, port): + def _getTryPorts( + cls, port: Union[str, bdDetect.DeviceMatch] + ) -> Iterable[bdDetect.DeviceMatch]: """Returns the ports for this driver to which a connection attempt should be made. This generator function is usually used in L{__init__} to connect to the desired display. @param port: the port to connect to. - @type port: one of basestring or L{bdDetect.DeviceMatch} - @return: The name and description for each port. - @rtype: iterable of basestring, basestring + @return: The name and description for each port """ if isinstance(port, bdDetect.DeviceMatch): yield port - elif isinstance(port, basestring): + elif isinstance(port, str): isUsb = port in (AUTOMATIC_PORT[0], USB_PORT[0]) isBluetooth = port in (AUTOMATIC_PORT[0], BLUETOOTH_PORT[0]) if not isUsb and not isBluetooth: diff --git a/source/brailleDisplayDrivers/alva.py b/source/brailleDisplayDrivers/alva.py index 67c6697cdb4..104a09cde63 100644 --- a/source/brailleDisplayDrivers/alva.py +++ b/source/brailleDisplayDrivers/alva.py @@ -4,14 +4,15 @@ #See the file COPYING for more details. #Copyright (C) 2009-2018 NV Access Limited, Davy Kager, Leonard de Ruijter, Optelec B.V. -import serial +from typing import List, Union + import bdDetect import braille from logHandler import log import inputCore import brailleInput import hwIo -from collections import OrderedDict +from hwIo import intToByte, boolToByte, Serial from globalCommands import SCRCAT_BRAILLE import ui from baseObject import ScriptableObject @@ -39,6 +40,7 @@ ALVA_MODEL_BC640 = 0x40 ALVA_MODEL_BC680 = 0x80 ALVA_MODEL_CONVERTER = 0x99 +ESCAPE = b"\x1b" ALVA_MODEL_IDS = { ALVA_MODEL_BC640: "BC640", @@ -101,6 +103,7 @@ } class BrailleDisplayDriver(braille.BrailleDisplayDriver, ScriptableObject): + _dev: Union[hwIo.Serial, hwIo.Hid] name = "alva" # Translators: The name of a braille display. description = _("Optelec ALVA 6 series/protocol converter") @@ -124,22 +127,22 @@ def _updateSettings(self): oldNumCells = self.numCells if self.isHid: displaySettings = self._dev.getFeature(ALVA_DISPLAY_SETTINGS_REPORT) - if ord(displaySettings[ALVA_DISPLAY_SETTINGS_STATUS_CELL_SIDE_POS]) > 1: + if displaySettings[ALVA_DISPLAY_SETTINGS_STATUS_CELL_SIDE_POS] > 1: # #8106: The ALVA BC680 is known to return a malformed feature report for the first issued request. # Therefore, request another display settings report displaySettings = self._dev.getFeature(ALVA_DISPLAY_SETTINGS_REPORT) - self.numCells = ord(displaySettings[ALVA_DISPLAY_SETTINGS_CELL_COUNT_POS]) - timeStr = self._dev.getFeature(ALVA_RTC_REPORT)[1:ALVA_RTC_STR_LENGTH+1] + self.numCells = displaySettings[ALVA_DISPLAY_SETTINGS_CELL_COUNT_POS] + timeBytes: bytes = self._dev.getFeature(ALVA_RTC_REPORT)[1:ALVA_RTC_STR_LENGTH+1] try: - self._handleTime(timeStr) + self._handleTime(timeBytes) except: log.debugWarning("Getting time from ALVA display failed", exc_info=True) keySettings = self._dev.getFeature(ALVA_KEY_SETTINGS_REPORT)[ALVA_KEY_SETTINGS_POS] - self._rawKeyboardInput = bool(ord(keySettings) & ALVA_KEY_RAW_INPUT_MASK) + self._rawKeyboardInput = bool(keySettings & ALVA_KEY_RAW_INPUT_MASK) else: # Get cell count self._ser6SendMessage(b"E", b"?") - for i in xrange(3): + for i in range(3): self._dev.waitForRead(self.timeout) if self.numCells: # Display responded break @@ -170,7 +173,7 @@ def __init__(self, port="auto"): self._dev = hwIo.Serial(port, timeout=self.timeout, writeTimeout=self.timeout, onReceive=self._ser6OnReceive) # Get the device ID self._ser6SendMessage(b"?", b"?") - for i in xrange(3): + for i in range(3): self._dev.waitForRead(self.timeout) if self._deviceId: # Display responded break @@ -204,35 +207,43 @@ def terminate(self): # We must sleep after closing the COM port, as it takes some time for the device to disconnect. time.sleep(self.timeout) - def _ser6SendMessage(self, cmd, value=""): - if isinstance(value, (int, bool)): - value = chr(value) - self._dev.write(b"\x1b{cmd}{value}".format(cmd=cmd, value=value,)) + def _ser6SendMessage(self, cmd: bytes, value: bytes = b"") -> None: + if not isinstance(value, bytes): + raise TypeError("Expected param 'value' to have type 'bytes'") + self._dev.write(b"".join([ESCAPE, cmd, value])) - def _ser6OnReceive(self, data): - if data != b"\x1b": # Escape + def _ser6OnReceive(self, data: bytes): + """ Callback for L{self._dev} when it is L{hwIo.Serial} + """ + if data != ESCAPE: return - cmd = self._dev.read(1) - value = self._dev.read(ALVA_SER_CMD_LENGTHS[cmd]) + cmd: bytes = self._dev.read(1) + commandLen = ALVA_SER_CMD_LENGTHS[cmd] + value: bytes = self._dev.read(commandLen) - if cmd == b"K": # Input - self._handleInput(ord(value[0]), ord(value[1])) - elif cmd == b"E": # Braille cell count + if cmd == b"K": # Input + self._handleInput(group=value[0], number=value[1]) + elif cmd == b"E": # Braille cell count self.numCells = ord(value) - elif cmd == b"?": # Device ID - self._deviceId = ord(value) - elif cmd == b"r": # Raw keyboard messages enable/disable + elif cmd == b"?": # Device ID + self._deviceId = ord(value) # this command only gets one byte + elif cmd == b"r": # Raw keyboard messages enable/disable self._rawKeyboardInput = bool(ord(value)) - elif cmd == b"H": # Time + elif cmd == b"H": # Time # Handling time for serial displays does not block initialization if it fails. self._handleTime(value) - def _hidOnReceive(self, data): - reportID = data[0] + def _hidOnReceive(self, data: bytes): + """Callback for L{self._dev} when it is L{hwIo.Hid} + """ + reportID: bytes = data[0:1] if reportID == ALVA_KEY_REPORT: - self._handleInput(ord(data[ALVA_KEY_REPORT_KEY_GROUP_POS]), ord(data[ALVA_KEY_REPORT_KEY_POS])) + self._handleInput( + data[ALVA_KEY_REPORT_KEY_GROUP_POS], + data[ALVA_KEY_REPORT_KEY_POS] + ) - def _handleInput(self, group, number): + def _handleInput(self, group: int, number: int) -> None: if group == ALVA_SPECIAL_KEYS_GROUP: # ALVA displays communicate setting changes as input messages. if number == ALVA_SPECIAL_SETTINGS_CHANGED: @@ -258,44 +269,54 @@ def _handleInput(self, group, number): # This begins a new key combination. self._ignoreKeyReleases = False - def _hidDisplay(self, cells): - for offset in xrange(0, len(cells), ALVA_BRAILLE_OUTPUT_MAX_SIZE): - cellsToWrite = cells[offset:offset+ALVA_BRAILLE_OUTPUT_MAX_SIZE] - self._dev.write("{id}{offset}{count}{cells}".format( - id=ALVA_BRAILLE_OUTPUT_REPORT, - offset=chr(offset), - count=chr(len(cellsToWrite)), - cells=cellsToWrite - )) - - def _ser6Display(self, cells): - self._ser6SendMessage(b"B", chr(0)+chr(len(cells))+cells) - - def display(self, cells): + def _hidDisplay(self, cellBytes: bytes) -> None: + for offset in range(0, len(cellBytes), ALVA_BRAILLE_OUTPUT_MAX_SIZE): + cellsToWrite = cellBytes[offset:offset+ALVA_BRAILLE_OUTPUT_MAX_SIZE] + data = b"".join([ + ALVA_BRAILLE_OUTPUT_REPORT, + intToByte(offset), + intToByte(len(cellsToWrite)), + cellsToWrite + ]) + self._dev.write(data) + + def _ser6Display(self, cellBytes: bytes) -> None: + if not isinstance(cellBytes, bytes): + raise TypeError("Expected param 'cells' to be of type 'bytes'") + value = b"".join([ + b"\x00", + intToByte(len(cellBytes)), + cellBytes + ]) + self._ser6SendMessage(b"B", value) + + def display(self, cells: List[int]): # cells will already be padded up to numCells. - cells = b"".join(map(chr, cells)) + cellBytes = bytes(cells) if self.isHid: - self._hidDisplay(cells) + self._hidDisplay(cellBytes) else: - self._ser6Display(cells) + self._ser6Display(cellBytes) - def _handleTime(self, timeStr): - ords = map(ord, timeStr) - year=ords[0] | ords[1] << 8 + def _handleTime(self, time: bytes): + """ + @type time: bytes + """ + year = time[0] | time[1] << 8 if not ALVA_RTC_MIN_YEAR <= year <= ALVA_RTC_MAX_YEAR: log.debug("This ALVA display doesn't reveal clock information") return try: displayDateTime = datetime.datetime( year=year, - month=ords[2], - day=ords[3], - hour=ords[4], - minute=ords[5], - second=ords[6] + month=time[2], + day=time[3], + hour=time[4], + minute=time[5], + second=time[6] ) except ValueError: - log.debugWarning("Invalid time/date of ALVA display: %r"%timeStr) + log.debugWarning("Invalid time/date of ALVA display: %r" % time) return localDateTime = datetime.datetime.today() if abs((displayDateTime - localDateTime).total_seconds()) >= ALVA_RTC_MAX_DRIFT: @@ -304,18 +325,20 @@ def _handleTime(self, timeStr): else: log.debug("Time not synchronized. Display time %s"%displayDateTime.isoformat()) - def _syncTime(self, dt): + def _syncTime(self, dt: datetime.datetime): log.debug("Synchronizing braille display date and time...") - timeList = [ + timeList: List[int] = [ dt.year & 0xFF, dt.year >> 8, - dt.month, dt.day, - dt.hour, dt.minute, dt.second + dt.month, + dt.day, + dt.hour, + dt.minute, + dt.second ] - timeStr = b"".join(map(chr, timeList)) if self.isHid: - self._dev.setFeature(ALVA_RTC_REPORT + timeStr) + self._dev.setFeature(ALVA_RTC_REPORT + bytes(timeList)) else: - self._ser6SendMessage(b"H", timeStr) + self._ser6SendMessage(b"H", bytes(timeList)) def _get_hidKeyboardInput(self): return not self._rawKeyboardInput @@ -324,24 +347,31 @@ def _set_hidKeyboardInput(self, state): rawState = not state if self.isHid: # Make sure the device settings are up to date. - keySettings = self._dev.getFeature(ALVA_KEY_SETTINGS_REPORT)[ALVA_KEY_SETTINGS_POS] + keySettings: int = self._dev.getFeature( + ALVA_KEY_SETTINGS_REPORT + )[ALVA_KEY_SETTINGS_POS] # Try to update the state if rawState: - newKeySettings = chr(ord(keySettings) | ALVA_KEY_RAW_INPUT_MASK) - elif ord(keySettings) & ALVA_KEY_RAW_INPUT_MASK: - newKeySettings = chr(ord(keySettings) ^ ALVA_KEY_RAW_INPUT_MASK) + newKeySettings = intToByte(keySettings | ALVA_KEY_RAW_INPUT_MASK) + elif keySettings & ALVA_KEY_RAW_INPUT_MASK: + newKeySettings = intToByte(keySettings ^ ALVA_KEY_RAW_INPUT_MASK) else: - newKeySettings = keySettings + newKeySettings = intToByte(keySettings) self._dev.setFeature(ALVA_KEY_SETTINGS_REPORT + newKeySettings) # Check whether the state has been changed successfully. # If not, this device does not support this feature. - keySettings = self._dev.getFeature(ALVA_KEY_SETTINGS_REPORT)[ALVA_KEY_SETTINGS_POS] + keySettings: int = self._dev.getFeature( + ALVA_KEY_SETTINGS_REPORT + )[ALVA_KEY_SETTINGS_POS] # Save the new state - self._rawKeyboardInput = bool(ord(keySettings) & ALVA_KEY_RAW_INPUT_MASK) + self._rawKeyboardInput = bool(keySettings & ALVA_KEY_RAW_INPUT_MASK) else: - self._ser6SendMessage(b"r", rawState) + self._ser6SendMessage( + cmd=b"r", + value=boolToByte(rawState) + ) self._ser6SendMessage(b"r", b"?") - for i in xrange(3): + for i in range(3): self._dev.waitForRead(self.timeout) if rawState is self._rawKeyboardInput: break @@ -416,8 +446,7 @@ def __init__(self, model, keys, brailleInput=False): assert(self.model.isalnum()) self.keyCodes = set(keys) self.keyNames = names = [] - if isNoBC640: - secondaryNames = [] + secondaryNames = [] dots = 0 space = False for group, number in self.keyCodes: diff --git a/source/brailleDisplayDrivers/baum.py b/source/brailleDisplayDrivers/baum.py index 6b2a332cf7c..3e253e23a3e 100644 --- a/source/brailleDisplayDrivers/baum.py +++ b/source/brailleDisplayDrivers/baum.py @@ -5,10 +5,11 @@ #See the file COPYING for more details. #Copyright (C) 2010-2017 NV Access Limited, Babbage B.V. -import time -from collections import OrderedDict -from cStringIO import StringIO +from io import BytesIO +from typing import Union, List, Optional + import braille +from hwIo import intToByte, boolToByte import inputCore from logHandler import log import brailleInput @@ -18,21 +19,21 @@ TIMEOUT = 0.2 BAUD_RATE = 19200 -ESCAPE = "\x1b" - -BAUM_DISPLAY_DATA = "\x01" -BAUM_CELL_COUNT = "\x01" -BAUM_REQUEST_INFO = "\x02" -BAUM_PROTOCOL_ONOFF = "\x15" -BAUM_COMMUNICATION_CHANNEL = "\x16" -BAUM_POWERDOWN = "\x17" -BAUM_ROUTING_KEYS = "\x22" -BAUM_DISPLAY_KEYS = "\x24" -BAUM_ROUTING_KEY = "\x27" -BAUM_BRAILLE_KEYS = "\x33" -BAUM_JOYSTICK_KEYS = "\x34" -BAUM_DEVICE_ID = "\x84" -BAUM_SERIAL_NUMBER = "\x8A" +ESCAPE = b"\x1b" + +BAUM_DISPLAY_DATA = b"\x01" +BAUM_CELL_COUNT = b"\x01" +BAUM_REQUEST_INFO = b"\x02" +BAUM_PROTOCOL_ONOFF = b"\x15" +BAUM_COMMUNICATION_CHANNEL = b"\x16" +BAUM_POWERDOWN = b"\x17" +BAUM_ROUTING_KEYS = b"\x22" +BAUM_DISPLAY_KEYS = b"\x24" +BAUM_ROUTING_KEY = b"\x27" +BAUM_BRAILLE_KEYS = b"\x33" +BAUM_JOYSTICK_KEYS = b"\x34" +BAUM_DEVICE_ID = b"\x84" +BAUM_SERIAL_NUMBER = b"\x8A" BAUM_RSP_LENGTHS = { BAUM_CELL_COUNT: 1, @@ -56,6 +57,7 @@ } class BrailleDisplayDriver(braille.BrailleDisplayDriver): + _dev: hwIo.IoBase name = "baum" # Translators: Names of braille displays. description = _("Baum/HumanWare/APH/Orbit braille displays") @@ -68,7 +70,7 @@ def getManualPorts(cls): def __init__(self, port="auto"): super(BrailleDisplayDriver, self).__init__() self.numCells = 0 - self._deviceID = None + self._deviceID: Optional[str] = None for portType, portId, port, portInfo in self._getTryPorts(port): # At this point, a port bound to this display has been found. @@ -100,7 +102,7 @@ def __init__(self, port="auto"): self._sendRequest(BAUM_PROTOCOL_ONOFF, True) # Send again in case the display misses the first one. self._sendRequest(BAUM_PROTOCOL_ONOFF, True) - for i in xrange(3): + for i in range(3): # An expected response hasn't arrived yet, so wait for it. self._dev.waitForRead(TIMEOUT) if self.numCells and self._deviceID: @@ -122,7 +124,7 @@ def terminate(self): try: super(BrailleDisplayDriver, self).terminate() try: - self._sendRequest(BAUM_PROTOCOL_ONOFF, False) + self._sendRequest(BAUM_PROTOCOL_ONOFF, boolToByte(False)) except EnvironmentError: # Some displays don't support BAUM_PROTOCOL_ONOFF. pass @@ -131,19 +133,38 @@ def terminate(self): # If it doesn't, we may not be able to re-open it later. self._dev.close() - def _sendRequest(self, command, arg=""): - if isinstance(arg, (int, bool)): - arg = chr(arg) + def _sendRequest(self, command: bytes, arg: Union[bytes, bool, int] = b""): + """ + :type command: bytes + :type arg: bytes | bool | int + """ + typeErrorString = "Expected param '{}' to be of type '{}', got '{}'" + if not isinstance(arg, bytes): + if isinstance(arg, bool): + arg = boolToByte(arg) + elif isinstance(arg, int): + arg = intToByte(arg) + else: + raise TypeError(typeErrorString.format("arg", "bytes, bool, or int", type(arg).__name__)) + + if not isinstance(command, bytes): + raise TypeError(typeErrorString.format("command", "bytes", type(command).__name__)) + if self.isHid: self._dev.write(command + arg) else: - self._dev.write("\x1b{command}{arg}".format(command=command, - arg=arg.replace(ESCAPE, ESCAPE * 2))) + arg = arg.replace(ESCAPE, ESCAPE * 2) + data = b"".join([ + ESCAPE, + command, + arg + ]) + self._dev.write(data) - def _onReceive(self, data): + def _onReceive(self, data: bytes): if self.isHid: # data contains the entire packet. - stream = StringIO(data) + stream = BytesIO(data) else: if data != ESCAPE: log.debugWarning("Ignoring byte before escape: %r" % data) @@ -161,14 +182,19 @@ def _onReceive(self, data): arg += stream.read(2) self._handleResponse(command, arg) - def _handleResponse(self, command, arg): + def _handleResponse(self, command: bytes, arg: bytes): if command == BAUM_CELL_COUNT: + # Assumption: BAUM_CELL_COUNT command has a single byte unsigned argument. + # Value range (0-255) self.numCells = ord(arg) elif command == BAUM_DEVICE_ID: # Short ids can be padded with either nulls or spaces. - self._deviceID = arg.rstrip("\0 ") + arg = arg.rstrip(b"\0 ") + # Assumption: all device IDs can be decoded with latin-1. + # If not, we wish to know about it, allow decode to raise. + self._deviceID = arg.decode("latin-1", errors="strict") elif command in KEY_NAMES: - arg = sum(ord(byte) << offset * 8 for offset, byte in enumerate(arg)) + arg = sum(byte << offset * 8 for offset, byte in enumerate(arg)) if arg < self._keysDown.get(command, 0): # Release. if not self._ignoreKeyReleases: @@ -199,9 +225,10 @@ def _handleResponse(self, command, arg): else: log.debugWarning("Unknown command {command!r}, arg {arg!r}".format(command=command, arg=arg)) - def display(self, cells): + def display(self, cells: List[int]): # cells will already be padded up to numCells. - self._sendRequest(BAUM_DISPLAY_DATA, "".join(chr(cell) for cell in cells)) + arg = bytes(cells) + self._sendRequest(BAUM_DISPLAY_DATA, arg) gestureMap = inputCore.GlobalGestureMap({ "globalCommands.GlobalCommands": { @@ -231,14 +258,14 @@ def __init__(self, model, keysDown): self.keysDown = dict(keysDown) self.keyNames = names = [] - for group, groupKeysDown in keysDown.iteritems(): + for group, groupKeysDown in keysDown.items(): if group == BAUM_BRAILLE_KEYS and len(keysDown) == 1 and not groupKeysDown & 0xfc: # This is braille input. # 0xfc covers command keys. The space bars are covered by 0x3. self.dots = groupKeysDown >> 8 self.space = groupKeysDown & 0x3 if group == BAUM_ROUTING_KEYS: - for index in xrange(braille.handler.display.numCells): + for index in range(braille.handler.display.numCells): if groupKeysDown & (1 << index): self.routingIndex = index names.append("routing") diff --git a/source/brailleDisplayDrivers/brailleNote.py b/source/brailleDisplayDrivers/brailleNote.py index 1daa540ef77..afa503fa991 100644 --- a/source/brailleDisplayDrivers/brailleNote.py +++ b/source/brailleDisplayDrivers/brailleNote.py @@ -8,16 +8,17 @@ USB, serial and bluetooth communications are supported. QWERTY keyboard input using basic terminal mode (no PC keyboard emulation) and scroll wheel are supported. See Brailliant B module for BrailleNote Touch support routines. -""" -from collections import OrderedDict -import itertools +""" + +from typing import List, Optional + import serial import braille import brailleInput import inputCore from logHandler import log import hwIo -import bdDetect +from hwIo import intToByte BAUD_RATE = 38400 TIMEOUT = 0.1 @@ -48,9 +49,9 @@ QT_CTRL = 0x4 QT_READ = 0x8 #Alt key -DESCRIBE_TAG = "\x1B?" -DISPLAY_TAG = "\x1bB" -ESCAPE = '\x1b' +ESCAPE = b'\x1b' +DESCRIBE_TAG = ESCAPE + b"?" +DISPLAY_TAG = ESCAPE + b"B" # Dots DOT_1 = 0x1 @@ -82,7 +83,7 @@ # Dots: # Backspace is dot7 and enter dot8 _dotNames = {} -for i in xrange(1,9): +for i in range(1,9): key = globals()["DOT_%d" % i] _dotNames[key] = "d%d" % i @@ -166,11 +167,12 @@ def _describe(self): log.debug("Not a braillenote") return False - def _onReceive(self, command): - command = ord(command) + def _onReceive(self, command: bytes): + assert len(command) == 1 + command: int = ord(command) if command == STATUS_TAG: arg = self._serial.read(2) - self.numCells = ord(arg[1]) + self.numCells = arg[1] return arg = self._serial.read(1) if not arg: @@ -178,13 +180,18 @@ def _onReceive(self, command): return # #5993: Read the buffer once more if a BrailleNote QT says it's got characters in its pipeline. if command == QT_MOD_TAG: - key = self._serial.read(2)[-1] - arg2 = _qtKeys.get(ord(key), key) + commandKey: int = self._serial.read(2)[-1] + arg2 = _qtKeys.get(commandKey, str(commandKey)) else: arg2 = None - self._dispatch(command, ord(arg), arg2 if arg2 is not None else None) + self._dispatch(command, ord(arg), arg2) - def _dispatch(self, command, arg, arg2=None): + def _dispatch( + self, + command: int, + arg: int, + arg2: Optional[str] = None + ): space = False if command == THUMB_KEYS_TAG: gesture = InputGesture(keys=arg) @@ -211,10 +218,11 @@ def _dispatch(self, command, arg, arg2=None): except inputCore.NoInputGestureAction: pass - def display(self, cells): + def display(self, cells: List[int]): # ESCAPE must be quoted because it is a control character - cells = [chr(cell).replace(ESCAPE, ESCAPE * 2) for cell in cells] - self._serial.write(DISPLAY_TAG + "".join(cells)) + cellBytesList = [intToByte(cell).replace(ESCAPE, ESCAPE * 2) for cell in cells] + cellBytesList.insert(0, DISPLAY_TAG) + self._serial.write(b"".join(cellBytesList)) gestureMap = inputCore.GlobalGestureMap({ "globalCommands.GlobalCommands": { @@ -248,14 +256,23 @@ def display(self, cells): class InputGesture(braille.BrailleDisplayGesture, brailleInput.BrailleInputGesture): source = BrailleDisplayDriver.name - def __init__(self, keys=None, dots=None, space=False, routing=None, wheel=None, qtMod=None, qtData=None): + def __init__( + self, + keys: Optional[int] = None, + dots: Optional[int] = None, + space: bool = False, + routing: Optional[int] = None, + wheel: Optional[int] = None, + qtMod: Optional[int] = None, + qtData:Optional[str] = None + ): super(braille.BrailleDisplayGesture, self).__init__() # Denotes if we're dealing with a QT model. self.qt = qtMod is not None # Handle thumb-keys and scroll wheel (wheel is for Apex BT). names = set() if keys is not None: - names.update(_keyNames[1 << i] for i in xrange(4) if (1 << i) & keys) + names.update(_keyNames[1 << i] for i in range(4) if (1 << i) & keys) elif wheel is not None: names.add(_scrWheel[wheel]) elif dots is not None: @@ -263,12 +280,14 @@ def __init__(self, keys=None, dots=None, space=False, routing=None, wheel=None, if space: self.space = space names.add(_keyNames[0]) - names.update(_dotNames[1 << i] for i in xrange(8) if (1 << i) & dots) + names.update(_dotNames[1 << i] for i in range(8) if (1 << i) & dots) elif routing is not None: self.routingIndex = routing names.add('routing') elif qtMod is not None: - names.update(_qtKeyNames[1 << i] for i in xrange(4) - if (1 << i) & qtMod) + names.update( + _qtKeyNames[1 << i] for i in range(4) + if (1 << i) & qtMod + ) names.add(qtData) self.id = "+".join(names) diff --git a/source/brailleDisplayDrivers/brailliantB.py b/source/brailleDisplayDrivers/brailliantB.py index 92cf354864c..fbf42f2b28b 100644 --- a/source/brailleDisplayDrivers/brailliantB.py +++ b/source/brailleDisplayDrivers/brailliantB.py @@ -5,6 +5,8 @@ #Copyright (C) 2012-2017 NV Access Limited, Babbage B.V. import time +from typing import List, Union + import serial import braille import inputCore @@ -12,6 +14,7 @@ import brailleInput import bdDetect import hwIo +from hwIo import intToByte, boolToByte TIMEOUT = 0.2 BAUD_RATE = 115200 @@ -21,18 +24,18 @@ INIT_RETRY_DELAY = 0.2 # Serial -HEADER = "\x1b" -MSG_INIT = "\x00" -MSG_INIT_RESP = "\x01" -MSG_DISPLAY = "\x02" -MSG_KEY_DOWN = "\x05" -MSG_KEY_UP = "\x06" +HEADER = b"\x1b" +MSG_INIT = b"\x00" +MSG_INIT_RESP = b"\x01" +MSG_DISPLAY = b"\x02" +MSG_KEY_DOWN = b"\x05" +MSG_KEY_UP = b"\x06" # HID -HR_CAPS = "\x01" -HR_KEYS = "\x04" -HR_BRAILLE = "\x05" -HR_POWEROFF = "\x07" +HR_CAPS = b"\x01" +HR_KEYS = b"\x04" +HR_BRAILLE = b"\x05" +HR_POWEROFF = b"\x07" KEY_NAMES = { 1: "power", # Brailliant BI 32, 40 and 80. @@ -76,6 +79,7 @@ SPACE_KEY = 10 class BrailleDisplayDriver(braille.BrailleDisplayDriver): + _dev: Union[hwIo.Serial, hwIo.Hid] name = "brailliantB" # Translators: The name of a series of braille displays. description = _("HumanWare Brailliant BI/B series / BrailleNote Touch") @@ -103,7 +107,7 @@ def __init__(self, port="auto"): # The Brailliant can fail to init if you try immediately after connecting. time.sleep(DELAY_AFTER_CONNECT) # Sometimes, a few attempts are needed to init successfully. - for attempt in xrange(INIT_ATTEMPTS): + for attempt in range(INIT_ATTEMPTS): if attempt > 0: # Not the first attempt time.sleep(INIT_RETRY_DELAY) # Delay before next attempt. self._initAttempt() @@ -126,10 +130,10 @@ def __init__(self, port="auto"): def _initAttempt(self): if self.isHid: try: - data = self._dev.getFeature(HR_CAPS) + data: bytes = self._dev.getFeature(HR_CAPS) except WindowsError: return # Fail! - self.numCells = ord(data[24]) + self.numCells = data[24] else: # This will cause the display to return the number of cells. # The _serOnReceive callback will see this and set self.numCells. @@ -144,14 +148,23 @@ def terminate(self): # If it doesn't, we may not be able to re-open it later. self._dev.close() - def _serSendMessage(self, msgId, payload=""): - if isinstance(payload, (int, bool)): - payload = chr(payload) - self._dev.write("{header}{id}{length}{payload}".format( - header=HEADER, id=msgId, - length=chr(len(payload)), payload=payload)) + def _serSendMessage(self, msgId: bytes, payload: Union[bytes, int, bool] = b""): + if not isinstance(payload, bytes): + if isinstance(payload, int): + payload: bytes = intToByte(payload) + elif isinstance(payload, bool): + payload: bytes = boolToByte(payload) + else: + raise TypeError("Expected arg 'payload' to be of type 'bytes, int, or bool'") + data = b''.join([ + HEADER, + msgId, + intToByte(len(payload)), + payload + ]) + self._dev.write(data) - def _serOnReceive(self, data): + def _serOnReceive(self, data: bytes): if data != HEADER: log.debugWarning("Ignoring byte before header: %r" % data) return @@ -160,13 +173,13 @@ def _serOnReceive(self, data): payload = self._dev.read(length) self._serHandleResponse(msgId, payload) - def _serHandleResponse(self, msgId, payload): + def _serHandleResponse(self, msgId: bytes, payload: bytes): if msgId == MSG_INIT_RESP: - if ord(payload[0]) != 0: + if payload[0] != 0: # Communication not allowed. log.debugWarning("Display at %r reports communication not allowed" % self._dev.port) return - self.numCells = ord(payload[2]) + self.numCells = payload[2] elif msgId == MSG_KEY_DOWN: payload = ord(payload) @@ -182,11 +195,12 @@ def _serHandleResponse(self, msgId, payload): else: log.debugWarning("Unknown message: id {id!r}, payload {payload!r}".format(id=msgId, payload=payload)) - def _hidOnReceive(self, data): - rId = data[0] + def _hidOnReceive(self, data: bytes): + # Indexing bytes gives an int, where slicing gives a byte, so 0:1 will return a bytes of length 1 + rId: bytes = data[0:1] if rId == HR_KEYS: - keys = data[1:].split("\0", 1)[0] - keys = {ord(key) for key in keys} + keys = data[1:].split(b"\x00", 1)[0] + keys = {keyInt for keyInt in keys} if len(keys) > len(self._keysDown): # Press. This begins a new key combination. self._ignoreKeyReleases = False @@ -210,18 +224,22 @@ def _handleKeyRelease(self): # so they should be ignored. self._ignoreKeyReleases = True - def display(self, cells): + def display(self, cells: List[int]): # cells will already be padded up to numCells. - cells = "".join(chr(cell) for cell in cells) + cellBytes = b"".join(intToByte(cell) for cell in cells) if self.isHid: - outputReport=("{id}" - "\x01\x00" # Module 1, offset 0 - "{length}{cells}" - .format(id=HR_BRAILLE, length=chr(self.numCells), cells=cells)) - #: Humanware HID devices require the use of HidD_SetOutputReport when sending data to the device via HID, as WriteFile seems to block forever or fail to reach the device at all. + outputReport: bytes = b"".join([ + HR_BRAILLE, # id + b"\x01\x00", # Module 1, offset 0 + intToByte(self.numCells), # length + cellBytes + ]) + #: Humanware HID devices require the use of HidD_SetOutputReport when + # sending data to the device via HID, as WriteFile seems to block forever + # or fail to reach the device at all. self._dev.setOutputReport(outputReport) else: - self._serSendMessage(MSG_DISPLAY, cells) + self._serSendMessage(MSG_DISPLAY, cellBytes) gestureMap = inputCore.GlobalGestureMap({ "globalCommands.GlobalCommands": { diff --git a/source/brailleDisplayDrivers/brltty.py b/source/brailleDisplayDrivers/brltty.py index 777cf2737f1..6a998cfbb8c 100644 --- a/source/brailleDisplayDrivers/brltty.py +++ b/source/brailleDisplayDrivers/brltty.py @@ -2,19 +2,22 @@ #A part of NonVisual Desktop Access (NVDA) #This file is covered by the GNU General Public License. #See the file COPYING for more details. -#Copyright (C) 2008-2010 James Teh +#Copyright (C) 2008-2019 NV Access Limited, Babbage B.V> import time import wx import braille from logHandler import log import inputCore +from typing import List try: import brlapi - BRLAPI_CMD_KEYS = dict((code, name[8:].lower()) - for name, code in brlapi.__dict__.iteritems() if name.startswith("KEY_CMD_")) + BRLAPI_CMD_KEYS = { + code: name[8:].lower() + for name, code in vars(brlapi).items() if name.startswith("KEY_CMD_") + } except ImportError: - pass + brlapi = None KEY_CHECK_INTERVAL = 50 @@ -26,12 +29,7 @@ class BrailleDisplayDriver(braille.BrailleDisplayDriver): @classmethod def check(cls): - try: - brlapi - return True - except NameError: - pass - return False + return bool(brlapi) def __init__(self): super(BrailleDisplayDriver, self).__init__() @@ -41,7 +39,7 @@ def __init__(self): self._keyCheckTimer.Start(KEY_CHECK_INTERVAL) # BRLTTY simulates key presses for braille typing keys, so let BRLTTY handle them. # NVDA may eventually implement this itself, but there's no reason to deny BRLTTY users this functionality in the meantime. - self._con.ignoreKeys(brlapi.rangeType_type, (long(brlapi.KEY_TYPE_SYM),)) + self._con.ignoreKeys(brlapi.rangeType_type, (brlapi.KEY_TYPE_SYM,)) def terminate(self): super(BrailleDisplayDriver, self).terminate() @@ -61,13 +59,16 @@ def terminate(self): def _get_numCells(self): return self._con.displaySize[0] - def display(self, cells): - cells = "".join(chr(cell) for cell in cells) + def display(self, cells: List[int]): + cells = bytes(cells) # HACK: Temporarily work around a bug which causes brltty to freeze if data is written while there are key presses waiting. # Simply consume and act upon any waiting key presses. self._handleKeyPresses() self._con.writeDots(cells) + def _get_driverName(self): + return self._con.driverName.decode() + def _handleKeyPresses(self): while True: try: @@ -86,7 +87,9 @@ def _onKeyPress(self, key): argument = key["argument"] if keyType == brlapi.KEY_TYPE_CMD: try: - inputCore.manager.executeGesture(InputGesture(command, argument)) + inputCore.manager.executeGesture( + InputGesture(self.driverName, command, argument) + ) except inputCore.NoInputGestureAction: pass @@ -104,8 +107,9 @@ class InputGesture(braille.BrailleDisplayGesture): source = BrailleDisplayDriver.name - def __init__(self, command, argument): + def __init__(self, model, command, argument): super(InputGesture, self).__init__() + self.model = model self.id = BRLAPI_CMD_KEYS[command] if command == brlapi.KEY_CMD_ROUTE: self.routingIndex = argument diff --git a/source/brailleDisplayDrivers/ecoBraille.py b/source/brailleDisplayDrivers/ecoBraille.py index ae1b88686de..07902783a92 100644 --- a/source/brailleDisplayDrivers/ecoBraille.py +++ b/source/brailleDisplayDrivers/ecoBraille.py @@ -4,10 +4,12 @@ #This file is covered by the GNU General Public License. #See the file COPYING for more details. #Copyright (C) 2014-2015 ONCE-CIDAT +from typing import List, Tuple import inputCore import braille import hwPortUtils +from hwIo import intToByte from collections import OrderedDict from logHandler import log import serial @@ -67,41 +69,52 @@ class ecoTypes: TECO_40 = 40 TECO_80 = 80 -def eco_in_init(dev): - msg = dev.read(9) - if (len(msg) < 9): +def eco_in_init(dev: serial.Serial) -> int: + msg: bytes = dev.read(9) + if len(msg) < 9: return ecoTypes.TECO_80 # Needed to restart NVDA with Ecoplus - msg = struct.unpack('BBBBBBBBB', msg) # Command message from EcoBraille is something like that: # 0x10 0x02 TT AA BB CC DD 0x10 0x03 # where TT can be 0xF1 (identification message) or 0x88 (command pressed in the line) # If TT = 0xF1, then the next byte (AA) give us the type of EcoBraille line (ECO 80, 40 or 20) - if (msg[0] == 0x10) and (msg[1] == 0x02) and (msg[7] == 0x10) and (msg[8] == 0x03): - if msg[2] == 0xf1: # Initial message - if (msg[3] == 0x80): + if ( + (msg[0] == 0x10) + and (msg[1] == 0x02) + and (msg[7] == 0x10) + and (msg[8] == 0x03) + ): + if msg[2] == 0xf1: # Initial message + if msg[3] == 0x80: return ecoTypes.TECO_80 - if (msg[3] == 0x40): + if msg[3] == 0x40: return ecoTypes.TECO_40 - if (msg[3] == 0x20): + if msg[3] == 0x20: return ecoTypes.TECO_20 return ecoTypes.TECO_80 # Needed for changing Braille Settings with Ecoplus -def eco_in(dev): - msg = dev.read(9) +def eco_in(dev: serial.Serial) -> int: try: - msg = struct.unpack('BBBBBBBBB', msg) + msg: bytes = dev.read(9) except: + log.debug("unpacking error", exc_info=True) return 0 # Command message from EcoBraille is something like that: # 0x10 0x02 TT AA BB CC DD 0x10 0x03 # where TT can be 0xF1 (identification message) or 0x88 (command pressed in the line) # If TT = 0x88 then AA, BB, CC and DD give us the command pressed in the braille line - if (msg[0] == 0x10) and (msg[1] == 0x02) and (msg[7] == 0x10) and (msg[8] == 0x03): - if msg[2] == 0x88: # command pressed message - return (msg[3] << 24) | (msg[4] << 16) | (msg[5] << 8) | msg[6] + if( + (msg[0] == 0x10) + and (msg[1] == 0x02) + and (msg[7] == 0x10) + and (msg[8] == 0x03) + and (msg[2] == 0x88) # command pressed message + ): + return (msg[3] << 24) | (msg[4] << 16) | (msg[5] << 8) | msg[6] return 0 -output_dots_map=[0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, + +output_dots_map: List[int] = [ + 0x00, 0x10, 0x20, 0x30, 0x40, 0x50, 0x60, 0x70, 0x01, 0x11, 0x21, 0x31, 0x41, 0x51, 0x61, 0x71, 0x02, 0x12, 0x22, 0x32, 0x42, 0x52, 0x62, 0x72, 0x03, 0x13, 0x23, 0x33, 0x43, 0x53, 0x63, 0x73, @@ -132,19 +145,20 @@ def eco_in(dev): 0x8C, 0x9C, 0xAC, 0xBC, 0xCC, 0xDC, 0xEC, 0xFC, 0x8D, 0x9D, 0xAD, 0xBD, 0xCD, 0xDD, 0xED, 0xFD, 0x8E, 0x9E, 0xAE, 0xBE, 0xCE, 0xDE, 0xEE, 0xFE, - 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF] + 0x8F, 0x9F, 0xAF, 0xBF, 0xCF, 0xDF, 0xEF, 0xFF +] + -def eco_out(cells): +def eco_out(cells: List[int]) -> bytes: # Messages sends to EcoBraille display are something like that: # 0x10 0x02 0xBC message 0x10 0x03 - ret = [] - ret.append(struct.pack('BBB', 0x10, 0x02, 0xBC)) + ret = bytearray(b"\x10\x02\xBC") + ret.extend(b"\00" * 5) # Leave status cells blank - ret.append(struct.pack('BBBBB', 0x00, 0x00, 0x00, 0x00, 0x00)) - for d in cells: - ret.append(struct.pack('B', output_dots_map[d])) - ret.append(struct.pack('BB', 0x10, 0x03)) - return "".join(ret) + ret.extend(output_dots_map[c] for c in cells) + ret.extend(b"\x10\x03") + return bytes(ret) + class BrailleDisplayDriver(braille.BrailleDisplayDriver): """ EcoBraille display driver. @@ -167,17 +181,17 @@ def getPossiblePorts(cls): def __init__(self, port): super(BrailleDisplayDriver, self).__init__() - self._port = (port) + self._port = port # Try to open port self._dev = serial.Serial(self._port, baudrate = 19200, bytesize = serial.EIGHTBITS, parity = serial.PARITY_NONE, stopbits = serial.STOPBITS_ONE) # Use a longer timeout when waiting for initialisation. self._dev.timeout = self._dev.write_timeout = 2.7 - self._ecoType = eco_in_init(self._dev) + self._ecoType = eco_in_init(self._dev) # Use a shorter timeout hereafter. self._dev.timeout = self._dev.write_timeout = TIMEOUT # Always send the protocol answer. - self._dev.write("\x61\x10\x02\xf1\x57\x57\x57\x10\x03") - self._dev.write("\x10\x02\xbc\x00\x00\x00\x00\x00\x10\x03") + self._dev.write(b"\x61\x10\x02\xf1\x57\x57\x57\x10\x03") + self._dev.write(b"\x10\x02\xbc\x00\x00\x00\x00\x00\x10\x03") # Start keyCheckTimer. self._readTimer = wx.PyTimer(self._handleResponses) self._readTimer.Start(READ_INTERVAL) @@ -185,7 +199,7 @@ def __init__(self, port): def terminate(self): super(BrailleDisplayDriver, self).terminate() try: - self._dev.write("\x61\x10\x02\xf1\x57\x57\x57\x10\x03") + self._dev.write(b"\x61\x10\x02\xf1\x57\x57\x57\x10\x03") self._readTimer.Stop() self._readTimer = None finally: @@ -195,11 +209,11 @@ def terminate(self): def _get_numCells(self): return self._ecoType - def display(self, cells): + def display(self, cells: List[int]): try: self._dev.write(eco_out(cells)) except: - pass + log.debug("error writing to the display", exc_info=True) def _handleResponses(self): if self._dev.in_waiting: @@ -208,9 +222,9 @@ def _handleResponses(self): try: self._handleResponse(command) except KeyError: - pass + log.debug("error handling responses", exc_info=True) - def _handleResponse(self, command): + def _handleResponse(self, command: int): if command in (ECO_KEY_STATUS1, ECO_KEY_STATUS2, ECO_KEY_STATUS3, ECO_KEY_STATUS4): # Nothing to do with the status cells return 0 @@ -250,6 +264,7 @@ def _handleResponse(self, command): } }) + class InputGestureKeys(braille.BrailleDisplayGesture): source = BrailleDisplayDriver.name @@ -257,6 +272,7 @@ def __init__(self, keys): super(InputGestureKeys, self).__init__() self.id = keyNames[keys] + class InputGestureRouting(braille.BrailleDisplayGesture): source = BrailleDisplayDriver.name diff --git a/source/brailleDisplayDrivers/eurobraille.py b/source/brailleDisplayDrivers/eurobraille.py index 1081da47e4a..dfbbaf3e06c 100644 --- a/source/brailleDisplayDrivers/eurobraille.py +++ b/source/brailleDisplayDrivers/eurobraille.py @@ -6,7 +6,9 @@ #Copyright (C) 2017-2019 NV Access Limited, Babbage B.V., Eurobraille from collections import OrderedDict, defaultdict -from cStringIO import StringIO +from typing import Dict, Any, List, Union + +from io import BytesIO import serial import bdDetect import braille @@ -14,6 +16,7 @@ from logHandler import log import brailleInput import hwIo +from hwIo import intToByte, boolToByte from baseObject import AutoPropertyObject, ScriptableObject import wx import threading @@ -34,7 +37,7 @@ EB_KEY_INTERACTIVE_SINGLE_CLICK = b'\x01' EB_KEY_INTERACTIVE_REPETITION = b'\x02' EB_KEY_INTERACTIVE_DOUBLE_CLICK = b'\x03' -EB_KEY_BRAILLE='B' # 0x42 +EB_KEY_BRAILLE=b'B' # 0x42 EB_KEY_COMMAND = b'C' # 0x43 EB_KEY_QWERTY = b'Z' # 0x5a EB_KEY_USB_HID_MODE = b'U' # 0x55 @@ -53,6 +56,10 @@ EB_VISU = b'V' # 0x56 EB_VISU_DOT = b'D' # 0x44 +# The eurobraille protocol uses real number characters as boolean values, so 0 (0x30) and 1 (0x31) +EB_FALSE = b'0' # 0x30 +EB_TRUE = b'1' # 0x31 + KEYS_STICK = OrderedDict({ 0x10000: "joystick1Up", 0x20000: "joystick1Down", @@ -127,11 +134,16 @@ 0x11:"Esytime evo 32 standard", } -def bytesToInt(bytes): - """Converts a basestring to its integral equivalent.""" - return int(bytes.encode('hex'), 16) + +def bytesToInt(byteData: bytes): + """Converts bytes to its integral equivalent.""" + return int.from_bytes(byteData, byteorder="big", signed=False) + class BrailleDisplayDriver(braille.BrailleDisplayDriver, ScriptableObject): + _dev: hwIo.IoBase + # Used to for error checking. + _awaitingFrameReceipts: Dict[int, Any] name = "eurobraille" # Translators: Names of braille displays. description = _("Eurobraille Esys/Esytime/Iris displays") @@ -155,7 +167,7 @@ def __init__(self, port="Auto"): self._frame = 0x20 self._frameLock = threading.Lock() self._hidKeyboardInput = False - self._hidInputBuffer = "" + self._hidInputBuffer = b"" for portType, portId, port, portInfo in self._getTryPorts(port): # At this point, a port bound to this display has been found. @@ -184,11 +196,11 @@ def __init__(self, port="Auto"): log.debugWarning("Error while connecting to port %r"%port, exc_info=True) continue - for i in xrange(3): + for i in range(3): # Request device identification self._sendPacket(EB_SYSTEM, EB_SYSTEM_IDENTITY) # Make sure visualisation packets are disabled, as we ignore them anyway. - self._sendPacket(EB_VISU, EB_VISU_DOT, '0') + self._sendPacket(EB_VISU, EB_VISU_DOT, EB_FALSE) # A device identification results in multiple packets. # Make sure we've received everything before we continue while self._dev.waitForRead(self.timeout*2): @@ -218,53 +230,60 @@ def terminate(self): self._dev = None self._deviceData.clear() - def _onReceive(self, data): + def _prepFirstByteStreamAndData( + self, + data: bytes + ) -> (bytes, Union[BytesIO, hwIo.IoBase], bytes): if self.isHid: # data contains the entire packet. # HID Packets start with 0x00. - byte0 = data[0] - assert byte0=="\x00", "byte 0 is %r"%byte0 + byte0 = data[0:1] + assert byte0 == b"\x00", "byte 0 is %r" % byte0 # Check whether there is an incomplete packet in the buffer if self._hidInputBuffer: data = self._hidInputBuffer + data[1:] - self._hidInputBuffer = "" - byte1 = data[1] - stream = StringIO(data) + self._hidInputBuffer = b"" + byte1 = data[1:2] + stream = BytesIO(data) stream.seek(2) - else: - byte1= data - stream = self._dev + return byte1, stream, data + else: # is serial + return data, self._dev, data + + def _onReceive(self, data: bytes): + byte1, stream, data = self._prepFirstByteStreamAndData(data) + if byte1 == ACK: frame = ord(stream.read(1)) self._handleAck(frame) elif byte1 == STX: - length = bytesToInt(stream.read(2))-2 # lenght includes the lenght itself - packet = stream.read(length) - if self.isHid and not stream.read(1)==ETX: + length = bytesToInt(stream.read(2)) - 2 # length includes the length itself + packet: bytes = stream.read(length) + if self.isHid and not stream.read(1) == ETX: # Incomplete packet self._hidInputbuffer = data return - packetType = packet[0] - packetSubType = packet[1] - packetData = packet[2:] if length>2 else b"" - if packetType==EB_SYSTEM: + packetType: bytes = packet[0:1] + packetSubType: bytes = packet[1:2] + packetData: bytes = packet[2:] if length > 2 else b"" + if packetType == EB_SYSTEM: self._handleSystemPacket(packetSubType, packetData) - elif packetType==EB_MODE: - if packetSubType == EB_MODE_DRIVER: + elif packetType == EB_MODE: + if packetSubType == EB_MODE_DRIVER: log.debug("Braille display switched to driver mode, updating display...") braille.handler.update() - elif packetSubType == EB_MODE_INTERNAL: + elif packetSubType == EB_MODE_INTERNAL: log.debug("Braille display switched to internal mode") - elif packetType==EB_KEY: + elif packetType == EB_KEY: self._handleKeyPacket(packetSubType, packetData) - elif packetType==EB_IRIS_TEST and packetSubType==EB_IRIS_TEST_sub: + elif packetType == EB_IRIS_TEST and packetSubType == EB_IRIS_TEST_sub: # Ping command sent by Iris every two seconds, send it back on the main thread. # This means that, if the main thread is frozen, Iris will be notified of this. log.debug("Received ping from Iris braille display") wx.CallAfter(self._sendPacket, packetType, packetSubType, packetData) - elif packetType==EB_VISU: + elif packetType == EB_VISU: log.debug("Ignoring visualisation packet") - elif packetType==EB_ENCRYPTION_KEY: + elif packetType == EB_ENCRYPTION_KEY: log.debug("Ignoring encryption key packet") else: log.debug("Ignoring packet: type %r, subtype %r, data %r"%( @@ -273,9 +292,9 @@ def _onReceive(self, data): packetData )) - def _handleAck(self, frame): + def _handleAck(self, frame: int): try: - super(BrailleDisplayDriver,self)._handleAck() + super(BrailleDisplayDriver, self)._handleAck() except NotImplementedError: log.debugWarning("Received ACK for frame %d while ACK handling is disabled"%frame) else: @@ -284,51 +303,52 @@ def _handleAck(self, frame): except KeyError: log.debugWarning("Received ACK for unregistered frame %d"%frame) - def _handleSystemPacket(self, type, data): - if type==EB_SYSTEM_TYPE: + def _handleSystemPacket(self, packetType: bytes, data: bytes): + if packetType == EB_SYSTEM_TYPE: deviceType = ord(data) self.deviceType = DEVICE_TYPES[deviceType] - if 0x01<=deviceType<=0x06: # Iris + if 0x01 <= deviceType <= 0x06: # Iris self.keys = KEYS_IRIS - elif 0x07<=deviceType<=0x0d: # Esys + elif 0x07 <= deviceType <= 0x0d: # Esys self.keys = KEYS_ESYS - elif 0x0e<=deviceType<=0x11: # Esitime + elif 0x0e <= deviceType <= 0x11: # Esitime self.keys = KEYS_ESITIME else: log.debugWarning("Unknown device identifier %r"%data) - elif type==EB_SYSTEM_DISPLAY_LENGTH: + elif packetType == EB_SYSTEM_DISPLAY_LENGTH: self.numCells = ord(data) - elif type==EB_SYSTEM_FRAME_LENGTH: + elif packetType == EB_SYSTEM_FRAME_LENGTH: self._frameLength = bytesToInt(data) - elif type==EB_SYSTEM_PROTOCOL and self.isHid: - protocol = data.rstrip("\x00 ") + elif packetType == EB_SYSTEM_PROTOCOL and self.isHid: + protocol = data.rstrip(b"\x00 ") try: version = float(protocol[:4]) except ValueError: pass else: - self.receivesAckPackets = version>=3.0 - elif type==EB_SYSTEM_IDENTITY: - return # End of system information - self._deviceData[type]=data.rstrip("\x00 ") + self.receivesAckPackets = version >= 3.0 + elif packetType == EB_SYSTEM_IDENTITY: + return # End of system information + self._deviceData[packetType] = data.rstrip(b"\x00 ") - def _handleKeyPacket(self, group, data): + def _handleKeyPacket(self, group: bytes, data: bytes): if group == EB_KEY_USB_HID_MODE: - self._hidKeyboardInput = bool(int(data)) + assert data in [EB_TRUE, EB_FALSE] + self._hidKeyboardInput = EB_TRUE == data return if group == EB_KEY_QWERTY: log.debug("Ignoring Iris AZERTY/QWERTY input") return - if group == EB_KEY_INTERACTIVE and data[0]==EB_KEY_INTERACTIVE_REPETITION: - log.debug("Ignoring routing key %d repetition"%(ord(data[1])-1)) + if group == EB_KEY_INTERACTIVE and data[0:1] == EB_KEY_INTERACTIVE_REPETITION: + log.debug("Ignoring routing key %d repetition" % (data[1] - 1)) return arg = bytesToInt(data) - if arg==self.keysDown[group]: + if arg == self.keysDown[group]: log.debug("Ignoring key repetition") return self.keysDown[group] |= arg isIris = self.deviceType.startswith("Iris") - if not isIris and group == EB_KEY_COMMAND and arg>=self.keysDown[group]: + if not isIris and group == EB_KEY_COMMAND and arg >= self.keysDown[group]: # Started a gesture including command keys self._ignoreCommandKeyReleases = False else: @@ -337,55 +357,68 @@ def _handleKeyPacket(self, group, data): inputCore.manager.executeGesture(InputGesture(self)) except inputCore.NoInputGestureAction: pass - self._ignoreCommandKeyReleases = not isIris and (group == EB_KEY_COMMAND or self.keysDown[EB_KEY_COMMAND]>0) + self._ignoreCommandKeyReleases = not isIris and (group == EB_KEY_COMMAND or self.keysDown[EB_KEY_COMMAND] > 0) if not isIris and group == EB_KEY_COMMAND: self.keysDown[group] = arg else: del self.keysDown[group] - def _sendPacket(self, packetType, packetSubType, packetData=b""): - packetSize=len(packetData)+4 - packet=[ - STX, - chr((packetSize>>8)&0xff), - chr(packetSize&0xff), - packetType, - packetSubType, - packetData, - ETX - ] + def _sendPacket(self, packetType: bytes, packetSubType: bytes, packetData: bytes = b""): + packetSize = len(packetData)+4 + packetBytes = bytearray( + b"".join([ + STX, + packetSize.to_bytes(2, "big", signed=False), + packetType, + packetSubType, + packetData, + ETX + ])) if self.receivesAckPackets: with self._frameLock: frame = self._frame - packet.insert(-1,chr(frame)) - self._awaitingFrameReceipts[frame] = packet - self._frame = frame+1 if frame<0x7F else 0x20 - packetStr = b"".join(packet) + # Assumption: frame will only ever be 1 byte, otherwise consider byte order + packetBytes.insert(-1, frame) + self._awaitingFrameReceipts[frame] = packetBytes + self._frame = frame+1 if frame < 0x7F else 0x20 + packetData = bytes(packetBytes) if self.isHid: - self._sendHidPacket(packetStr) + self._sendHidPacket(packetData) else: - self._dev.write(packetStr) + self._dev.write(packetData) - def _sendHidPacket(self, packet): + def _sendHidPacket(self, packet: bytes): assert self.isHid - blockSize = self._dev._writeSize-1 + blockSize = self._dev._writeSize - 1 # When the packet length exceeds C{blockSize}, the packet is split up into several block packets. # These blocks are of size C{blockSize}. - for offset in xrange(0, len(packet), blockSize): + for offset in range(0, len(packet), blockSize): bytesToWrite = packet[offset:(offset+blockSize)] - hidPacket = b"\x00"+bytesToWrite+b"\x55"*(blockSize-len(bytesToWrite)) + hidPacket = b"".join([ + b"\x00", + bytesToWrite, + b"\x55" * (blockSize - len(bytesToWrite)) # padding + ]) self._dev.write(hidPacket) - def display(self, cells): + def display(self, cells: List[int]): # cells will already be padded up to numCells. - self._sendPacket(EB_BRAILLE_DISPLAY, EB_BRAILLE_DISPLAY_STATIC, b"".join(chr(cell) for cell in cells)) + self._sendPacket( + packetType=EB_BRAILLE_DISPLAY, + packetSubType=EB_BRAILLE_DISPLAY_STATIC, + packetData=bytes(cells) + ) def _get_hidKeyboardInput(self): return self._hidKeyboardInput - def _set_hidKeyboardInput(self, state): - self._sendPacket(EB_KEY, EB_KEY_USB_HID_MODE, str(int(state))) - for i in xrange(3): + def _set_hidKeyboardInput(self, state: bool): + self._sendPacket( + packetType=EB_KEY, + packetSubType=EB_KEY_USB_HID_MODE, + packetData=EB_TRUE if state else EB_FALSE + ) + for i in range(3): self._dev.waitForRead(self.timeout) if state is self._hidKeyboardInput: break @@ -549,14 +582,14 @@ def __init__(self, display): self.model = display.deviceType.lower().split(" ")[0] keysDown = dict(display.keysDown) self.keyNames = names = [] - for group, groupKeysDown in keysDown.iteritems(): + for group, groupKeysDown in keysDown.items(): if group == EB_KEY_BRAILLE: - if sum(keysDown.itervalues())==groupKeysDown and not groupKeysDown & 0x100: + if sum(keysDown.values())==groupKeysDown and not groupKeysDown & 0x100: # This is braille input. # 0x1000 is backspace, 0x2000 is space self.dots = groupKeysDown & 0xff self.space = groupKeysDown & 0x200 - names.extend("dot%d" % (i+1) for i in xrange(8) if (groupKeysDown &0xff) & (1 << i)) + names.extend("dot%d" % (i+1) for i in range(8) if (groupKeysDown &0xff) & (1 << i)) if groupKeysDown & 0x200: names.append("space") if groupKeysDown & 0x100: @@ -565,7 +598,7 @@ def __init__(self, display): self.routingIndex = (groupKeysDown & 0xff)-1 names.append("doubleRouting" if groupKeysDown>>8 ==ord(EB_KEY_INTERACTIVE_DOUBLE_CLICK) else "routing") if group == EB_KEY_COMMAND: - for key, keyName in display.keys.iteritems(): + for key, keyName in display.keys.items(): if groupKeysDown & key: # This key is pressed names.append(keyName) diff --git a/source/brailleDisplayDrivers/freedomScientific.py b/source/brailleDisplayDrivers/freedomScientific.py index 49eb851bd1a..cf53d392c79 100755 --- a/source/brailleDisplayDrivers/freedomScientific.py +++ b/source/brailleDisplayDrivers/freedomScientific.py @@ -10,8 +10,10 @@ A c(lang) reference implementation is available in brltty. """ -from six import BytesIO, int2byte +from io import BytesIO import itertools +from typing import List, Optional + import braille import inputCore from baseObject import ScriptableObject @@ -19,6 +21,7 @@ import bdDetect import brailleInput import hwIo +from hwIo import intToByte import serial @@ -121,9 +124,9 @@ def isoDot(number): return 1 << (number - 1) outputTable = [0] * TRANSLATION_TABLE_SIZE - for byte in xrange(TRANSLATION_TABLE_SIZE): + for byte in range(TRANSLATION_TABLE_SIZE): cell = 0 - for dot in xrange(DOTS_TABLE_SIZE): + for dot in range(DOTS_TABLE_SIZE): if byte & isoDot(dot + 1): cell |= dotsTable[dot] outputTable[byte] = cell @@ -182,16 +185,16 @@ def __init__(self, port="auto"): self._keyBits = 0 self._extendedKeyBits = 0 self._ignoreKeyReleases = False - self._model = None - self._manufacturer = None - self._firmwareVersion = None + self._model: Optional[str] = None + self._manufacturer: Optional[str] = None + self._firmwareVersion: Optional[str] = None self.translationTable = None self.leftWizWheelActionCycle = itertools.cycle(self.wizWheelActions) - action = self.leftWizWheelActionCycle.next() + action = next(self.leftWizWheelActionCycle) self.gestureMap.add("br(freedomScientific):leftWizWheelUp", *action[1]) self.gestureMap.add("br(freedomScientific):leftWizWheelDown", *action[2]) self.rightWizWheelActionCycle = itertools.cycle(self.wizWheelActions) - action = self.rightWizWheelActionCycle.next() + action = next(self.rightWizWheelActionCycle) self.gestureMap.add("br(freedomScientific):rightWizWheelUp", *action[1]) self.gestureMap.add("br(freedomScientific):rightWizWheelDown", *action[2]) super(BrailleDisplayDriver, self).__init__() @@ -205,7 +208,6 @@ def __init__(self, port="auto"): epIn=1, epOut=0, onReceive=self._onReceive, - writeSize=0, onReceiveSize=56 ) else: @@ -223,7 +225,7 @@ def __init__(self, port="auto"): # Send an identification request self._sendPacket(FS_PKT_QUERY) - for _i in xrange(3): + for _i in range(3): self._dev.waitForRead(self.timeout) if self.numCells and self._model: break @@ -252,33 +254,38 @@ def terminate(self): # If it doesn't, we may not be able to re-open it later. self._dev.close() - def _sendPacket(self, packetType, arg1=FS_BYTE_NULL, arg2=FS_BYTE_NULL, arg3=FS_BYTE_NULL, data=FS_DATA_EMPTY): + def _sendPacket( + self, + packetType: bytes, + arg1: bytes = FS_BYTE_NULL, + arg2: bytes = FS_BYTE_NULL, + arg3: bytes = FS_BYTE_NULL, + data: bytes = FS_DATA_EMPTY + ): """Send a packet to the display - @param packetType: Type of packet (first byte), use one of the FS_PKT constants - @type packetType: str @param arg1: First argument (second byte of packet) - @type arg1: str @param arg2: Second argument (third byte of packet) - @type arg2: str @param arg3: Third argument (fourth byte of packet) - @type arg3: str - @param data: Data to send if this is an extended packet, required checksum will be added automatically - @type data: str + @param data: Data to send if this is an extended packet, required checksum will + be added automatically """ - def handleArg(arg): - if type(arg) == int: - return int2byte(arg) - return arg + def handleArg(arg: bytes) -> bytes: + if isinstance(arg, bytes): + return arg + else: + raise TypeError("Expected arg to be bytes") + arg1 = handleArg(arg1) arg2 = handleArg(arg2) arg3 = handleArg(arg3) - packet = [packetType, arg1, arg2, arg3, data] + packet = b"".join([packetType, arg1, arg2, arg3, data]) if data: - packet.append(int2byte(BrailleDisplayDriver._calculateChecksum("".join(packet)))) - self._dev.write("".join(packet)) + checksum = BrailleDisplayDriver._calculateChecksum(packet) + packet += intToByte(checksum) + self._dev.write(packet) - def _onReceive(self, data): + def _onReceive(self, data: bytes): """Event handler when data from the display is received Formats a packet of four bytes in a packet type and three arguments. @@ -287,28 +294,32 @@ def _onReceive(self, data): """ if self.isUsb: data = BytesIO(data) - packetType = data.read(1) + packetType: bytes = data.read(1) else: - packetType = data + packetType: bytes = data data = self._dev - arg1 = data.read(1) - arg2 = data.read(1) - arg3 = data.read(1) + arg1: bytes = data.read(1) + arg2: bytes = data.read(1) + arg3: bytes = data.read(1) log.debug("Got packet of type %r with args: %r %r %r", packetType, arg1, arg2, arg3) # Info and extended key responses are the only packets with payload and checksum if packetType in (FS_PKT_INFO, FS_PKT_EXT_KEY): - length = ord(arg1) - payload = data.read(length) - checksum = ord(data.read(1)) - calculatedChecksum = BrailleDisplayDriver._calculateChecksum(packetType + arg1 + arg2 + arg3 + payload) + length: int = ord(arg1) + payload: bytes = data.read(length) + checksum: int = ord(data.read(1)) + calculatedChecksum = BrailleDisplayDriver._calculateChecksum( + packetType + arg1 + arg2 + arg3 + payload + ) assert calculatedChecksum == checksum, "Checksum mismatch, expected %s but got %s" % (checksum, payload[-1]) else: payload = FS_DATA_EMPTY self._handlePacket(packetType, arg1, arg2, arg3, payload) - def _handlePacket(self, packetType, arg1, arg2, arg3, payload): + def _handlePacket( + self, packetType: bytes, arg1: bytes, arg2: bytes, arg3: bytes, payload: bytes + ): """Handle a packet from the device" The following packet types are handled: @@ -342,15 +353,26 @@ def _handlePacket(self, packetType, arg1, arg2, arg3, payload): log.debugWarning("NAK received!") self._handleAck() elif packetType == FS_PKT_INFO: - self._manufacturer = payload[INFO_MANU_START:INFO_MANU_END].replace(FS_BYTE_NULL, "") - self._model = payload[INFO_MODEL_START:INFO_MODEL_END].replace(FS_BYTE_NULL, "") - self._firmwareVersion = payload[INFO_VERSION_START:INFO_VERSION_END].replace(FS_BYTE_NULL, "") + manuBytes = payload[INFO_MANU_START:INFO_MANU_END].replace( + FS_BYTE_NULL, b"" + ) + self._manufacturer = manuBytes.decode() + modelBytes = payload[INFO_MODEL_START:INFO_MODEL_END].replace( + FS_BYTE_NULL, b"" + ) + self._model = modelBytes.decode() + firmwareBytes = payload[INFO_VERSION_START:INFO_VERSION_END].replace( + FS_BYTE_NULL, b"" + ) + self._firmwareVersion = firmwareBytes.decode() self.numCells = MODELS.get(self._model, 0) if self.numCells in FOCUS_1_CELL_COUNTS: # Focus first gen: apply custom translation table self.translationTable = FOCUS_1_TRANSLATION_TABLE - log.debug("Device info: manufacturer: %s model: %s, version: %s", - self._manufacturer, self._model, self._firmwareVersion) + log.debug( + "Device info: manufacturer: %s model: %s, version: %s", + self._manufacturer, self._model, self._firmwareVersion + ) elif packetType == FS_PKT_WHEEL: threeLeastSigBitsMask = 0x7 count = ord(arg1) & threeLeastSigBitsMask @@ -367,7 +389,7 @@ def _handlePacket(self, packetType, arg1, arg2, arg3, payload): except IndexError: log.debugWarning("wheelNumber unknown") return - for _i in xrange(count): + for _i in range(count): gesture = WizWheelGesture(self._model, isDown, isRight) try: inputCore.manager.executeGesture(gesture) @@ -391,7 +413,7 @@ def _handlePacket(self, packetType, arg1, arg2, arg3, payload): keyBits = ord(arg1) | (ord(arg2) << 8) | (ord(arg3) << 16) self._handleKeys(keyBits) elif packetType == FS_PKT_EXT_KEY: - keyBits = ord(payload[0]) >> 4 + keyBits = payload[0] >> 4 self._handleExtendedKeys(keyBits) else: log.debugWarning("Unknown packet of type: %r", packetType) @@ -403,7 +425,7 @@ def _handleAck(self): self.display(self._pendingCells) @staticmethod - def _updateKeyBits(keyBits, oldKeyBits, keyCount): + def _updateKeyBits(keyBits: int, oldKeyBits: int, keyCount: int): """Helper function that reports if keys have been pressed and which keys have been released based on old and new keybits. """ @@ -429,7 +451,7 @@ def _updateKeyBits(keyBits, oldKeyBits, keyCount): keyBit <<= 1 return oldKeyBits, isRelease, keyBitsBeforeRelease, newKeysPressed - def _handleKeys(self, keyBits): + def _handleKeys(self, keyBits: int): """Send gestures if keys are released and update self._keyBits""" keyBits, isRelease, keyBitsBeforeRelease, newKeysPressed = self._updateKeyBits(keyBits, self._keyBits, 24) if newKeysPressed: @@ -443,7 +465,7 @@ def _handleKeys(self, keyBits): pass self._ignoreKeyReleases = True - def _handleExtendedKeys(self, keyBits): + def _handleExtendedKeys(self, keyBits: int): """Send gestures if keys are released and update self._extendedKeyBits""" keyBits, isRelease, keyBitsBeforeRelease, newKeysPressed = self._updateKeyBits(keyBits, self._extendedKeyBits, 24) if newKeysPressed: @@ -458,20 +480,25 @@ def _handleExtendedKeys(self, keyBits): self._ignoreKeyReleases = True @staticmethod - def _calculateChecksum(data): + def _calculateChecksum(data: bytes) -> int: """Calculate the checksum for extended packets""" checksum = 0 for byte in data: - checksum -= ord(byte) + checksum -= byte checksum = checksum & 0xFF return checksum - def display(self, cells): + def display(self, cells: List[int]): if self.translationTable: cells = _translate(cells, FOCUS_1_TRANSLATION_TABLE) if not self._awaitingAck: - cells = b"".join([int2byte(x) for x in cells]) - self._sendPacket(FS_PKT_WRITE, int2byte(self.numCells), FS_BYTE_NULL, FS_BYTE_NULL, cells) + self._sendPacket( + FS_PKT_WRITE, + intToByte(self.numCells), + FS_BYTE_NULL, + FS_BYTE_NULL, + bytes(cells) + ) self._pendingCells = [] else: self._pendingCells = cells @@ -487,13 +514,17 @@ def _configureDisplay(self): self._sendPacket(FS_PKT_CONFIG, FS_CFG_EXTKEY) def script_toggleLeftWizWheelAction(self, _gesture): - action = self.leftWizWheelActionCycle.next() + # Python 3: review required + # original: self.leftWizWheelActionCycle.next() + action = next(self.leftWizWheelActionCycle) self.gestureMap.add("br(freedomScientific):leftWizWheelUp", *action[1], replace=True) self.gestureMap.add("br(freedomScientific):leftWizWheelDown", *action[2], replace=True) braille.handler.message(action[0]) def script_toggleRightWizWheelAction(self, _gesture): - action = self.rightWizWheelActionCycle.next() + # Python 3: review required + # original: self.rightWizWheelActionCycle.next() + action = next(self.rightWizWheelActionCycle) self.gestureMap.add("br(freedomScientific):rightWizWheelUp", *action[1], replace=True) self.gestureMap.add("br(freedomScientific):rightWizWheelDown", *action[2], replace=True) braille.handler.message(action[0]) @@ -543,7 +574,7 @@ class InputGesture(braille.BrailleDisplayGesture): """Base gesture for this braille display""" source = BrailleDisplayDriver.name - def __init__(self, model): + def __init__(self, model: str): self.model = model.replace(" ", "") super(InputGesture, self).__init__() @@ -568,10 +599,10 @@ class KeyGesture(InputGesture, brailleInput.BrailleInputGesture): "leftRockerBarUp", "leftRockerBarDown", "rightRockerBarUp", "rightRockerBarDown", ] - def __init__(self, model, keyBits, extendedKeyBits): + def __init__(self, model, keyBits: int, extendedKeyBits: int): super(KeyGesture, self).__init__(model) - keys = [self.keyLabels[num] for num in xrange(24) if (keyBits>>num) & 1] - extendedKeys = [self.extendedKeyLabels[num] for num in xrange(4) if (extendedKeyBits>>num) & 1] + keys = [self.keyLabels[num] for num in range(24) if (keyBits>>num) & 1] + extendedKeys = [self.extendedKeyLabels[num] for num in range(4) if (extendedKeyBits>>num) & 1] # pylint: disable=invalid-name self.id = "+".join(keys+extendedKeys) # Don't say is this a dots gesture if some keys either from dots and space are pressed. @@ -583,7 +614,7 @@ def __init__(self, model, keyBits, extendedKeyBits): class RoutingGesture(InputGesture): """Gesture to handle cursor routing and second row of routing keys on older models""" - def __init__(self, model, routingIndex, topRow=False): + def __init__(self, model: str, routingIndex: int, topRow: bool = False): if topRow: # pylint: disable=invalid-name self.id = "topRouting%d"%(routingIndex+1) @@ -595,7 +626,7 @@ def __init__(self, model, routingIndex, topRow=False): class WizWheelGesture(InputGesture): """Gesture to handle wiz wheels movements""" - def __init__(self, model, isDown, isRight): + def __init__(self, model: str, isDown: bool, isRight: bool): which = "right" if isRight else "left" direction = "Down" if isDown else "Up" # pylint: disable=invalid-name diff --git a/source/brailleDisplayDrivers/handyTech.py b/source/brailleDisplayDrivers/handyTech.py index 269bbe3cddc..27acfaff0e2 100644 --- a/source/brailleDisplayDrivers/handyTech.py +++ b/source/brailleDisplayDrivers/handyTech.py @@ -10,10 +10,11 @@ """ from collections import OrderedDict -from cStringIO import StringIO +from io import BytesIO import serial # pylint: disable=E0401 import weakref import hwIo +from hwIo import intToByte, boolToByte import braille import brailleInput import inputCore @@ -26,23 +27,26 @@ import datetime from ctypes import windll import windowUtils -from driverHandler import BooleanDriverSetting + import wx +from typing import List, Any, Union, Optional + class InvisibleDriverWindow(windowUtils.CustomWindow): className = u"Handy_Tech_Server" HT_SLEEP = 100 HT_INCREMENT = 1 HT_DECREMENT = 0 - def __init__(self, driver): + + def __init__(self, driver: Any): super(InvisibleDriverWindow, self).__init__(u"Handy Tech Server") # Register shared window message. # Note: There is no corresponding unregister function. # Still this does no harm if done repeatedly. self.window_message=windll.user32.RegisterWindowMessageW(u"Handy_Tech_Server") - self.driver = weakref.ref(driver, lambda(r): self.destroy()) + self.driver = weakref.ref(driver, lambda r: self.destroy()) - def windowProc(self, hwnd, msg, wParam, lParam): + def windowProc(self, hwnd: int, msg: int, wParam: int, lParam: int): if msg == self.window_message: if wParam == self.HT_SLEEP and lParam == self.HT_INCREMENT: d = self.driver() @@ -52,7 +56,7 @@ def windowProc(self, hwnd, msg, wParam, lParam): d = self.driver() if d is not None: d.wake_up() - return 0 # success, bypass default window procedure + return 0 # success, bypass default window procedure BAUD_RATE = 19200 @@ -211,25 +215,28 @@ def _get_keys(self): 0x1E: "n9", }) - def display(self, cells): + def display(self, cells: List[int]): """Display cells on the braille display This is the modern protocol, which uses an extended packet to send braille cells. Some displays use an older, simpler protocol. See OldProtocolMixin. """ - self._display.sendExtendedPacket(HT_EXTPKT_BRAILLE, - "".join(chr(cell) for cell in cells)) + cellBytes: bytes = bytes(cells) + self._display.sendExtendedPacket( + HT_EXTPKT_BRAILLE, + cellBytes + ) class OldProtocolMixin(object): "Mixin for displays using an older protocol to send braille cells and handle input" - def display(self, cells): + def display(self, cells: List[int]): """Write cells to the display according to the old protocol This older protocol sends a simple packet starting with HT_PKT_BRAILLE, - followed by the cells. No model ID or lenghth are included. + followed by the cells. No model ID or length are included. """ - self._display.sendPacket(HT_PKT_BRAILLE, b"".join(chr(cell) for cell in cells)) + self._display.sendPacket(HT_PKT_BRAILLE, bytes(cells)) class AtcMixin(object): @@ -255,19 +262,18 @@ def postInit(self): log.debug("Request current dot firmness") self._display.sendExtendedPacket(HT_EXTPKT_GET_FIRMNESS) - def handleTime(self, timeStr): - ords = map(ord, timeStr) + def handleTime(self, timeBytes: bytes): try: displayDateTime = datetime.datetime( - year=ords[0] << 8 | ords[1], - month=ords[2], - day=ords[3], - hour=ords[4], - minute=ords[5], - second=ords[6] + year=timeBytes[0] << 8 | timeBytes[1], + month=timeBytes[2], + day=timeBytes[3], + hour=timeBytes[4], + minute=timeBytes[5], + second=timeBytes[6] ) except ValueError: - log.debugWarning("Invalid time/date of Handy Tech display: %r"%timeStr) + log.debugWarning("Invalid time/date of Handy Tech display: %r" % timeBytes) return localDateTime = datetime.datetime.today() if abs((displayDateTime - localDateTime).total_seconds()) >= 5: @@ -276,16 +282,16 @@ def handleTime(self, timeStr): else: log.debug("Time in sync. Display time %s"%displayDateTime.isoformat()) - def syncTime(self, dt): + def syncTime(self, dt: datetime.datetime): log.debug("Synchronizing braille display date and time...") # Setting the time uses a swapped byte order for the year. - timeList = [ + timeList: List[int] = [ dt.year & 0xFF, dt.year >> 8, dt.month, dt.day, dt.hour, dt.minute, dt.second ] - timeStr = b"".join(map(chr, timeList)) - self._display.sendExtendedPacket(HT_EXTPKT_SET_RTC, timeStr) + timeBytes = bytes(timeList) + self._display.sendExtendedPacket(HT_EXTPKT_SET_RTC, timeBytes) class TripleActionKeysMixin(AutoPropertyObject): @@ -344,7 +350,7 @@ def _get_keys(self): }) return keys - def display(self, cells): + def display(self, cells: List[int]): """Display braille on the display with empty status cells Some displays (e.g. Modular series) have 4 status cells. @@ -440,7 +446,7 @@ def _get_name(self): return '{name} {cells}'.format(name=self.genericName, cells=self.numCells) -def basicBrailleFactory(numCells, deviceId): +def basicBrailleFactory(numCells: int, deviceId: bytes): return type("BasicBraille{cells}".format(cells=numCells), (BasicBraille,), { "deviceId": deviceId, "numCells": numCells, @@ -562,6 +568,8 @@ class BrailleDisplayDriver(braille.BrailleDisplayDriver, ScriptableObject): def getManualPorts(cls): return braille.getSerialPorts() + _dev: Optional[Union[hwIo.Hid, hwIo.Serial]] + def __init__(self, port="auto"): super(BrailleDisplayDriver, self).__init__() # Create the message window on the ui thread. @@ -599,7 +607,7 @@ def __init__(self, port="auto"): continue self.sendPacket(HT_PKT_RESET) - for _i in xrange(3): + for _i in range(3): # An expected response hasn't arrived yet, so wait for it. self._dev.waitForRead(self.timeout) if self.numCells and self._model: @@ -692,7 +700,7 @@ def _set_atc(self, state): if self._atc is state: return if isinstance(self._model,AtcMixin): - self.sendExtendedPacket(HT_EXTPKT_SET_ATC_MODE, state) + self.sendExtendedPacket(HT_EXTPKT_SET_ATC_MODE, boolToByte(state)) else: log.debugWarning("Changing ATC setting for unsupported device %s"%self._model.name) # Regardless whether this setting is supported or not, we want to safe its state. @@ -705,45 +713,43 @@ def _set_dotFirmness(self, value): if self._dotFirmness is value: return if isinstance(self._model,TimeSyncFirmnessMixin): - self.sendExtendedPacket(HT_EXTPKT_SET_FIRMNESS, value) + self.sendExtendedPacket(HT_EXTPKT_SET_FIRMNESS, intToByte(value)) else: log.debugWarning("Changing dot firmness setting for unsupported device %s"%self._model.name) # Regardless whether this setting is supported or not, we want to safe its state. self._dotFirmness = value - def sendPacket(self, packetType, data=""): + def sendPacket(self, packetType: bytes, data:bytes = b""): if self._sleepcounter > 0: return - if type(data) == bool or type(data) == int: - data = chr(data) if self.isHid: self._sendHidPacket(packetType+data) else: self._dev.write(packetType + data) - def sendExtendedPacket(self, packetType, data=""): + def sendExtendedPacket(self, packetType: bytes, data: bytes = b""): if self._sleepcounter > 0: log.debug("Packet discarded as driver was requested to sleep") return - if type(data) == bool or type(data) == int: - data = chr(data) - packet = b"{length}{extType}{data}\x16".format( - extType=packetType, data=data, - length=chr(len(data) + len(packetType)) - ) + packetBytes: bytes = b"".join([ + intToByte(len(data) + len(packetType)), + packetType, + data, + b"\x16" + ]) if self._model: - packet = self._model.deviceId + packet - self.sendPacket(HT_PKT_EXTENDED, packet) + packetBytes = self._model.deviceId + packetBytes + self.sendPacket(HT_PKT_EXTENDED, packetBytes) - def _sendHidPacket(self, packet): + def _sendHidPacket(self, packet: bytes): assert self.isHid maxBlockSize = self._dev._writeSize-3 # When the packet length exceeds C{writeSize}, the packet is split up into several packets. # They contain C{HT_HID_RPT_InData}, the length of the data block, # the data block itself and a terminating null character. - for offset in xrange(0, len(packet), maxBlockSize): + for offset in range(0, len(packet), maxBlockSize): block = packet[offset:offset+maxBlockSize] - hidPacket = HT_HID_RPT_InData + chr(len(block)) + block + b"\x00" + hidPacket = HT_HID_RPT_InData + intToByte(len(block)) + block + b"\x00" self._dev.write(hidPacket) def _handleKeyRelease(self): @@ -762,29 +768,29 @@ def _handleKeyRelease(self): # pylint: disable=R0912 # Pylint complains about many branches, might be worth refactoring - def _hidOnReceive(self, data): + def _hidOnReceive(self, data: bytes): # data contains the entire packet. - stream = StringIO(data) - htPacketType = data[2] + stream = BytesIO(data) + htPacketType = data[2:3] # Skip the header, so reading the stream will only give the rest of the data stream.seek(3) self._handleInputStream(htPacketType, stream) - def _hidSerialOnReceive(self, data): + def _hidSerialOnReceive(self, data: bytes): # The HID serial converter wraps one or two bytes into a single HID packet - hidLength = ord(data[1]) + hidLength = data[1] self._hidSerialBuffer+=data[2:(2+hidLength)] self._processHidSerialBuffer() def _processHidSerialBuffer(self): while self._hidSerialBuffer: currentBufferLength=len(self._hidSerialBuffer) - htPacketType = self._hidSerialBuffer[0] + htPacketType: bytes = self._hidSerialBuffer[0:1] if htPacketType!=HT_PKT_EXTENDED: packetLength = 2 if htPacketType==HT_PKT_OK else 1 if currentBufferLength>=packetLength: - stream = StringIO(self._hidSerialBuffer[:packetLength]) - self._hidSerialBuffer = self._hidSerialBuffer[packetLength:] + stream = BytesIO(self._hidSerialBuffer[:packetLength]) + self._hidSerialBuffer: bytes = self._hidSerialBuffer[packetLength:] else: # The packet is not yet complete return @@ -792,30 +798,30 @@ def _processHidSerialBuffer(self): # Check whether our packet is complete # Extended packets are at least 5 bytes in size. # The second byte is the model, the third byte is the data length, excluding the terminator - packet_length = ord(self._hidSerialBuffer[2])+4 + packet_length = self._hidSerialBuffer[2]+4 if len(self._hidSerialBuffer)= HEDO_MOBIL_CR_BEGIN and data <= HEDO_MOBIL_CR_END: + def handleData(self, data: int): + if HEDO_MOBIL_CR_BEGIN <= data <= HEDO_MOBIL_CR_END: # Routing key is pressed try: inputCore.manager.executeGesture(InputGestureRouting(data - HEDO_MOBIL_CR_BEGIN)) except inputCore.NoInputGestureAction: - log.debug("No Action for routing index " + index) + log.debug("No Action for routing index: %d", data) pass return @@ -200,4 +204,4 @@ def __init__(self, index): super(InputGestureRouting, self).__init__() self.id = "routing" - self.routingIndex = index \ No newline at end of file + self.routingIndex = index diff --git a/source/brailleDisplayDrivers/hedoProfiLine.py b/source/brailleDisplayDrivers/hedoProfiLine.py index 1669e977f48..366d49cdc16 100644 --- a/source/brailleDisplayDrivers/hedoProfiLine.py +++ b/source/brailleDisplayDrivers/hedoProfiLine.py @@ -10,7 +10,8 @@ # hedo ProfiLine USB, a product from hedo Reha-Technik GmbH # see www.hedo.de for more details -import time +from typing import List + import wx import serial import braille @@ -21,8 +22,8 @@ HEDO_TIMEOUT = 0.2 HEDO_BAUDRATE = 19200 HEDO_READ_INTERVAL = 50 -HEDO_ACK = 0x7E -HEDO_INIT = 0x01 +HEDO_ACK = b"\x7E" +HEDO_INIT = b"\x01" HEDO_CR_BEGIN = 0x20 HEDO_CR_END = 0x6F HEDO_RELEASE_OFFSET = 0x80 @@ -80,7 +81,8 @@ def __init__(self): continue # Prepare a blank line - cells = chr(HEDO_INIT) + chr(0) * (HEDO_CELL_COUNT + HEDO_STATUS_CELL_COUNT) + totalCells: int = HEDO_CELL_COUNT + HEDO_CELL_COUNT + cells: bytes = HEDO_INIT + bytes(totalCells) # Send the blank line twice self._ser.write(cells) @@ -89,8 +91,8 @@ def __init__(self): self._ser.flush() # Read out the input buffer - ackS = self._ser.read(2) - if chr(HEDO_ACK) in ackS: + ackS: bytes = self._ser.read(2) + if HEDO_ACK in ackS: log.info("Found hedo ProfiLine connected via {port}".format(port=port)) break @@ -113,36 +115,36 @@ def terminate(self): # If we don't, we won't be able to re-open it later. self._ser.close() - def display(self, cells): + def display(self, cells: List[int]): # every transmitted line consists of the preamble HEDO_INIT, the statusCells and the Cells - line = chr(HEDO_INIT) + chr(0) * HEDO_STATUS_CELL_COUNT + "".join(chr(cell) for cell in cells) - # cells will be padded up to 1 + numStatusCells + numCells. - expectedLength = 1 + HEDO_STATUS_CELL_COUNT + HEDO_CELL_COUNT - line += chr(0) * (expectedLength - len(line)) + # add padding so total length is 1 + numberOfStatusCells + numberOfRegularCells + cellPadding: bytes = bytes(HEDO_CELL_COUNT - len(cells)) + statusPadding: bytes = bytes(HEDO_STATUS_CELL_COUNT) + cellBytes: bytes = HEDO_INIT + statusPadding + bytes(cells) + cellPadding - self._ser.write(line) + self._ser.write(cellBytes) def handleResponses(self, wait=False): while wait or self._ser.in_waiting: - data = self._ser.read(1) + data: bytes = self._ser.read(1) if data: # do not handle acknowledge bytes - if data != chr(HEDO_ACK): + if data != HEDO_ACK: self.handleData(ord(data)) wait = False - def handleData(self, data): + def handleData(self, data: int): - if data >= HEDO_CR_BEGIN and data <= HEDO_CR_END: + if HEDO_CR_BEGIN <= data <= HEDO_CR_END: # Routing key is pressed try: inputCore.manager.executeGesture(InputGestureRouting(data - HEDO_CR_BEGIN)) except inputCore.NoInputGestureAction: - log.debug("No Action for routing command") + log.debug("No Action for routing command: %d", data) pass - elif data >= (HEDO_CR_BEGIN + HEDO_RELEASE_OFFSET) and data <= (HEDO_CR_END + HEDO_RELEASE_OFFSET): + elif (HEDO_CR_BEGIN + HEDO_RELEASE_OFFSET) <= data <= (HEDO_CR_END + HEDO_RELEASE_OFFSET): # Routing key is released return @@ -155,7 +157,7 @@ def handleData(self, data): elif data > HEDO_RELEASE_OFFSET and (data - HEDO_RELEASE_OFFSET) in HEDO_KEYMAP: # A key is released # log.debug("Key " + str(self._keysDown) + " released") - if self._ignoreKeyReleases == False: + if not self._ignoreKeyReleases: keys = "+".join(self._keysDown) self._ignoreKeyReleases = True self._keysDown = set() diff --git a/source/brailleDisplayDrivers/hims.py b/source/brailleDisplayDrivers/hims.py index 2683f67a33b..900f73f1e86 100644 --- a/source/brailleDisplayDrivers/hims.py +++ b/source/brailleDisplayDrivers/hims.py @@ -4,10 +4,10 @@ #This file is covered by the GNU General Public License. #See the file COPYING for more details. #Copyright (C) 2010-2018 Gianluca Casalino, NV Access Limited, Babbage B.V., Leonard de Ruijter, Bram Duvigneau +from typing import List import serial -from cStringIO import StringIO -import os +from io import BytesIO import hwIo import braille from logHandler import log @@ -15,7 +15,6 @@ import inputCore import brailleInput from baseObject import AutoPropertyObject -import weakref import time import bdDetect @@ -25,8 +24,8 @@ class Model(AutoPropertyObject): """Extend from this base class to define model specific behavior.""" #: Two bytes device identifier, used in the protocol to identify the device - #: @type: string - deviceId = "" + #: @type: bytes + deviceId = b"" #: A generic name that identifies the model/series, used in gesture identifiers #: @type: string name = "" @@ -89,7 +88,7 @@ def _get_keys(self): return keys class BrailleEdge(Model): - deviceId="\x42\x45" # BE + deviceId = b"\x42\x45" # BE name = "Braille Edge" usbId = "VID_045E&PID_930B" bluetoothPrefix = "BrailleEDGE" @@ -121,10 +120,10 @@ class BrailleSense2S(BrailleSense): """Braille Sense with one scroll key on both sides. Also referred to as Braille Sense Classic.""" name = "Braille Sense Classic" - deviceId="\x42\x53" # BS + deviceId = b"\x42\x53" # BS class BrailleSense4S(BrailleSense): - deviceId="\x4c\x58" # LX + deviceId = b"\x4c\x58" # LX class SmartBeetle(BrailleSense4S): """Subclass for Smart Beetle device, which has the same identifier as the Braille Sense with 4 scroll keys. @@ -146,13 +145,13 @@ def _get_keys(self): return keys class BrailleSenseQ(BrailleSense4S): - deviceId="\x51\x58" # QX + deviceId = b"\x51\x58" # QX name = "Braille Sense QWERTY" numCells = 32 class BrailleSenseQX(BrailleSenseQ): """Special identifier to support QWERTY input""" - deviceId="\x53\x58" # SX + deviceId = b"\x53\x58" # SX class SyncBraille(Model): name = "SyncBraille" @@ -201,13 +200,13 @@ def __init__(self, port="auto"): try: if self.isBulk: # onReceiveSize based on max packet size according to USB endpoint information. - self._dev = hwIo.Bulk(port, 0, 1, self._onReceive, writeSize=0, onReceiveSize=64) + self._dev = hwIo.Bulk(port, 0, 1, self._onReceive, onReceiveSize=64) else: self._dev = hwIo.Serial(port, baudrate=BAUD_RATE, parity=PARITY, timeout=self.timeout, writeTimeout=self.timeout, onReceive=self._onReceive) except EnvironmentError: log.debugWarning("", exc_info=True) continue - for i in xrange(3): + for i in range(3): self._sendCellCountRequest() # Wait for an expected response. if self.isBulk: @@ -235,29 +234,39 @@ def __init__(self, port="auto"): else: raise RuntimeError("No Hims display found") - def display(self, cells): + def display(self, cells: List[int]): # cells will already be padded up to numCells. - self._sendPacket("\xfc","\x01","".join(chr(cell) for cell in cells)) + cellBytes = bytes(cells) + self._sendPacket(b"\xfc", b"\x01", cellBytes) def _sendCellCountRequest(self): log.debug("Sending cell count request...") - self._sendPacket("\xfb","\x01","\x00"*32) + self._sendPacket(b"\xfb", b"\x01", bytes(32)) # send 32 null bytes - def _sendIdentificationRequests(self, match): + def _sendIdentificationRequests(self, match: bdDetect.DeviceMatch): log.debug("Considering sending identification requests for device %s"%str(match)) if match.type==bdDetect.KEY_CUSTOM: # USB Bulk - map=[modelTuple for modelTuple in modelMap if modelTuple[1].usbId==match.id] + matchedModelsMap = [ + modelTuple for modelTuple in modelMap if( + modelTuple[1].usbId == match.id + ) + ] elif "bluetoothName" in match.deviceInfo: # Bluetooth - map=[modelTuple for modelTuple in modelMap if modelTuple[1].bluetoothPrefix and match.id.startswith(modelTuple[1].bluetoothPrefix)] + matchedModelsMap = [ + modelTuple for modelTuple in modelMap if( + modelTuple[1].bluetoothPrefix + and match.id.startswith(modelTuple[1].bluetoothPrefix) + ) + ] else: # The only serial device we support which is not bluetooth, is a Sync Braille self._model = SyncBraille() log.debug("Use %s as model without sending an additional identification request"%self._model.name) return - if not map: + if not matchedModelsMap: log.debugWarning("The provided device match to send identification requests didn't yield any results") - map = modelMap - if len(map)==1: - modelCls = map[0][1] + matchedModelsMap = modelMap + if len(matchedModelsMap) == 1: + modelCls = matchedModelsMap[0][1] numCells = self.numCells or modelCls.numCells if numCells: # There is only one model matching the criteria, and we have the proper number of cells. @@ -267,18 +276,27 @@ def _sendIdentificationRequests(self, match): self.numCells = numCells return self._model = None - for id, cls in map: - log.debug("Sending request for id %r"%id) - self._dev.write("\x1c{id}\x1f".format(id=id)) + for modelId, cls in matchedModelsMap: + log.debug("Sending request for id %r" % modelId) + + self._dev.write(b"".join([ + b"\x1c", + modelId, + b"\x1f" + ])) self._dev.waitForRead(self.timeout) if self._model: log.debug("%s model has been set"%self._model.name) break - def _handleIdentification(self, id): + def _handleIdentification(self, recvId: bytes): modelCls = None - models=[modelCls for modelId,modelCls in modelMap if modelId==id] - log.debug("Identification received, id %s"%id) + models = [ + modelCls for modelId, modelCls in modelMap if( + modelId == recvId + ) + ] + log.debug("Identification received, id %s" % recvId) if not models: raise ValueError("Device identification ID unknown in model map") if len(models)==1: @@ -299,18 +317,18 @@ def _handleIdentification(self, id): if modelCls: self._model = modelCls() - def _handlePacket(self, packet): - mode=packet[1] - if mode=="\x00": # Cursor routing - routingIndex = ord(packet[3]) + def _handlePacket(self, packet: bytes): + mode = packet[1] + if mode == 0x00: # Cursor routing + routingIndex = packet[3] try: inputCore.manager.executeGesture(RoutingInputGesture(routingIndex)) except inputCore.NoInputGestureAction: pass - elif mode=="\x01": # Braille input or function key + elif mode == 0x01: # Braille input or function key if not self._model: return - _keys = sum(ord(packet[4+i])<<(i*8) for i in xrange(4)) + _keys = int.from_bytes(packet[4:8], "little", signed=False) keys = set() for keyHex in self._model.keys: if _keys & keyHex: @@ -326,76 +344,91 @@ def _handlePacket(self, packet): inputCore.manager.executeGesture(KeyInputGesture(self._model, keys)) except inputCore.NoInputGestureAction: pass - elif mode=="\x02": # Cell count - self.numCells=ord(packet[3]) + elif mode == 0x02: # Cell count + self.numCells = packet[3] - def _onReceive(self, data): + def _onReceive(self, data: bytes): if self.isBulk: # data contains the entire packet. - stream = StringIO(data) - firstByte=data[0] + stream = BytesIO(data) + firstByte:bytes = data[0:1] stream.seek(1) else: firstByte = data # data only contained the first byte. Read the rest from the device. stream = self._dev - if firstByte=="\x1c": + if firstByte == b"\x1c": # A device is identifying itself - deviceId=stream.read(2) + deviceId: bytes = stream.read(2) # When a device identifies itself, the packets ends with 0x1f - assert stream.read(1) == "\x1f" + assert stream.read(1) == b"\x1f" self._handleIdentification(deviceId) - elif firstByte=="\xfa": + elif firstByte == b"\xfa": # Command packets are ten bytes long - packet=firstByte+stream.read(9) - assert packet[2] == "\x01" # Fixed value - checksum=packet[8] - assert packet[9] == "\xfb" # Command End - assert(chr(sum(ord(c) for c in packet[0:8]+packet[9])&0xff)==checksum) + packet = firstByte + stream.read(9) + assert packet[2] == 0x01 # Fixed value + CHECKSUM_INDEX = 8 + checksum: int = packet[CHECKSUM_INDEX] + assert packet[9] == 0xfb # Command End + calcCheckSum: int = 0xff & sum( + c for index, c in enumerate(packet) if( + index != CHECKSUM_INDEX) + ) + assert(calcCheckSum == checksum) self._handlePacket(packet) else: log.debug("Unknown first byte received: 0x%x"%ord(firstByte)) return - def _sendPacket(self, type, mode, data1, data2=""): - packetLength = 2 + 1 + 1 + 2 + len(data1) + 1 + 1 + 2 + len(data2) + 1 + 4 + 1 + 2 + def _sendPacket( + self, packetType: bytes, mode: bytes, + data1: bytes, data2: bytes = b"" + ): + d1Len = len(data1) + d2Len = len(data2) # Construct the packet - packet=[ + packet: List[bytes] = [ # Packet start - type*2, + packetType * 2, # Mode mode, # Always "\x01" according to the spec # Data block 1 start - "\xf0", + b"\xf0", # Data block 1 length - chr((len(data1)>>0)&0xff), - chr((len(data1)>>8)&0xff), + d1Len.to_bytes(2, "little", signed=False), # Data block 1 data1, # Data block 1 end - "\xf1", + b"\xf1", # Data block 2 is currently not used, but it is part of the spec # Data block 2 start - "\xf2", + b"\xf2", # Data block 1 length - chr((len(data2)>>0)&0xff), - chr((len(data2)>>8)&0xff), + d2Len.to_bytes(2, "little", signed=False), # Data block 2 data2, # Data block 2 end - "\xf3", + b"\xf3", # Reserved bytes - "\x00"*4, + b"\x00"*4, # Reserved space for checksum - "\x00", + b"\x00", # Packet end - "\xfd"*2, + b"\xfd"*2, ] - packetStrWithoutCheksum="".join(s for s in packet) - packet[-2]=chr(sum(ord(c) for c in packetStrWithoutCheksum)&0xff) - packetStrWithCheksum="".join(s for s in packet) - assert(len(packetStrWithCheksum)==packetLength) - self._dev.write(packetStrWithCheksum) + packetB = bytearray(b"".join(packet)) + checksum: int = 0xff & sum(packetB) + packetB[-2] = checksum + + # check that the packet is the size we expect: + ptLen = len(packetType) + assert(ptLen == 1) + mLen = len(mode) + assert(mLen == 1) + packetLength = ptLen*2 + mLen + 1 + 2 + d1Len + 1 + 1 + 2 + d2Len + 1 + 4 + 1 + 2 + assert(len(packetB) == packetLength) + + self._dev.write(bytes(packetB)) def terminate(self): try: diff --git a/source/brailleDisplayDrivers/lilli.py b/source/brailleDisplayDrivers/lilli.py index a514b59a070..9158ec304ab 100644 --- a/source/brailleDisplayDrivers/lilli.py +++ b/source/brailleDisplayDrivers/lilli.py @@ -3,6 +3,7 @@ #This file is covered by the GNU General Public License. #See the file COPYING for more details. #Copyright (C) 2008-2017 NV Access Limited, Gianluca Casalino, Alberto Benassati, Babbage B.V. +from typing import Optional, List from logHandler import log from ctypes import * @@ -15,7 +16,7 @@ except: lilliDll=None -lilliCellsMap=[] +lilliCellsMap: List[int] = [] KEY_CHECK_INTERVAL = 50 LILLI_KEYS = [ @@ -25,17 +26,19 @@ "", "SLF1", "SLF2", "SLF3", "SLF4", "SLF5", "SLF6", "SLF7", "SLF8", "SLF9", "SLF10", "SLLF", "SLUP", "SLRG", "SLDN", "SFDN", "SFUP", "route" ] - - -def convertLilliCells(cell): - newCell = ((1<<6 if cell & 1<<4 else 0) | - (1<<5 if cell & 1<<5 else 0) | - (1<<0 if cell & 1<<6 else 0) | - (1<<3 if cell & 1<<0 else 0) | - (1<<2 if cell & 1<<1 else 0) | - (1<<1 if cell & 1<<2 else 0) | - (1<<7 if cell & 1<<3 else 0) | - (1<<4 if cell & 1<<7 else 0)) +ROUTE_COMMAND = "route" + +def convertLilliCells(cell: int) -> int: + newCell = ( + (1<<6 if cell & 1<<4 else 0) | + (1<<5 if cell & 1<<5 else 0) | + (1<<0 if cell & 1<<6 else 0) | + (1<<3 if cell & 1<<0 else 0) | + (1<<2 if cell & 1<<1 else 0) | + (1<<1 if cell & 1<<2 else 0) | + (1<<7 if cell & 1<<3 else 0) | + (1<<4 if cell & 1<<7 else 0) + ) return newCell class BrailleDisplayDriver(braille.BrailleDisplayDriver): @@ -47,10 +50,10 @@ class BrailleDisplayDriver(braille.BrailleDisplayDriver): def check(cls): return bool(lilliDll) - def __init__(self): + def __init__(self): global lilliCellsMap super(BrailleDisplayDriver, self).__init__() - lilliCellsMap=[convertLilliCells(x) for x in xrange(256)] + lilliCellsMap=[convertLilliCells(x) for x in range(256)] if (lilliDll.Init408USB()): self._keyCheckTimer = wx.PyTimer(self._handleKeyPresses) self._keyCheckTimer.Start(KEY_CHECK_INTERVAL) @@ -66,31 +69,36 @@ def terminate(self): pass lilliDll.Close408USB() - def _get_numCells(self): + def _get_numCells(self) -> int: return 40 def _handleKeyPresses(self): while True: + key: Optional[int] = None try: - key=lilliDll.ReadBuf() + # Python 3: review required + # The code seems to assume this returns an int. + # I haven't confirmed this. + key = lilliDll.ReadBuf() except: + log.debug("", exc_info=True) pass - if not key: break - if (key <= 0x40) or ((key >= 0x101) and (key <= 0x128)): + if not key: + break + if (key <= 0x40) or (0x101 <= key <= 0x128): self._onKeyPress(key) - def _onKeyPress(self, key): + def _onKeyPress(self, key: int): try: - if (key >= 0x101) and (key <= 0x128): - inputCore.manager.executeGesture(InputGesture(LILLI_KEYS[65],key-0x101)) - elif (key <= 0x40): - inputCore.manager.executeGesture(InputGesture(LILLI_KEYS[key],0)) + if 0x101 <= key <= 0x128: + inputCore.manager.executeGesture(InputGesture(ROUTE_COMMAND, key - 0x101)) + elif key <= 0x40: + inputCore.manager.executeGesture(InputGesture(LILLI_KEYS[key], 0)) except inputCore.NoInputGestureAction: pass - def display(self, cells): - cells="".join(chr(lilliCellsMap[x]) for x in cells) - lilliDll.WriteBuf(cells) + def display(self, cells: List[int]): + lilliDll.WriteBuf(bytes(lilliCellsMap[x] for x in cells)) gestureMap = inputCore.GlobalGestureMap({ "globalCommands.GlobalCommands": { @@ -110,8 +118,8 @@ class InputGesture(braille.BrailleDisplayGesture): source = BrailleDisplayDriver.name - def __init__(self, command, argument): + def __init__(self, command: str, argument: int): super(InputGesture, self).__init__() self.id = command - if (command == LILLI_KEYS[65]): + if command == ROUTE_COMMAND: self.routingIndex = argument diff --git a/source/brailleDisplayDrivers/papenmeier.py b/source/brailleDisplayDrivers/papenmeier.py index f1d1acdb43e..2257b444e62 100644 --- a/source/brailleDisplayDrivers/papenmeier.py +++ b/source/brailleDisplayDrivers/papenmeier.py @@ -7,14 +7,14 @@ #minor changes by Halim Sahin (nvda@lists.thm.de), Ali-Riza Ciftcioglu , James Teh and Davy Kager import time -import itertools +from typing import List, Union, Tuple, Optional + import wx import braille from logHandler import log import inputCore import brailleInput -import struct import keyboardHandler try: @@ -26,17 +26,11 @@ import serial #for brxcom -import ctypes as c -try: - import _winreg as winreg # Python 2.7 import -except ImportError: - import winreg # Python 3 import -import winUser +import ctypes +import winreg #for scripting from baseObject import ScriptableObject -import globalCommands -import scriptHandler #timer intervalls used by the driver KEY_CHECK_INTERVAL = 50 @@ -53,151 +47,77 @@ #Timeout for bluetooth BLUETOOTH_TIMEOUT = 0.2 -def brl_auto_id(): +def brl_auto_id() -> bytes: """send auto id command to braille display""" - return struct.pack('bbbbb',STX,AUTOID,0x50,0x50,ETX) - #device will respond with a message that allows identification of the display - -def brl_out(data,nrk,nlk,nv): + # device will respond with a message that allows identification of the display + return bytes([ + STX, AUTOID, 0x50, 0x50, ETX + ]) + +def _swapDotBits(d: int) -> List[int]: + # swap dot bits + d2 = 0 + if(d & 1): d2|=128 + if(d & 2): d2|=64 + if(d & 4): d2|=32 + if(d & 8): d2|=16 + if(d & 16): d2|=8 + if(d & 32): d2|=4 + if(d & 64): d2|=2 + if(d & 128): d2|=1 + a = 0x30|(d2 & 0x0F) + b = 0x30|(d2 >> 4) + return [b, a] + +def brl_out(data: List[int], nrk: int, nlk: int, nv: int) -> bytes: """write data to braille cell with nv vertical cells, nrk cells right and nlk cells left some papenmeier displays have vertical cells, other displays have dummy cells with keys """ - ret = [] - ret.append( struct.pack('BB', STX, BRAILLE)) #STX,COMMAND BRAILLE d2 = len(data) + nv + 2 * nlk + 2 * nrk + ret = bytearray([ + STX, # STX + BRAILLE, # COMMAND BRAILLE + # write length to stream + 0x50 | (d2 >> 4), # big end + 0x50 | (d2 & 0x0F), # little end + ]) + + # fill dummy bytes + dummyByteCount = ( + 2 * nv # left + + 4 * nlk # vertical + ) + ret.extend([0x30] * dummyByteCount) - a = 0x50|(d2 & 0x0F) - b = 0x50|(d2 >> 4) - #write length to stream - ret.append(struct.pack('BB',b,a)) - #fill dummy bytes (left,vertical) - ret.append(struct.pack('BB',0x30,0x30)*nv) - ret.append(struct.pack('BBBB',0x30,0x30,0x30,0x30)*nlk) - #swap dot bits for d in data: - d2 = 0 - if(d & 1): d2|=128 - if(d & 2): d2|=64 - if(d & 4): d2|=32 - if(d & 8): d2|=16 - if(d & 16): d2|=8 - if(d & 32): d2|=4 - if(d & 64): d2|=2 - if(d & 128): d2|=1 - a = 0x30|(d2 & 0x0F) - b = 0x30|(d2 >> 4) - ret.append(struct.pack('BB',b,a)) + ret.extend(_swapDotBits(d)) + #fill dummy bytes on (right) - ret.append(struct.pack('BBBB',0x30,0x30,0x30,0x30)*nrk) + ret.extend([0x30] * 4 * nrk) + #ETX - ret.append(struct.pack('B',ETX)) - return "".join(ret) + ret.append(ETX) + return bytes(ret) -def brl_poll(dev): +def brl_poll(dev: serial.Serial) -> bytes: """read sequence from braille display""" if dev.inWaiting() > 3: - status = [] - status.append(dev.read(4)) - if(ord(status[0][0])==STX):#first char must be an STX - if status[0][1] == 'K' or status[0][1] == 'L': l = (2*(((ord(status[0][2]) - 0x50) << 4) + (ord(status[0][3]) - 0x50)) +1) - else: l=6 - status.append(dev.read(l)) - if ord(status[-1][-1]) == ETX: - return "".join(status)[1:-1] # strip STX and ETX - return "" - -def brl_decode_trio(keys): - """decode routing keys on Trio""" - if(keys[0]=='K' ): #KEYSTATE CHANGED EVENT on Trio, not Braille keys - keys = keys[3:] - i = 0 - j = [] - for k in keys: - a= ord(k)&0x0F - #convert bitstream to list of indexes - if(a & 1): j.append(i+3) - if(a & 2): j.append(i+2) - if(a & 4): j.append(i+1) - if(a & 8): j.append(i) - i +=4 - return j - return [] - -def brl_decode_keys_A(data,start,voffset): - """decode routing keys non Trio devices""" - n = start #key index iterator - j= [] - shift = 0 - for i in xrange(0,len(data)): #byte index - if(i%2==0): - a= ord(data[i])&0x0F #n+4,n+3 - b= ord(data[i+1])&0x0F #n+2,n+1 - #convert bitstream to list of indexes - if(n > 26): shift=voffset - if(b & 1): j.append(n+0-shift) - if(b & 2): j.append(n+1-shift) - if(b & 4): j.append(n+2-shift) - if(b & 8): j.append(n+3-shift) - if(a & 1): j.append(n+4-shift) - if(a & 2): j.append(n+5-shift) - if(a & 4): j.append(n+6-shift) - if(a & 8): j.append(n+7-shift) - n+=8 - return j - -def brl_decode_key_names_repeat(driver): - """translate key names for protocol A with repeat""" - driver._repeatcount+=1 - dec = [] - if(driver._repeatcount < 10): return dec - else: driver._repeatcount = 0 - for key in driver.decodedkeys: - try: - dec.append(driver._keynamesrepeat[key]) - except: - pass - return dec - -def brl_decode_key_names(driver): - """translate key names for protocol A""" - dec = [] - keys = driver.decodedkeys - for key in keys: - try: - dec.append(driver._keynames[key]) - except: - pass - return dec - -def brl_join_keys(dec): - """join key names with comma, this is used for key combinations""" - if(len(dec) == 1): return dec[0] - elif(len(dec) == 3 and dec[0] == dec[1]): return dec[0] + "," + dec[2] - elif(len(dec) == 3 and dec[0] == dec[2]): return dec[0] + "," + dec[1] - elif(len(dec) == 2): return dec[1] + "," + dec[0] - else: return '' - -def brl_keyname_decoded(key,rest): - """convert index used by brxcom to keyname""" - if(key == 11 or key == 9): return 'l1' + rest - elif(key == 12 or key == 10): return 'l2' + rest - elif(key == 13 or key == 15): return 'r1' + rest - elif(key == 14 or key == 16): return 'r2' + rest - - elif(key == 3): return 'up' + rest - elif(key == 7): return 'dn' + rest - elif(key == 1): return 'left' + rest - elif(key == 5): return 'right' + rest + status = bytearray(dev.read(4)) + if status[0] == STX: # first char must be an STX + if status[1] in [ord(b'K'), ord(b'L')]: + length = 2 * (((status[2] - 0x50) << 4) + status[3] - 0x50) + 1 + else: + length = 6 + status.extend(dev.read(length)) + if status[-1] == ETX: + return bytes(status[1:-1]) # strip STX and ETX + return b"" - elif(key == 4): return 'up2' + rest - elif(key == 8): return 'dn2' + rest - elif(key == 2): return 'left2' + rest - elif(key == 6): return 'right2' + rest - else: return '' class BrailleDisplayDriver(braille.BrailleDisplayDriver, ScriptableObject): """papenmeier braille display driver. """ + _dev: serial.Serial name = "papenmeier" # Translators: Names of braille displays. description = _("Papenmeier BRAILLEX newer models") @@ -209,14 +129,17 @@ def check(cls): def connectBrxCom(self):#connect to brxcom server (provided by papenmeier) try: - brxcomkey=winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,"SOFTWARE\\FHP\\BrxCom") - value, vtype = winreg.QueryValueEx(brxcomkey, "InstallPath") - winreg.CloseKey(brxcomkey) - self._brxnvda = c.cdll.LoadLibrary(str(value+"\\brxnvda.dll")) - if(self._brxnvda.brxnvda_init(str(value+"\\BrxCom.dll").decode("mbcs"))==0): + with winreg.OpenKey( + winreg.HKEY_LOCAL_MACHINE, + r"SOFTWARE\FHP\BrxCom" + ) as brxcomkey: + value, vtype = winreg.QueryValueEx(brxcomkey, "InstallPath") + assert vtype == winreg.REG_SZ # value is of type: str + self._brxnvda = ctypes.cdll.LoadLibrary(value + r"\brxnvda.dll") + if self._brxnvda.brxnvda_init(value + r"\BrxCom.dll"): self._baud=1 #prevent bluetooth from connecting - self.numCells=self._brxnvda.brxnvda_numCells(); - self._voffset=self._brxnvda.brxnvda_numVertCells(); + self.numCells=self._brxnvda.brxnvda_numCells() + self._voffset=self._brxnvda.brxnvda_numVertCells() log.info("Found Braille Display connected via BRXCom") self.startTimer() return None @@ -238,7 +161,7 @@ def connectBluetooth(self): except: log.debugWarning("connectBluetooth failed") - def connectUSB(self,devlist): + def connectUSB(self, devlist: List[bytes]): """try to connect to usb device,is triggered when BRXCOM is not installed and bluetooth connection could not be established""" try: @@ -259,7 +182,7 @@ def __init__(self): self._baud = 0 self._dev = None self._proto = None - devlist = [] + devlist: List[bytes] = [] self.connectBrxCom() if(self._baud == 1): return #brxcom is running, skip bluetooth and USB @@ -277,8 +200,8 @@ def __init__(self): #request type of braille display self._dev.write(brl_auto_id()) time.sleep(0.05)# wait 50 ms in order to get response for further actions - autoid=brl_poll(self._dev) - if(autoid == ''): + autoid: bytes = brl_poll(self._dev) + if autoid == b'': #no response, assume a Trio is connected self._baud = 115200 self._dev.set_baud_rate(self._baud) @@ -288,11 +211,10 @@ def __init__(self): self._dev.write(brl_auto_id()) self._dev.write(brl_auto_id()) time.sleep(0.05)# wait 50 ms in order to get response for further actions - autoid=brl_poll(self._dev) - if(len(autoid) != 8): - return None + autoid = brl_poll(self._dev) + if len(autoid) != 8: + return else: - autoid = struct.unpack('BBBBBBBB',autoid) if(autoid[3] == 0x35 and autoid[4] == 0x38):#EL80s self.numCells = 80 self._nlk = 1 @@ -424,21 +346,21 @@ def terminate(self): try: super(BrailleDisplayDriver, self).terminate() self.stopTimer() - if(self._dev!=None): self._dev.close() + if(self._dev is not None): self._dev.close() self._dev=None if(self._brxnvda): self._brxnvda.brxnvda_close() except: self._dev=None - def display(self, cells): + def display(self, cells: List[int]): """write to braille display""" if(self._brxnvda): - newcells = "".join([chr(cell) for cell in cells]) + newcells = bytes(cells) self._brxnvda.brxnvda_sendToDisplay(newcells) return if(self._dev is None): return try: - self._dev.write(brl_out(cells, self._nlk, self._nrk,self._voffset)) + self._dev.write(brl_out(cells, self._nlk, self._nrk, self._voffset)) except: self._dev.close() self._dev=None @@ -451,18 +373,18 @@ def _handleKeyPresses(self): """handles key presses and performs a gesture""" try: if(self._brxnvda): - k = self._brxnvda.brxnvda_keyIndex() + k: int = self._brxnvda.brxnvda_keyIndex() if(k!=-1): self.executeGesture(InputGesture(k,self)) return if(self._dev is None and self._baud>0): try: - devlist = ftdi2.list_devices() + devlist: List[bytes] = ftdi2.list_devices() if(len(devlist)>0): self.connectUSB(devlist) except: return - s = brl_poll(self._dev) + s: bytes = brl_poll(self._dev) if s: self._repeatcount=0 ig = InputGesture(s,self) @@ -508,37 +430,130 @@ def _handleKeyPresses(self): } }) +def brl_decode_trio(keys: bytes)->List[int]: + """decode routing keys on Trio""" + if keys[0] == ord(b'K'): # KEYSTATE CHANGED EVENT on Trio, not Braille keys + keys = keys[3:] + i = 0 + j = [] + for k in keys: + a = k & 0x0F + #convert bitstream to list of indexes + if(a & 1): j.append(i+3) + if(a & 2): j.append(i+2) + if(a & 4): j.append(i+1) + if(a & 8): j.append(i) + i +=4 + return j + return [] + +def brl_decode_keys_A(data: bytes, start: int, voffset: int) -> List[int]: + """decode routing keys non Trio devices""" + n = start #key index iterator + j = [] + shift = 0 + for i, value in enumerate(data): + if(i%2==0): + a = value & 0x0F # n+4,n+3 + b = data[i+1] & 0x0F # n+2,n+1 + #convert bitstream to list of indexes + if(n > 26): shift=voffset + if(b & 1): j.append(n+0-shift) + if(b & 2): j.append(n+1-shift) + if(b & 4): j.append(n+2-shift) + if(b & 8): j.append(n+3-shift) + if(a & 1): j.append(n+4-shift) + if(a & 2): j.append(n+5-shift) + if(a & 4): j.append(n+6-shift) + if(a & 8): j.append(n+7-shift) + n+=8 + return j + +def brl_decode_key_names_repeat(driver: BrailleDisplayDriver) -> List[str]: + """translate key names for protocol A with repeat""" + driver._repeatcount+=1 + if(driver._repeatcount < 10): + return [] + else: + driver._repeatcount = 0 + dec = [] + for key in driver.decodedkeys: + try: + dec.append(driver._keynamesrepeat[key]) + except: + pass + return dec + +def brl_decode_key_names(driver: BrailleDisplayDriver) -> List[str]: + """translate key names for protocol A""" + dec = [] + keys = driver.decodedkeys + for key in keys: + try: + dec.append(driver._keynames[key]) + except: + pass + return dec + +def brl_join_keys(dec: List[str]) -> str: + """join key names with comma, this is used for key combinations""" + if(len(dec) == 1): return dec[0] + elif(len(dec) == 3 and dec[0] == dec[1]): return dec[0] + "," + dec[2] + elif(len(dec) == 3 and dec[0] == dec[2]): return dec[0] + "," + dec[1] + elif(len(dec) == 2): return dec[1] + "," + dec[0] + else: return '' + +def brl_keyname_decoded(key: int, rest: str) -> str: + """convert index used by brxcom to keyname""" + if(key == 11 or key == 9): return 'l1' + rest + elif(key == 12 or key == 10): return 'l2' + rest + elif(key == 13 or key == 15): return 'r1' + rest + elif(key == 14 or key == 16): return 'r2' + rest + + elif(key == 3): return 'up' + rest + elif(key == 7): return 'dn' + rest + elif(key == 1): return 'left' + rest + elif(key == 5): return 'right' + rest + + elif(key == 4): return 'up2' + rest + elif(key == 8): return 'dn2' + rest + elif(key == 2): return 'left2' + rest + elif(key == 6): return 'right2' + rest + else: return '' + + class InputGesture(braille.BrailleDisplayGesture, brailleInput.BrailleInputGesture): """Input gesture for papenmeier displays""" source = BrailleDisplayDriver.name - def __init__(self, keys, driver): + def __init__(self, keys: Optional[Union[bytes, int]], driver: BrailleDisplayDriver): """create an input gesture and decode keys""" super(InputGesture, self).__init__() self.id='' - if(keys is None): + if keys is None: self.id=brl_join_keys(brl_decode_key_names_repeat(driver)) return if driver._baud != 1 and keys[0] == 'L': - if ((ord(keys[3]) -48) >>3): - scancode=ord(keys[5])-48 << 4| ord(keys[6])-48 - press = not ord(keys[4]) & 1 - ext = bool(ord(keys[4]) & 2) + assert isinstance(keys, bytes) + if (keys[3] - 48) >> 3: + scancode = keys[5] - 48 << 4 | keys[6] - 48 + press = not keys[4] & 1 + ext = bool(keys[4] & 2) keyboardHandler.injectRawKeyboardInput(press,scancode,ext) return #get dots - z = ord('0') - b = ord(keys[4])-z - c = ord(keys[5])-z - d = ord(keys[6])-z + z = ord(b'0') + b = keys[4] - z + c = keys[5] - z + d = keys[6] - z dots = c << 4 | d - thumbs = b&7 + thumbs = b & 7 if thumbs and dots: names = set() - names.update(driver._thumbs[1 << i] for i in xrange(3) if (1 << i) & thumbs) - names.update(driver._dotNames[1 << i] for i in xrange(8)if (1 << i) & dots) + names.update(driver._thumbs[1 << i] for i in range(3) if (1 << i) & thumbs) + names.update(driver._dotNames[1 << i] for i in range(8)if (1 << i) & dots) self.id = "+".join(names) self.space = True self.dots = dots @@ -551,35 +566,41 @@ def __init__(self, keys, driver): return if(driver._baud==1):#brxcom + assert isinstance(keys, int) if(keys>255 and keys<512): self.routingIndex = keys-256-driver._voffset self.id = "route" - return None + return elif(keys>511 and keys <786): self.routingIndex = keys-512-driver._voffset self.id="upperRouting" - return None + return else: key1 = (keys & 0xFFFF0000) >> 16 key2 = keys & 0x0000FFFF self.id=brl_keyname_decoded(key1, ',')+brl_keyname_decoded(key2, '') - return None + return if(driver._proto == 'A'):#non trio + assert isinstance(keys, bytes) decodedkeys = brl_decode_keys_A(keys[3:], 4, driver._voffset*2) elif(driver._proto=='B'):#trio + assert isinstance(keys, bytes) decodedkeys = brl_decode_trio(keys) + else: + decodedkeys: List[int] = [] - if(len(decodedkeys)==1 and decodedkeys[0]>=32 and decodedkeys[0]<32+driver.numCells*2): + length = len(decodedkeys) + if length == 1 and 32 <= decodedkeys[0] < 32 + driver.numCells * 2: #routing keys - self.routingIndex = (decodedkeys[0]-32)/2 + self.routingIndex = (decodedkeys[0] - 32) // 2 self.id = "route" if(decodedkeys[0] % 2 == 1): self.id="upperRouting" #other keys - elif(len(decodedkeys) > 0 and len(decodedkeys) >= len(driver.decodedkeys)): + elif length > 0 and length >= len(driver.decodedkeys): driver.decodedkeys.extend(decodedkeys) - elif(len(decodedkeys) == 0 and len(driver.decodedkeys)>0): + elif length == 0 and len(driver.decodedkeys) > 0: self.id=brl_join_keys(brl_decode_key_names(driver)) driver.decodedkeys=[] diff --git a/source/brailleDisplayDrivers/papenmeier_serial.py b/source/brailleDisplayDrivers/papenmeier_serial.py index c751893b2e7..a708f6b00b6 100644 --- a/source/brailleDisplayDrivers/papenmeier_serial.py +++ b/source/brailleDisplayDrivers/papenmeier_serial.py @@ -9,16 +9,14 @@ from collections import OrderedDict import time -import itertools +from typing import List, Optional + import wx import braille import hwPortUtils from logHandler import log from baseObject import ScriptableObject import inputCore -import globalCommands -import scriptHandler -import struct import serial #Control Flow @@ -28,31 +26,33 @@ KEY_CHECK_INTERVAL = 10 TIMEOUT = 0.5 -def brl_auto_id(): +def brl_auto_id() -> bytes: """send auto id command to braille display""" - return chr(STX)+'S'+chr(0)+chr(0)+chr(0)+chr(0)+chr(ETX) #send a bad packet to the braille display - -def brl_out(offset, data): - """send data to braille display""" - ret = [] - ret.append(struct.pack('BB', STX, 0x53)) #STX,'S' + return bytes([STX, ord(b'S'), 0x0, 0x0, 0x0, 0x0, ETX]) + +def brl_out(offset: int, data: List[int]) -> bytes: + """send data to braille display + @param offset: Must be positive. + """ d2 = len(data)+7 - ret.append(struct.pack('BB', offset / 256, offset % 256)) - ret.append(struct.pack('BB', 0, d2 % 256)) - for d in data: - ret.append(struct.pack('B', d)) - ret.append(struct.pack('B', ETX)) - return "".join(ret) + ret = bytearray([ + STX, + ord(b'S') + ]) + ret.extend(offset.to_bytes(2, "big", signed=False)) + ret.extend(d2.to_bytes(2, "big", signed=False)) + ret.extend(data) + ret.append(ETX) + return bytes(ret) -def brl_poll(dev): +def brl_poll(dev: serial.Serial) -> bytes: """read data from braille display, used by keypress handler""" - if dev.in_waiting < 10: return "" - ret = [] - ret.append(dev.read(dev.in_waiting)) - if ret[0][0] == chr(STX) and ret[0][9] == chr(ETX): - return "".join(ret) - return "" + if dev.in_waiting < 10: return b"" + ret = dev.read(dev.in_waiting) + if ret[0] == STX and ret[9] == ETX: + return ret + return b"" class BrailleDisplayDriver(braille.BrailleDisplayDriver, ScriptableObject): """papenmeier_serial braille display driver. @@ -76,8 +76,7 @@ def getPossiblePorts(cls): def initTable(self): """do not use braille builtin table""" - table = [] - for i in xrange(0, self.numCells): table +=[1] + table = [1] * self.numCells self._dev.write(brl_out(512+self._offsetHorizontal, table)) def __init__(self, port): @@ -98,8 +97,8 @@ def __init__(self, port): else: time.sleep(0.03) displaytype = brl_poll(self._dev) dic = -1 - if(len(displaytype)==10 and ord(displaytype[0])==STX and displaytype[1]=='I'): - dic = ord(displaytype[2]) + if len(displaytype) == 10 and displaytype[0] == STX and displaytype[1] == ord(b'I'): + dic = displaytype[2] self._eab = (baud == 38400) if(dic == -1): self._dev.close() @@ -162,7 +161,7 @@ def terminate(self): except: pass - def display(self, cells): + def display(self, cells: List[int]): """write data to braille display""" if(self._dev!=None): try: @@ -182,11 +181,11 @@ def _handleKeyPresses(self): #called by the keycheck timer """if a button was pressed an input gesture is executed""" if(self._dev!=None): data = brl_poll(self._dev) - if(len(data) == 10 and data[1]=='K'): - pos = ord(data[2])*256+ord(data[3]) + if len(data) == 10 and data[1] == ord(b'K'): + pos = data[2] * 256 + data[3] pos = (pos-768)/3 - pressed = ord(data[6]) - keys = ord(data[8]) + pressed = data[6] + keys = data[8] self._repeatcount = 0 self.executeGesture(InputGesture(pos, pressed, keys, self)) elif(len(data) == 0): @@ -221,7 +220,7 @@ def _handleKeyPresses(self): #called by the keycheck timer } }) -def brl_keyname2(keys): +def brl_keyname2(keys: int) -> str: """returns keyname for key index on displays with eab""" if(keys & 4 == 4): return 'l1' if(keys & 8 == 8): return 'l2' @@ -229,7 +228,7 @@ def brl_keyname2(keys): if(keys & 32 == 32): return 'r2' return '' -def brl_keyname(keyindex, driver): +def brl_keyname(keyindex: int, driver: BrailleDisplayDriver) -> str: """returns keyname for key index""" if(driver._eab): if(keyindex==-255): return "left" @@ -253,7 +252,13 @@ class InputGesture(braille.BrailleDisplayGesture): source = BrailleDisplayDriver.name - def __init__(self, keyindex, pressed, keys, driver): + def __init__( + self, + keyindex: Optional[int], + pressed: Optional[int], + keys: Optional[int], + driver: BrailleDisplayDriver + ): super(InputGesture, self).__init__() self.id = '' if(keyindex is None): @@ -266,7 +271,7 @@ def __init__(self, keyindex, pressed, keys, driver): self.routingIndex -= 256 self.id = "upperRouting" elif(pressed == 0): - k = brl_keyname(keyindex, driver) + k: str = brl_keyname(keyindex, driver) if(driver._lastkey!=k): if(driver._lastkey!=''): self.id=driver._lastkey+','+k else: diff --git a/source/brailleDisplayDrivers/seika.py b/source/brailleDisplayDrivers/seika.py index 664d89e2026..60495e6f836 100644 --- a/source/brailleDisplayDrivers/seika.py +++ b/source/brailleDisplayDrivers/seika.py @@ -13,7 +13,8 @@ # see www.seika-braille.com for more details # 18.08.2012 13:54 -import time +from typing import List + import wx import serial import braille @@ -51,7 +52,7 @@ def __init__(self): except serial.SerialException: continue log.debug("serial port open {port}".format(port=port)) - self._ser.write("\xFF\xFF\x1C") + self._ser.write(b"\xFF\xFF\x1C") self._ser.flush() # Read out the input buffer versionS = self._ser.read(13) @@ -63,19 +64,22 @@ def __init__(self): if versionS.startswith("seika3"): log.info("Found Seika40 connected via {port} Version {versionS}".format(port=port, versionS=versionS)) self.numCells = 40 - self.s40 = "\xFF\xFF\x73\x65\x69\x6B\x61\x00" + self.s40 = b"\xFF\xFF\x73\x65\x69\x6B\x61\x00" break # is it a old Seika3? log.debug("test if it is a old Seika3") - self._ser.write("\xFF\xFF\x0A") + self._ser.write(b"\xFF\xFF\x0A") self._ser.flush() # Read out the input buffer versionS = self._ser.read(12) log.debug("receive {p}".format(p=versionS)) - if versionS.startswith("\x00\x05\x28\x08\x76\x35\x2E\x30\x01\x01\x01\x01") or versionS.startswith("\x00\x05\x28\x08\x73\x65\x69\x6b\x61\x00"): + if versionS.startswith(( + b"\x00\x05\x28\x08\x76\x35\x2E\x30\x01\x01\x01\x01", + b"\x00\x05\x28\x08\x73\x65\x69\x6b\x61\x00" + )): log.info("Found Seika3 old Version connected via {port} Version {versionS}".format(port=port, versionS=versionS)) self.numCells = 40 - self.s40 = "\xFF\xFF\x04\x00\x63\x00\x50\x00" + self.s40 = b"\xFF\xFF\x04\x00\x63\x00\x50\x00" break self._ser.close() else: @@ -91,27 +95,31 @@ def terminate(self): finally: self._ser.close() - def display(self, cells): + def display(self, cells: List[int]): # every transmitted line consists of the preamble SEIKA_SENDHEADER and the Cells if self.numCells==80: - line = "\xff\xff\x73\x38\x30\x00\x00\x00"+"".join(chr(cell) for cell in cells) + lineBytes = b"".join([ + b"\xff\xff\x73\x38\x30\x00\x00\x00", + bytes(cells) + ]) else: - line = self.s40+"".join("\0"+chr(cell) for cell in cells) - self._ser.write(line) + lineBytes = b"".join([ + self.s40, + b"\0", + bytes(cells) + ]) + self._ser.write(lineBytes) def handleResponses(self): if not self._ser.in_waiting: return - chars = [0,0] key = 0 - keys= set() - max = self.numCells / 4 # for 80 max is 20, for 40 cell max is 10 - chars[0] = ord(self._ser.read()) - chars[1] = ord(self._ser.read()) + keys = set() + maxCellRead = self.numCells // 4 # for 80 maxCellRead is 20, for 40 cell maxCellRead is 10 + chars: bytes = self._ser.read(2) keytyp=1 if not chars[0] & 0x60: # a cursorrouting block is expected - char = self._ser.read(max) - chars = [ord(c) for c in char] + chars: bytes = self._ser.read(maxCellRead) keytyp=2 # log.info("Seika K {c}".format(c=chars)) if keytyp == 1: # normal key @@ -139,7 +147,7 @@ def handleResponses(self): pass else: i = 0 - k = max / 2 + k = maxCellRead // 2 while i < k: j = 0 while j < 8: diff --git a/source/brailleDisplayDrivers/superBrl.py b/source/brailleDisplayDrivers/superBrl.py index 1200d298b07..e040ab60bd5 100644 --- a/source/brailleDisplayDrivers/superBrl.py +++ b/source/brailleDisplayDrivers/superBrl.py @@ -3,24 +3,24 @@ #This file is covered by the GNU General Public License. #See the file COPYING for more details. #Copyright (C) 2017 NV Access Limited, Coscell Kao, Babbage B.V. +from typing import List import serial -from collections import OrderedDict import braille import hwIo +from hwIo import intToByte import time import inputCore from logHandler import log -import bdDetect BAUD_RATE = 9600 TIMEOUT = 0.5 # Tags sent by the SuperBraille # Sent to identify the display and receive amount of cells this unit has -DESCRIBE_TAG = "\xff\xff\x0a" +DESCRIBE_TAG = b"\xff\xff\x0a" # Sent to request displaying of cells -DISPLAY_TAG = "\xff\xff\x04\x00\x99\x00\x50\x00" +DISPLAY_TAG = b"\xff\xff\x04\x00\x99\x00\x50\x00" class BrailleDisplayDriver(braille.BrailleDisplayDriver): name = "superBrl" @@ -63,24 +63,24 @@ def terminate(self): self._dev.close() self._dev = None - def _onReceive(self,data): + def _onReceive(self, data: bytes): # The only info this display ever sends is number of cells and the display version. - # It sends 0x00, 0x05, number of cells, then version string of 8 bytes. - if data!='\x00': + # It sends 0x00, 0x05, number of cells, then version string of 8 bytes. + if data != b'\x00': return data=self._dev.read(1) - if data!='\x05': + if data!= b'\x05': return self.numCells = ord(self._dev.read(1)) self._dev.read(1) self.version=self._dev.read(8) - def display(self, cells): - out = [] + def display(self, cells: List[int]): + writeBytes: List[bytes] = [DISPLAY_TAG, ] for cell in cells: - out.append("\x00") - out.append(chr(cell)) - self._dev.write(DISPLAY_TAG + "".join(out)) + writeBytes.append(b"\x00") + writeBytes.append(intToByte(cell)) + self._dev.write(b"".join(writeBytes)) gestureMap = inputCore.GlobalGestureMap({ "globalCommands.GlobalCommands": { diff --git a/source/brailleInput.py b/source/brailleInput.py index 8646e7950a7..a2b7d6dcbc0 100644 --- a/source/brailleInput.py +++ b/source/brailleInput.py @@ -7,6 +7,8 @@ import os.path import time +from typing import Optional, List, Set + import louis import brailleTables import braille @@ -36,25 +38,21 @@ #: @type: int UNICODE_BRAILLE_START = 0x2800 #: The Unicode braille character to use when masking cells in protected fields. -#: @type: unicode +#: @type: str UNICODE_BRAILLE_PROTECTED = u"⣿" # All dots down -#: The singleton BrailleInputHandler instance. -#: @type: L{BrailleInputHandler} -handler = None - -def initialize(): - global handler - handler = BrailleInputHandler() - log.info("Braille input initialized") - -def terminate(): - global handler - handler = None class BrailleInputHandler(AutoPropertyObject): """Handles braille input. """ + bufferBraille: List[int] + bufferText: str + cellsWithText: Set[int] + untranslatedBraille: str + untranslatedStart: int + untranslatedCursorPos: int + _uncontSentTime: Optional[float] + currentModifiers: Set[str] def __init__(self): super(BrailleInputHandler,self).__init__() @@ -82,7 +80,6 @@ def __init__(self): #: or were translated but did not produce any text. #: This is used to show these cells to the user while they're entering braille. #: This is a string of Unicode braille. - #: @type: unicode self.untranslatedBraille = "" #: The position in L{brailleBuffer} where untranslated braille begins. self.untranslatedStart = 0 @@ -95,30 +92,37 @@ def __init__(self): self.currentModifiers = set() config.post_configProfileSwitch.register(self.handlePostConfigProfileSwitch) + # Provided by auto property: L{_get_table} and L{_set_table} + table: brailleTables.BrailleTable + def _get_table(self): """The translation table to use for braille input. @rtype: L{brailleTables.BrailleTable} """ return self._table - def _set_table(self, table): + def _set_table(self, table: brailleTables.BrailleTable): self._table = table config.conf["braille"]["inputTable"] = table.fileName + # Provided by auto property: L{_get_currentFocusIsTextObj} + currentFocusIsTextObj: bool + def _get_currentFocusIsTextObj(self): focusObj = api.getFocusObject() return focusObj._hasNavigableText and (not focusObj.treeInterceptor or focusObj.treeInterceptor.passThrough) + # Provided by auto property: L{_get_useContractedForCurrentFocus} + useContractedForCurrentFocus: bool + def _get_useContractedForCurrentFocus(self): return self._table.contracted and self.currentFocusIsTextObj and not self.currentModifiers - def _translate(self, endWord): + def _translate(self, endWord: bool) -> bool: """Translate buffered braille up to the cursor. Any text produced is sent to the system. @param endWord: C{True} if this is the end of a word, C{False} otherwise. - @type endWord: bool @return: C{True} if translation produced text, C{False} if not. - @rtype: bool """ assert not self.useContractedForCurrentFocus or endWord, "Must only translate contracted at end of word" if self.useContractedForCurrentFocus: @@ -126,7 +130,7 @@ def _translate(self, endWord): self.bufferText = u"" oldTextLen = len(self.bufferText) pos = self.untranslatedStart + self.untranslatedCursorPos - data = u"".join([unichr(cell | LOUIS_DOTS_IO_START) for cell in self.bufferBraille[:pos]]) + data = u"".join([chr(cell | LOUIS_DOTS_IO_START) for cell in self.bufferBraille[:pos]]) mode = louis.dotsIO | louis.noUndefinedDots if (not self.currentFocusIsTextObj or self.currentModifiers) and self._table.contracted: mode |= louis.partialTrans @@ -175,10 +179,10 @@ def _translate(self, endWord): def _translateForReportContractedCell(self, pos): """Translate text for current input as required by L{_reportContractedCell}. @return: The previous translated text. - @rtype: unicode + @rtype: str """ cells = self.bufferBraille[:pos + 1] - data = u"".join([unichr(cell | LOUIS_DOTS_IO_START) for cell in cells]) + data = u"".join([chr(cell | LOUIS_DOTS_IO_START) for cell in cells]) oldText = self.bufferText text = louis.backTranslate( [os.path.join(brailleTables.TABLES_DIR, self._table.fileName), @@ -228,7 +232,7 @@ def _reportUntranslated(self, pos): self._updateUntranslated() self.updateDisplay() - def input(self, dots): + def input(self, dots: int): """Handle one cell of braille input. """ # Insert the newly entered cell into the buffer at the cursor position. @@ -257,9 +261,9 @@ def input(self, dots): else: self._reportUntranslated(pos) - def toggleModifier(self, modifier): + def toggleModifier(self, modifier: str): # Check modifier validity - isModifier = keyboardHandler.KeyboardInputGesture.fromName(modifier).isModifier + isModifier: bool = keyboardHandler.KeyboardInputGesture.fromName(modifier).isModifier if not isModifier: raise ValueError("%r is not a valid modifier"%modifier) if modifier in self.currentModifiers: @@ -293,7 +297,7 @@ def _updateUntranslated(self): if api.isTypingProtected(): self.untranslatedBraille = UNICODE_BRAILLE_PROTECTED * (len(self.bufferBraille) - self.untranslatedStart) else: - self.untranslatedBraille = "".join([unichr(UNICODE_BRAILLE_START + dots) for dots in self.bufferBraille[self.untranslatedStart:]]) + self.untranslatedBraille = "".join([chr(UNICODE_BRAILLE_START + dots) for dots in self.bufferBraille[self.untranslatedStart:]]) def updateDisplay(self): """Update the braille display to reflect untranslated input. @@ -331,7 +335,7 @@ def eraseLastCell(self): self.untranslatedCursorPos = 0 # This might leave us with some untranslated braille. # For example, in English grade 1, erasing the number 1 leaves us with a number sign. - for prevIndex in xrange(index - 1, -1, -1): + for prevIndex in range(index - 1, -1, -1): if prevIndex in self.cellsWithText: # This cell produced text, so stop. break @@ -361,13 +365,12 @@ def flushBuffer(self): self.untranslatedStart = 0 self.untranslatedCursorPos = 0 - def emulateKey(self, key, withModifiers=True): + def emulateKey(self, key: str, withModifiers: bool = True): """Emulates a key using the keyboard emulation system. If emulation fails (e.g. because of an unknown key), a debug warning is logged and the system falls back to sending unicode characters. @param withModifiers: Whether this key emulation should include the modifiers that are held virtually. Note that this method does not take care of clearing L{self.currentModifiers}. - @type withModifiers: bool """ if withModifiers: # The emulated key should be the last item in the identifier string. @@ -382,10 +385,9 @@ def emulateKey(self, key, withModifiers=True): log.debugWarning("Unable to emulate %r, falling back to sending unicode characters"%gesture, exc_info=True) self.sendChars(key) - def sendChars(self, chars): + def sendChars(self, chars: str): """Sends the provided unicode characters to the system. @param chars: The characters to send to the system. - @type chars: unicode """ inputs = [] for ch in chars: @@ -399,10 +401,15 @@ def sendChars(self, chars): winUser.SendInput(inputs) def handleGainFocus(self, obj): - # Clear all state when the focus changes. + """ Clear all state when the focus changes. + :type obj: NVDAObjects.NVDAObject + """ self.flushBuffer() def handleCaretMove(self, obj): + """ + :type obj: NVDAObjects.NVDAObject + """ if not self.bufferBraille: # No pending braille input, so nothing to do. return @@ -424,14 +431,27 @@ def handlePostConfigProfileSwitch(self): if table != self._table.fileName: self._table = brailleTables.getTable(table) -def formatDotNumbers(dots): + +#: The singleton BrailleInputHandler instance. +handler: Optional[BrailleInputHandler] = None + +def initialize(): + global handler + handler = BrailleInputHandler() + log.info("Braille input initialized") + +def terminate(): + global handler + handler = None + +def formatDotNumbers(dots: int): out = [] - for dot in xrange(8): + for dot in range(8): if dots & (1 << dot): out.append(str(dot + 1)) return " ".join(out) -def speakDots(dots): +def speakDots(dots: int): # Translators: Used when reporting braille dots to the user. speech.speakMessage(_("dot") + " " + formatDotNumbers(dots)) @@ -450,7 +470,7 @@ class BrailleInputGesture(inputCore.InputGesture): space = False def _makeDotsId(self): - items = ["dot%d" % (i+1) for i in xrange(8) if self.dots & (1 << i)] + items = ["dot%d" % (i+1) for i in range(8) if self.dots & (1 << i)] if self.space: items.append("space") return "bk:" + "+".join(items) @@ -474,7 +494,8 @@ def _get_identifiers(self): return () @classmethod - def _makeDisplayText(cls, dots, space): + def _makeDisplayText(cls, dots: int, space: bool): + out = "" if space and dots: # Translators: Reported when braille space is pressed with dots in input help mode. out = _("space with dot") @@ -494,7 +515,8 @@ def _get_displayName(self): return self._makeDisplayText(self.dots, self.space) @classmethod - def getDisplayTextForIdentifier(cls, identifier): + def getDisplayTextForIdentifier(cls, identifier: str): + assert isinstance(identifier, str) # Translators: Used when describing keys on a braille keyboard. source = _("braille keyboard") if identifier == cls.GENERIC_ID_SPACE_DOTS: diff --git a/source/brailleTables.py b/source/brailleTables.py index 560e4b270ad..49d8830eb3a 100644 --- a/source/brailleTables.py +++ b/source/brailleTables.py @@ -56,9 +56,7 @@ def listTables(): @return: A list of braille tables. @rtype: list of L{BrailleTable} """ - tables = _tables.values() - tables.sort(key=lambda table: table.displayName) - return tables + return sorted(_tables.values(), key=lambda table: table.displayName) #: Maps old table names to new table names for tables renamed in newer versions of liblouis. RENAMED_TABLES = { diff --git a/source/browseMode.py b/source/browseMode.py index b647431edbc..6126a8b386e 100644 --- a/source/browseMode.py +++ b/source/browseMode.py @@ -35,7 +35,6 @@ import gui.guiHelper from NVDAObjects import NVDAObject from abc import ABCMeta, abstractmethod -from six import with_metaclass REASON_QUICKNAV = "quickNav" @@ -93,7 +92,7 @@ def mergeQuickNavItemIterators(iterators,direction="next"): continue curValues.append((it,newVal)) -class QuickNavItem(with_metaclass(ABCMeta, object)): +class QuickNavItem(object, metaclass=ABCMeta): """ Emitted by L{BrowseModeTreeInterceptor._iterNodesByType}, this represents one of many positions in a browse mode document, based on the type of item being searched for (e.g. link, heading, table etc).""" itemType=None #: The type of items searched for (e.g. link, heading, table etc) @@ -1025,7 +1024,7 @@ def onTreeChar(self, evt): else: # Search the list. # We have to implement this ourselves, as tree views don't accept space as a search character. - char = unichr(evt.UnicodeKey).lower() + char = chr(evt.UnicodeKey).lower() # IF the same character is typed twice, do the same search. if self._searchText != char: self._searchText += char @@ -1648,7 +1647,12 @@ def _get_shouldRememberCaretPositionAcrossLoads(self): docConstId = self.documentConstantIdentifier # Return True if the URL indicates that this is probably a web browser document. # We do this check because we don't want to remember caret positions for email messages, etc. - return isinstance(docConstId, basestring) and docConstId.split("://", 1)[0] in ("http", "https", "ftp", "ftps", "file") + if isinstance(docConstId, str): + protocols=("http", "https", "ftp", "ftps", "file") + protocol=docConstId.split("://", 1)[0] + return protocol in protocols + return False + def _getInitialCaretPos(self): """Retrieve the initial position of the caret after the buffer has been loaded. @@ -1664,14 +1668,14 @@ def _getInitialCaretPos(self): pass return None - def getEnclosingContainerRange(self,range): - range=range.copy() - range.collapse() + def getEnclosingContainerRange(self, textRange): + textRange = textRange.copy() + textRange.collapse() try: - item = next(self._iterNodesByType("container", "up", range)) + item = next(self._iterNodesByType("container", "up", textRange)) except (NotImplementedError,StopIteration): try: - item = next(self._iterNodesByType("landmark", "up", range)) + item = next(self._iterNodesByType("landmark", "up", textRange)) except (NotImplementedError,StopIteration): return return item.textInfo @@ -1720,8 +1724,8 @@ def script_movePastEndOfContainer(self,gesture): script_movePastEndOfContainer.__doc__=_("Moves past the end of the container element, such as a list or table") NOT_LINK_BLOCK_MIN_LEN = 30 - def _isSuitableNotLinkBlock(self,range): - return len(range.text)>=self.NOT_LINK_BLOCK_MIN_LEN + def _isSuitableNotLinkBlock(self, textRange): + return len(textRange.text) >= self.NOT_LINK_BLOCK_MIN_LEN def _iterNotLinkBlock(self, direction="next", pos=None): links = self._iterNodesByType("link", direction=direction, pos=pos) @@ -1731,15 +1735,15 @@ def _iterNotLinkBlock(self, direction="next", pos=None): item2 = next(links) # If the distance between the links is small, this is probably just a piece of non-link text within a block of links; e.g. an inactive link of a nav bar. if direction=="previous": - range=item1.textInfo.copy() - range.collapse() - range.setEndPoint(item2.textInfo,"startToEnd") + textRange=item1.textInfo.copy() + textRange.collapse() + textRange.setEndPoint(item2.textInfo,"startToEnd") else: - range=item2.textInfo.copy() - range.collapse() - range.setEndPoint(item1.textInfo,"startToEnd") - if self._isSuitableNotLinkBlock(range): - yield TextInfoQuickNavItem("notLinkBlock",self,range) + textRange=item2.textInfo.copy() + textRange.collapse() + textRange.setEndPoint(item1.textInfo,"startToEnd") + if self._isSuitableNotLinkBlock(textRange): + yield TextInfoQuickNavItem("notLinkBlock", self, textRange) item1=item2 __gestures={ diff --git a/source/buildVersion.py b/source/buildVersion.py index dde2044d8df..65bd1d85228 100644 --- a/source/buildVersion.py +++ b/source/buildVersion.py @@ -18,14 +18,16 @@ def _updateVersionFromVCS(): # The root of the Git working tree will be the parent of this module's directory. gitDir = os.path.join(os.path.dirname(os.path.dirname(__file__)), ".git") try: - head = file(os.path.join(gitDir, "HEAD"), "r").read().rstrip() + with open(os.path.join(gitDir, "HEAD"), "r") as f: + head = f.read().rstrip() if not head.startswith("ref: "): # Detached head. version = "source-DETACHED-%s" % head[:7] return # Strip the "ref: " prefix to get the ref. ref = head[5:] - commit = file(os.path.join(gitDir, ref), "r").read().rstrip() + with open(os.path.join(gitDir, ref), "r") as f: + commit = f.read().rstrip() version = "source-%s-%s" % ( os.path.basename(ref), commit[:7]) @@ -61,8 +63,6 @@ def formatVersionForGUI(year, major, minor): return "{y}.{M}.{m}".format(y=year, M=major, m=minor) -# ticket:3763#comment:19: name must be str, not unicode. -# Otherwise, py2exe will break. name="NVDA" version_year=2019 version_major=2 diff --git a/source/characterProcessing.py b/source/characterProcessing.py index d8c830a1b85..21e1e39690e 100644 --- a/source/characterProcessing.py +++ b/source/characterProcessing.py @@ -252,7 +252,7 @@ def _loadSymbolField(self, input, inputMap=None): "#": "#", "\\": "\\", } - IDENTIFIER_ESCAPES_OUTPUT = {v: k for k, v in IDENTIFIER_ESCAPES_INPUT.iteritems()} + IDENTIFIER_ESCAPES_OUTPUT = {v: k for k, v in IDENTIFIER_ESCAPES_INPUT.items()} LEVEL_INPUT = { "none": SYMLVL_NONE, "some": SYMLVL_SOME, @@ -260,13 +260,13 @@ def _loadSymbolField(self, input, inputMap=None): "all": SYMLVL_ALL, "char": SYMLVL_CHAR, } - LEVEL_OUTPUT = {v:k for k, v in LEVEL_INPUT.iteritems()} + LEVEL_OUTPUT = {v:k for k, v in LEVEL_INPUT.items()} PRESERVE_INPUT = { "never": SYMPRES_NEVER, "always": SYMPRES_ALWAYS, "norep": SYMPRES_NOREP, } - PRESERVE_OUTPUT = {v: k for k, v in PRESERVE_INPUT.iteritems()} + PRESERVE_OUTPUT = {v: k for k, v in PRESERVE_INPUT.items()} def _loadSymbol(self, line): line = line.split("\t") @@ -315,13 +315,13 @@ def save(self, fileName=None): with codecs.open(fileName, "w", "utf_8_sig", errors="replace") as f: if self.complexSymbols: f.write(u"complexSymbols:\r\n") - for identifier, pattern in self.complexSymbols.iteritems(): + for identifier, pattern in self.complexSymbols.items(): f.write(u"%s\t%s\r\n" % (identifier, pattern)) f.write(u"\r\n") if self.symbols: f.write(u"symbols:\r\n") - for symbol in self.symbols.itervalues(): + for symbol in self.symbols.values(): f.write(u"%s\r\n" % self._saveSymbol(symbol)) def _saveSymbolField(self, output, outputMap=None): @@ -429,7 +429,7 @@ def __init__(self, locale): # Add all complex symbols first, as they take priority. for source in sources: - for identifier, pattern in source.complexSymbols.iteritems(): + for identifier, pattern in source.complexSymbols.items(): if identifier in symbols: # Already defined. continue @@ -439,7 +439,7 @@ def __init__(self, locale): # Supplement the data for complex symbols and add all simple symbols. for source in sources: - for identifier, sourceSymbol in source.symbols.iteritems(): + for identifier, sourceSymbol in source.symbols.items(): try: symbol = symbols[identifier] # We're updating an already existing symbol. @@ -462,7 +462,8 @@ def __init__(self, locale): symbol.displayName = sourceSymbol.displayName # Set defaults for any fields not explicitly set. - for symbol in symbols.values(): + # As the symbols dictionary changes during iteration, wrap this inside a list call. + for symbol in list(symbols.values()): if symbol.replacement is None: # Symbols without a replacement specified are useless. log.warning(u"Replacement not defined in locale {locale} for symbol: {symbol}".format( @@ -507,7 +508,7 @@ def __init__(self, locale): # Simple symbols. # These are all handled in one named group. # Because the symbols are just text, we know which symbol matched just by looking at the matched text. - patterns.append(ur"(?P{multiChars}|{singleChars})".format( + patterns.append(r"(?P{multiChars}|{singleChars})".format( multiChars="|".join(re.escape(identifier) for identifier in multiChars), singleChars=characters )) @@ -616,7 +617,7 @@ def deleteSymbol(self, symbol): def isBuiltin(self, symbolIdentifier): """Determine whether a symbol is built in. @param symbolIdentifier: The identifier of the symbol in question. - @type symbolIdentifier: unicode + @type symbolIdentifier: str @return: C{True} if the symbol is built in, C{False} if it was added by the user. @rtype: bool diff --git a/source/comInterfaces/_944DE083_8FB8_45CF_BCB7_C477ACB2F897_0_1_0.py b/source/comInterfaces/_944DE083_8FB8_45CF_BCB7_C477ACB2F897_0_1_0.py index 28ffcf15af0..0cf9ce92cba 100644 --- a/source/comInterfaces/_944DE083_8FB8_45CF_BCB7_C477ACB2F897_0_1_0.py +++ b/source/comInterfaces/_944DE083_8FB8_45CF_BCB7_C477ACB2F897_0_1_0.py @@ -5,2261 +5,2185 @@ import comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0 from comtypes import GUID from ctypes import HRESULT -from comtypes.automation import _midlSAFEARRAY from comtypes import helpstring from comtypes import COMMETHOD from comtypes import dispid -from comtypes.automation import VARIANT +from comtypes import CoClass from ctypes.wintypes import tagPOINT -from comtypes import IUnknown +from comtypes.automation import _midlSAFEARRAY from comtypes import BSTR +WSTRING = c_wchar_p +from comtypes.automation import VARIANT +from comtypes import IUnknown from ctypes.wintypes import tagRECT from comtypes.automation import VARIANT -WSTRING = c_wchar_p from ctypes.wintypes import tagRECT -from comtypes import CoClass from comtypes.automation import IDispatch -UIA_BulletStyleAttributeId = 40002 # Constant c_int -UIA_AccessKeyPropertyId = 30007 # Constant c_int -StyleId_NumberedList = 70016 # Constant c_int -UIA_FormLandmarkTypeId = 80001 # Constant c_int -UIA_PositionInSetPropertyId = 30152 # Constant c_int -UIA_MainLandmarkTypeId = 80002 # Constant c_int - -# values for enumeration 'SupportedTextSelection' -SupportedTextSelection_None = 0 -SupportedTextSelection_Single = 1 -SupportedTextSelection_Multiple = 2 -SupportedTextSelection = c_int # enum -AnnotationType_ConflictingChange = 60018 # Constant c_int -UIA_NavigationLandmarkTypeId = 80003 # Constant c_int -class IUIAutomationProxyFactoryMapping(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): +class IUIAutomationSelectionPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): _case_insensitive_ = True - _iid_ = GUID('{09E31E18-872D-4873-93D1-1E541EC133FD}') + _iid_ = GUID('{5ED5202E-B2AC-47A6-B638-4B0BF140D78E}') _idlflags_ = [] -class IUIAutomationProxyFactoryEntry(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): +class IUIAutomationSelectionPattern2(IUIAutomationSelectionPattern): _case_insensitive_ = True - _iid_ = GUID('{D50E472E-B64B-490C-BCA1-D30696F9F289}') + _iid_ = GUID('{0532BFAE-C011-4E32-A343-6D642D798555}') _idlflags_ = [] -IUIAutomationProxyFactoryMapping._methods_ = [ - COMMETHOD(['propget'], HRESULT, 'count', - ( ['retval', 'out'], POINTER(c_uint), 'count' )), - COMMETHOD([], HRESULT, 'GetTable', - ( ['retval', 'out'], POINTER(_midlSAFEARRAY(POINTER(IUIAutomationProxyFactoryEntry))), 'table' )), - COMMETHOD([], HRESULT, 'GetEntry', - ( ['in'], c_uint, 'index' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationProxyFactoryEntry)), 'entry' )), - COMMETHOD([], HRESULT, 'SetTable', - ( ['in'], _midlSAFEARRAY(POINTER(IUIAutomationProxyFactoryEntry)), 'factoryList' )), - COMMETHOD([], HRESULT, 'InsertEntries', - ( ['in'], c_uint, 'before' ), - ( ['in'], _midlSAFEARRAY(POINTER(IUIAutomationProxyFactoryEntry)), 'factoryList' )), - COMMETHOD([], HRESULT, 'InsertEntry', - ( ['in'], c_uint, 'before' ), - ( ['in'], POINTER(IUIAutomationProxyFactoryEntry), 'factory' )), - COMMETHOD([], HRESULT, 'RemoveEntry', - ( ['in'], c_uint, 'index' )), - COMMETHOD([], HRESULT, 'ClearTable'), - COMMETHOD([], HRESULT, 'RestoreDefaultTable'), +class IUIAutomationElementArray(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{14314595-B4BC-4055-95F2-58F2E42C9855}') + _idlflags_ = [] +IUIAutomationSelectionPattern._methods_ = [ + COMMETHOD([], HRESULT, 'GetCurrentSelection', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentCanSelectMultiple', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentIsSelectionRequired', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD([], HRESULT, 'GetCachedSelection', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedCanSelectMultiple', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedIsSelectionRequired', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), ] ################################################################ -## code template for IUIAutomationProxyFactoryMapping implementation -##class IUIAutomationProxyFactoryMapping_Impl(object): +## code template for IUIAutomationSelectionPattern implementation +##class IUIAutomationSelectionPattern_Impl(object): +## def GetCurrentSelection(self): +## '-no docstring-' +## #return retVal +## ## @property -## def count(self): +## def CurrentCanSelectMultiple(self): ## '-no docstring-' -## #return count +## #return retVal ## -## def ClearTable(self): +## @property +## def CurrentIsSelectionRequired(self): ## '-no docstring-' -## #return +## #return retVal ## -## def GetEntry(self, index): +## def GetCachedSelection(self): ## '-no docstring-' -## #return entry +## #return retVal ## -## def InsertEntries(self, before, factoryList): +## @property +## def CachedCanSelectMultiple(self): ## '-no docstring-' -## #return +## #return retVal ## -## def RestoreDefaultTable(self): +## @property +## def CachedIsSelectionRequired(self): ## '-no docstring-' -## #return +## #return retVal ## -## def SetTable(self, factoryList): + +class IUIAutomationElement(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{D22108AA-8AC5-49A5-837B-37BBB3D7591E}') + _idlflags_ = [] +IUIAutomationSelectionPattern2._methods_ = [ + COMMETHOD(['propget'], HRESULT, 'CurrentFirstSelectedItem', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentLastSelectedItem', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentCurrentSelectedItem', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentItemCount', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedFirstSelectedItem', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedLastSelectedItem', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedCurrentSelectedItem', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedItemCount', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), +] +################################################################ +## code template for IUIAutomationSelectionPattern2 implementation +##class IUIAutomationSelectionPattern2_Impl(object): +## @property +## def CurrentFirstSelectedItem(self): ## '-no docstring-' -## #return +## #return retVal ## -## def GetTable(self): +## @property +## def CurrentLastSelectedItem(self): ## '-no docstring-' -## #return table +## #return retVal ## -## def InsertEntry(self, before, factory): +## @property +## def CurrentCurrentSelectedItem(self): ## '-no docstring-' -## #return +## #return retVal ## -## def RemoveEntry(self, index): +## @property +## def CurrentItemCount(self): ## '-no docstring-' -## #return +## #return retVal ## - -UIA_FontWeightAttributeId = 40007 # Constant c_int -class IUIAutomationCondition(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{352FFBA8-0973-437C-A61F-F64CAFD81DF9}') - _idlflags_ = [] -class IUIAutomationPropertyCondition(IUIAutomationCondition): - _case_insensitive_ = True - _iid_ = GUID('{99EBF2CB-5578-4267-9AD4-AFD6EA77E94B}') - _idlflags_ = [] -IUIAutomationCondition._methods_ = [ -] -################################################################ -## code template for IUIAutomationCondition implementation -##class IUIAutomationCondition_Impl(object): - - -# values for enumeration 'PropertyConditionFlags' -PropertyConditionFlags_None = 0 -PropertyConditionFlags_IgnoreCase = 1 -PropertyConditionFlags_MatchSubstring = 2 -PropertyConditionFlags = c_int # enum -IUIAutomationPropertyCondition._methods_ = [ - COMMETHOD(['propget'], HRESULT, 'propertyId', - ( ['retval', 'out'], POINTER(c_int), 'propertyId' )), - COMMETHOD(['propget'], HRESULT, 'PropertyValue', - ( ['retval', 'out'], POINTER(VARIANT), 'PropertyValue' )), - COMMETHOD(['propget'], HRESULT, 'PropertyConditionFlags', - ( ['retval', 'out'], POINTER(PropertyConditionFlags), 'flags' )), -] -################################################################ -## code template for IUIAutomationPropertyCondition implementation -##class IUIAutomationPropertyCondition_Impl(object): ## @property -## def PropertyConditionFlags(self): +## def CachedFirstSelectedItem(self): ## '-no docstring-' -## #return flags +## #return retVal ## ## @property -## def propertyId(self): +## def CachedLastSelectedItem(self): ## '-no docstring-' -## #return propertyId +## #return retVal ## ## @property -## def PropertyValue(self): +## def CachedCurrentSelectedItem(self): ## '-no docstring-' -## #return PropertyValue +## #return retVal +## +## @property +## def CachedItemCount(self): +## '-no docstring-' +## #return retVal ## -class IUIAutomationElement(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): +class CUIAutomation(CoClass): + 'The Central Class for UIAutomation' + _reg_clsid_ = GUID('{FF48DBA4-60EF-4201-AA87-54103EEF594E}') + _idlflags_ = [] + _typelib_path_ = typelib_path + _reg_typelib_ = ('{944DE083-8FB8-45CF-BCB7-C477ACB2F897}', 1, 0) +class IUIAutomation(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): _case_insensitive_ = True - _iid_ = GUID('{D22108AA-8AC5-49A5-837B-37BBB3D7591E}') + _iid_ = GUID('{30CBE57D-D9D0-452A-AB13-7AC5AC4825EE}') _idlflags_ = [] -class IUIAutomationElement2(IUIAutomationElement): +CUIAutomation._com_interfaces_ = [IUIAutomation] + +class IUIAutomationTextPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): _case_insensitive_ = True - _iid_ = GUID('{6749C683-F70D-4487-A698-5F79D55290D6}') + _iid_ = GUID('{32EBA289-3583-42C9-9C59-3B6D9A1E9B6A}') _idlflags_ = [] -class IUIAutomationElement3(IUIAutomationElement2): +class IUIAutomationTextPattern2(IUIAutomationTextPattern): _case_insensitive_ = True - _iid_ = GUID('{8471DF34-AEE0-4A01-A7DE-7DB9AF12C296}') + _iid_ = GUID('{506A921A-FCC9-409F-B23B-37EB74106872}') _idlflags_ = [] - -# values for enumeration 'TreeScope' -TreeScope_None = 0 -TreeScope_Element = 1 -TreeScope_Children = 2 -TreeScope_Descendants = 4 -TreeScope_Parent = 8 -TreeScope_Ancestors = 16 -TreeScope_Subtree = 7 -TreeScope = c_int # enum -class IUIAutomationElementArray(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): +class IUIAutomationTextRange(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): _case_insensitive_ = True - _iid_ = GUID('{14314595-B4BC-4055-95F2-58F2E42C9855}') + _iid_ = GUID('{A543CC6A-F4AE-494B-8239-C814481187A8}') _idlflags_ = [] -class IUIAutomationCacheRequest(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): +class IUIAutomationTextRangeArray(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): _case_insensitive_ = True - _iid_ = GUID('{B32A92B5-BC25-4078-9C08-D7EE95C48E03}') + _iid_ = GUID('{CE4AE76A-E717-4C98-81EA-47371D028EB6}') _idlflags_ = [] -# values for enumeration 'OrientationType' -OrientationType_None = 0 -OrientationType_Horizontal = 1 -OrientationType_Vertical = 2 -OrientationType = c_int # enum -IUIAutomationElement._methods_ = [ - COMMETHOD([], HRESULT, 'SetFocus'), - COMMETHOD([], HRESULT, 'GetRuntimeId', - ( ['retval', 'out'], POINTER(_midlSAFEARRAY(c_int)), 'runtimeId' )), - COMMETHOD([], HRESULT, 'FindFirst', - ( ['in'], TreeScope, 'scope' ), - ( ['in'], POINTER(IUIAutomationCondition), 'condition' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'found' )), - COMMETHOD([], HRESULT, 'FindAll', - ( ['in'], TreeScope, 'scope' ), - ( ['in'], POINTER(IUIAutomationCondition), 'condition' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'found' )), - COMMETHOD([], HRESULT, 'FindFirstBuildCache', - ( ['in'], TreeScope, 'scope' ), - ( ['in'], POINTER(IUIAutomationCondition), 'condition' ), - ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'found' )), - COMMETHOD([], HRESULT, 'FindAllBuildCache', - ( ['in'], TreeScope, 'scope' ), - ( ['in'], POINTER(IUIAutomationCondition), 'condition' ), - ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'found' )), - COMMETHOD([], HRESULT, 'BuildUpdatedCache', - ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'updatedElement' )), - COMMETHOD([], HRESULT, 'GetCurrentPropertyValue', - ( ['in'], c_int, 'propertyId' ), - ( ['retval', 'out'], POINTER(VARIANT), 'retVal' )), - COMMETHOD([], HRESULT, 'GetCurrentPropertyValueEx', - ( ['in'], c_int, 'propertyId' ), - ( ['in'], c_int, 'ignoreDefaultValue' ), - ( ['retval', 'out'], POINTER(VARIANT), 'retVal' )), - COMMETHOD([], HRESULT, 'GetCachedPropertyValue', - ( ['in'], c_int, 'propertyId' ), - ( ['retval', 'out'], POINTER(VARIANT), 'retVal' )), - COMMETHOD([], HRESULT, 'GetCachedPropertyValueEx', - ( ['in'], c_int, 'propertyId' ), - ( ['in'], c_int, 'ignoreDefaultValue' ), - ( ['retval', 'out'], POINTER(VARIANT), 'retVal' )), - COMMETHOD([], HRESULT, 'GetCurrentPatternAs', - ( ['in'], c_int, 'patternId' ), - ( ['in'], POINTER(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.GUID), 'riid' ), - ( ['retval', 'out'], POINTER(c_void_p), 'patternObject' )), - COMMETHOD([], HRESULT, 'GetCachedPatternAs', - ( ['in'], c_int, 'patternId' ), - ( ['in'], POINTER(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.GUID), 'riid' ), - ( ['retval', 'out'], POINTER(c_void_p), 'patternObject' )), - COMMETHOD([], HRESULT, 'GetCurrentPattern', - ( ['in'], c_int, 'patternId' ), - ( ['retval', 'out'], POINTER(POINTER(IUnknown)), 'patternObject' )), - COMMETHOD([], HRESULT, 'GetCachedPattern', - ( ['in'], c_int, 'patternId' ), - ( ['retval', 'out'], POINTER(POINTER(IUnknown)), 'patternObject' )), - COMMETHOD([], HRESULT, 'GetCachedParent', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'parent' )), - COMMETHOD([], HRESULT, 'GetCachedChildren', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'children' )), - COMMETHOD(['propget'], HRESULT, 'CurrentProcessId', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentControlType', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentLocalizedControlType', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentName', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentAcceleratorKey', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentAccessKey', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentHasKeyboardFocus', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentIsKeyboardFocusable', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentIsEnabled', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentAutomationId', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentClassName', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentHelpText', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentCulture', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentIsControlElement', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentIsContentElement', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentIsPassword', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentNativeWindowHandle', - ( ['retval', 'out'], POINTER(c_void_p), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentItemType', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentIsOffscreen', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentOrientation', - ( ['retval', 'out'], POINTER(OrientationType), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentFrameworkId', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentIsRequiredForForm', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentItemStatus', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentBoundingRectangle', - ( ['retval', 'out'], POINTER(tagRECT), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentLabeledBy', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentAriaRole', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentAriaProperties', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentIsDataValidForForm', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentControllerFor', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentDescribedBy', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentFlowsTo', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentProviderDescription', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedProcessId', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedControlType', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedLocalizedControlType', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedName', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedAcceleratorKey', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedAccessKey', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedHasKeyboardFocus', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedIsKeyboardFocusable', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedIsEnabled', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedAutomationId', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedClassName', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedHelpText', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedCulture', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedIsControlElement', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedIsContentElement', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedIsPassword', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedNativeWindowHandle', - ( ['retval', 'out'], POINTER(c_void_p), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedItemType', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedIsOffscreen', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedOrientation', - ( ['retval', 'out'], POINTER(OrientationType), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedFrameworkId', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedIsRequiredForForm', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedItemStatus', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedBoundingRectangle', - ( ['retval', 'out'], POINTER(tagRECT), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedLabeledBy', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedAriaRole', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedAriaProperties', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedIsDataValidForForm', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedControllerFor', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedDescribedBy', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedFlowsTo', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedProviderDescription', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD([], HRESULT, 'GetClickablePoint', - ( ['out'], POINTER(tagPOINT), 'clickable' ), - ( ['retval', 'out'], POINTER(c_int), 'gotClickable' )), +# values for enumeration 'SupportedTextSelection' +SupportedTextSelection_None = 0 +SupportedTextSelection_Single = 1 +SupportedTextSelection_Multiple = 2 +SupportedTextSelection = c_int # enum +IUIAutomationTextPattern._methods_ = [ + COMMETHOD([], HRESULT, 'RangeFromPoint', + ( ['in'], tagPOINT, 'pt' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationTextRange)), 'range' )), + COMMETHOD([], HRESULT, 'RangeFromChild', + ( ['in'], POINTER(IUIAutomationElement), 'child' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationTextRange)), 'range' )), + COMMETHOD([], HRESULT, 'GetSelection', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationTextRangeArray)), 'ranges' )), + COMMETHOD([], HRESULT, 'GetVisibleRanges', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationTextRangeArray)), 'ranges' )), + COMMETHOD(['propget'], HRESULT, 'DocumentRange', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationTextRange)), 'range' )), + COMMETHOD(['propget'], HRESULT, 'SupportedTextSelection', + ( ['out', 'retval'], POINTER(SupportedTextSelection), 'SupportedTextSelection' )), ] ################################################################ -## code template for IUIAutomationElement implementation -##class IUIAutomationElement_Impl(object): -## def SetFocus(self): +## code template for IUIAutomationTextPattern implementation +##class IUIAutomationTextPattern_Impl(object): +## def RangeFromPoint(self, pt): ## '-no docstring-' -## #return +## #return range ## -## @property -## def CurrentItemStatus(self): +## def RangeFromChild(self, child): ## '-no docstring-' -## #return retVal +## #return range ## -## @property -## def CachedHelpText(self): +## def GetSelection(self): ## '-no docstring-' -## #return retVal +## #return ranges ## -## @property -## def CachedIsRequiredForForm(self): +## def GetVisibleRanges(self): ## '-no docstring-' -## #return retVal +## #return ranges ## ## @property -## def CurrentAccessKey(self): +## def DocumentRange(self): ## '-no docstring-' -## #return retVal +## #return range ## ## @property -## def CachedIsKeyboardFocusable(self): +## def SupportedTextSelection(self): ## '-no docstring-' -## #return retVal +## #return SupportedTextSelection ## -## @property -## def CurrentAriaRole(self): + +IUIAutomationTextPattern2._methods_ = [ + COMMETHOD([], HRESULT, 'RangeFromAnnotation', + ( ['in'], POINTER(IUIAutomationElement), 'annotation' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationTextRange)), 'range' )), + COMMETHOD([], HRESULT, 'GetCaretRange', + ( ['out'], POINTER(c_int), 'isActive' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationTextRange)), 'range' )), +] +################################################################ +## code template for IUIAutomationTextPattern2 implementation +##class IUIAutomationTextPattern2_Impl(object): +## def RangeFromAnnotation(self, annotation): ## '-no docstring-' -## #return retVal +## #return range ## -## @property -## def CurrentProviderDescription(self): +## def GetCaretRange(self): ## '-no docstring-' -## #return retVal +## #return isActive, range ## -## def FindFirst(self, scope, condition): + +class IUIAutomationRangeValuePattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{59213F4F-7346-49E5-B120-80555987A148}') + _idlflags_ = [] +IUIAutomationRangeValuePattern._methods_ = [ + COMMETHOD([], HRESULT, 'SetValue', + ( ['in'], c_double, 'val' )), + COMMETHOD(['propget'], HRESULT, 'CurrentValue', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentIsReadOnly', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentMaximum', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentMinimum', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentLargeChange', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentSmallChange', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedValue', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedIsReadOnly', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedMaximum', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedMinimum', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedLargeChange', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedSmallChange', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), +] +################################################################ +## code template for IUIAutomationRangeValuePattern implementation +##class IUIAutomationRangeValuePattern_Impl(object): +## def SetValue(self, val): ## '-no docstring-' -## #return found +## #return ## ## @property -## def CurrentIsEnabled(self): +## def CurrentValue(self): ## '-no docstring-' ## #return retVal ## -## def FindAllBuildCache(self, scope, condition, cacheRequest): -## '-no docstring-' -## #return found -## ## @property -## def CachedNativeWindowHandle(self): +## def CurrentIsReadOnly(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedAutomationId(self): +## def CurrentMaximum(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedAriaRole(self): +## def CurrentMinimum(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentHelpText(self): +## def CurrentLargeChange(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentIsControlElement(self): +## def CurrentSmallChange(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedAcceleratorKey(self): +## def CachedValue(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedControllerFor(self): +## def CachedIsReadOnly(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedLabeledBy(self): +## def CachedMaximum(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedProcessId(self): -## '-no docstring-' -## #return retVal -## -## def FindAll(self, scope, condition): -## '-no docstring-' -## #return found -## -## def GetCachedPropertyValueEx(self, propertyId, ignoreDefaultValue): +## def CachedMinimum(self): ## '-no docstring-' ## #return retVal ## -## def BuildUpdatedCache(self, cacheRequest): -## '-no docstring-' -## #return updatedElement -## ## @property -## def CachedIsControlElement(self): +## def CachedLargeChange(self): ## '-no docstring-' ## #return retVal ## -## def FindFirstBuildCache(self, scope, condition, cacheRequest): -## '-no docstring-' -## #return found -## ## @property -## def CachedName(self): -## '-no docstring-' -## #return retVal -## -## def GetCurrentPropertyValue(self, propertyId): +## def CachedSmallChange(self): ## '-no docstring-' ## #return retVal ## + + +# values for enumeration 'ConnectionRecoveryBehaviorOptions' +ConnectionRecoveryBehaviorOptions_Disabled = 0 +ConnectionRecoveryBehaviorOptions_Enabled = 1 +ConnectionRecoveryBehaviorOptions = c_int # enum +class IUIAutomationCondition(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{352FFBA8-0973-437C-A61F-F64CAFD81DF9}') + _idlflags_ = [] +class IUIAutomationAndCondition(IUIAutomationCondition): + _case_insensitive_ = True + _iid_ = GUID('{A7D0AF36-B912-45FE-9855-091DDC174AEC}') + _idlflags_ = [] +IUIAutomationCondition._methods_ = [ +] +################################################################ +## code template for IUIAutomationCondition implementation +##class IUIAutomationCondition_Impl(object): + +IUIAutomationAndCondition._methods_ = [ + COMMETHOD(['propget'], HRESULT, 'ChildCount', + ( ['out', 'retval'], POINTER(c_int), 'ChildCount' )), + COMMETHOD([], HRESULT, 'GetChildrenAsNativeArray', + ( ['out'], POINTER(POINTER(POINTER(IUIAutomationCondition))), 'childArray' ), + ( ['out'], POINTER(c_int), 'childArrayCount' )), + COMMETHOD([], HRESULT, 'GetChildren', + ( ['out', 'retval'], POINTER(_midlSAFEARRAY(POINTER(IUIAutomationCondition))), 'childArray' )), +] +################################################################ +## code template for IUIAutomationAndCondition implementation +##class IUIAutomationAndCondition_Impl(object): ## @property -## def CurrentName(self): +## def ChildCount(self): ## '-no docstring-' -## #return retVal +## #return ChildCount ## -## def GetCachedPattern(self, patternId): +## def GetChildrenAsNativeArray(self): ## '-no docstring-' -## #return patternObject +## #return childArray, childArrayCount ## -## @property -## def CachedCulture(self): +## def GetChildren(self): ## '-no docstring-' -## #return retVal +## #return childArray ## -## @property -## def CachedProviderDescription(self): -## '-no docstring-' -## #return retVal -## -## def GetRuntimeId(self): -## '-no docstring-' -## #return runtimeId -## -## @property -## def CurrentAcceleratorKey(self): + +class IUIAutomationTextEditPattern(IUIAutomationTextPattern): + _case_insensitive_ = True + _iid_ = GUID('{17E21576-996C-4870-99D9-BFF323380C06}') + _idlflags_ = [] +IUIAutomationTextEditPattern._methods_ = [ + COMMETHOD([], HRESULT, 'GetActiveComposition', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationTextRange)), 'range' )), + COMMETHOD([], HRESULT, 'GetConversionTarget', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationTextRange)), 'range' )), +] +################################################################ +## code template for IUIAutomationTextEditPattern implementation +##class IUIAutomationTextEditPattern_Impl(object): +## def GetActiveComposition(self): ## '-no docstring-' -## #return retVal +## #return range ## -## def GetCurrentPattern(self, patternId): +## def GetConversionTarget(self): ## '-no docstring-' -## #return patternObject +## #return range ## -## @property -## def CurrentIsPassword(self): + +class IUIAutomationSelectionItemPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{A8EFA66A-0FDA-421A-9194-38021F3578EA}') + _idlflags_ = [] +IUIAutomationSelectionItemPattern._methods_ = [ + COMMETHOD([], HRESULT, 'Select'), + COMMETHOD([], HRESULT, 'AddToSelection'), + COMMETHOD([], HRESULT, 'RemoveFromSelection'), + COMMETHOD(['propget'], HRESULT, 'CurrentIsSelected', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentSelectionContainer', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedIsSelected', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedSelectionContainer', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), +] +################################################################ +## code template for IUIAutomationSelectionItemPattern implementation +##class IUIAutomationSelectionItemPattern_Impl(object): +## def Select(self): ## '-no docstring-' -## #return retVal +## #return ## -## @property -## def CurrentOrientation(self): +## def AddToSelection(self): ## '-no docstring-' -## #return retVal +## #return ## -## def GetCachedChildren(self): +## def RemoveFromSelection(self): ## '-no docstring-' -## #return children +## #return ## ## @property -## def CurrentIsDataValidForForm(self): +## def CurrentIsSelected(self): ## '-no docstring-' ## #return retVal ## -## def GetCurrentPatternAs(self, patternId, riid): -## '-no docstring-' -## #return patternObject -## ## @property -## def CachedLocalizedControlType(self): +## def CurrentSelectionContainer(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedAriaProperties(self): +## def CachedIsSelected(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentIsOffscreen(self): +## def CachedSelectionContainer(self): ## '-no docstring-' ## #return retVal ## -## @property -## def CurrentFrameworkId(self): + + +# values for enumeration 'CoalesceEventsOptions' +CoalesceEventsOptions_Disabled = 0 +CoalesceEventsOptions_Enabled = 1 +CoalesceEventsOptions = c_int # enum +class CUIAutomation8(CoClass): + 'The Central Class for UIAutomation8' + _reg_clsid_ = GUID('{E22AD333-B25F-460C-83D0-0581107395C9}') + _idlflags_ = [] + _typelib_path_ = typelib_path + _reg_typelib_ = ('{944DE083-8FB8-45CF-BCB7-C477ACB2F897}', 1, 0) +class IUIAutomation2(IUIAutomation): + _case_insensitive_ = True + _iid_ = GUID('{34723AFF-0C9D-49D0-9896-7AB52DF8CD8A}') + _idlflags_ = [] +class IUIAutomation3(IUIAutomation2): + _case_insensitive_ = True + _iid_ = GUID('{73D768DA-9B51-4B89-936E-C209290973E7}') + _idlflags_ = [] +class IUIAutomation4(IUIAutomation3): + _case_insensitive_ = True + _iid_ = GUID('{1189C02A-05F8-4319-8E21-E817E3DB2860}') + _idlflags_ = [] +class IUIAutomation5(IUIAutomation4): + _case_insensitive_ = True + _iid_ = GUID('{25F700C8-D816-4057-A9DC-3CBDEE77E256}') + _idlflags_ = [] +class IUIAutomation6(IUIAutomation5): + _case_insensitive_ = True + _iid_ = GUID('{AAE072DA-29E3-413D-87A7-192DBF81ED10}') + _idlflags_ = [] +CUIAutomation8._com_interfaces_ = [IUIAutomation2, IUIAutomation3, IUIAutomation4, IUIAutomation5, IUIAutomation6] + +class IUIAutomationCustomNavigationPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{01EA217A-1766-47ED-A6CC-ACF492854B1F}') + _idlflags_ = [] + +# values for enumeration 'NavigateDirection' +NavigateDirection_Parent = 0 +NavigateDirection_NextSibling = 1 +NavigateDirection_PreviousSibling = 2 +NavigateDirection_FirstChild = 3 +NavigateDirection_LastChild = 4 +NavigateDirection = c_int # enum +IUIAutomationCustomNavigationPattern._methods_ = [ + COMMETHOD([], HRESULT, 'Navigate', + ( ['in'], NavigateDirection, 'direction' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'pRetVal' )), +] +################################################################ +## code template for IUIAutomationCustomNavigationPattern implementation +##class IUIAutomationCustomNavigationPattern_Impl(object): +## def Navigate(self, direction): ## '-no docstring-' -## #return retVal +## #return pRetVal ## -## @property -## def CachedControlType(self): + + +# values for enumeration 'PropertyConditionFlags' +PropertyConditionFlags_None = 0 +PropertyConditionFlags_IgnoreCase = 1 +PropertyConditionFlags_MatchSubstring = 2 +PropertyConditionFlags = c_int # enum +class IUIAutomationSynchronizedInputPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{2233BE0B-AFB7-448B-9FDA-3B378AA5EAE1}') + _idlflags_ = [] + +# values for enumeration 'SynchronizedInputType' +SynchronizedInputType_KeyUp = 1 +SynchronizedInputType_KeyDown = 2 +SynchronizedInputType_LeftMouseUp = 4 +SynchronizedInputType_LeftMouseDown = 8 +SynchronizedInputType_RightMouseUp = 16 +SynchronizedInputType_RightMouseDown = 32 +SynchronizedInputType = c_int # enum +IUIAutomationSynchronizedInputPattern._methods_ = [ + COMMETHOD([], HRESULT, 'StartListening', + ( ['in'], SynchronizedInputType, 'inputType' )), + COMMETHOD([], HRESULT, 'Cancel'), +] +################################################################ +## code template for IUIAutomationSynchronizedInputPattern implementation +##class IUIAutomationSynchronizedInputPattern_Impl(object): +## def StartListening(self, inputType): ## '-no docstring-' -## #return retVal +## #return ## -## @property -## def CurrentClassName(self): +## def Cancel(self): ## '-no docstring-' -## #return retVal +## #return ## -## @property -## def CachedAccessKey(self): + +class IUIAutomationActiveTextPositionChangedEventHandler(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{F97933B0-8DAE-4496-8997-5BA015FE0D82}') + _idlflags_ = ['oleautomation'] +IUIAutomationActiveTextPositionChangedEventHandler._methods_ = [ + COMMETHOD([], HRESULT, 'HandleActiveTextPositionChangedEvent', + ( ['in'], POINTER(IUIAutomationElement), 'sender' ), + ( ['in'], POINTER(IUIAutomationTextRange), 'range' )), +] +################################################################ +## code template for IUIAutomationActiveTextPositionChangedEventHandler implementation +##class IUIAutomationActiveTextPositionChangedEventHandler_Impl(object): +## def HandleActiveTextPositionChangedEvent(self, sender, range): ## '-no docstring-' -## #return retVal +## #return ## -## @property -## def CurrentIsKeyboardFocusable(self): + +class IUIAutomationLegacyIAccessiblePattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{828055AD-355B-4435-86D5-3B51C14A9B1B}') + _idlflags_ = [] +class IAccessible(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IDispatch): + _case_insensitive_ = True + _iid_ = GUID('{618736E0-3C3D-11CF-810C-00AA00389B71}') + _idlflags_ = ['hidden', 'dual', 'oleautomation'] +IUIAutomationLegacyIAccessiblePattern._methods_ = [ + COMMETHOD([], HRESULT, 'Select', + ( [], c_int, 'flagsSelect' )), + COMMETHOD([], HRESULT, 'DoDefaultAction'), + COMMETHOD([], HRESULT, 'SetValue', + ( [], WSTRING, 'szValue' )), + COMMETHOD(['propget'], HRESULT, 'CurrentChildId', + ( ['out', 'retval'], POINTER(c_int), 'pRetVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentName', + ( ['out', 'retval'], POINTER(BSTR), 'pszName' )), + COMMETHOD(['propget'], HRESULT, 'CurrentValue', + ( ['out', 'retval'], POINTER(BSTR), 'pszValue' )), + COMMETHOD(['propget'], HRESULT, 'CurrentDescription', + ( ['out', 'retval'], POINTER(BSTR), 'pszDescription' )), + COMMETHOD(['propget'], HRESULT, 'CurrentRole', + ( ['out', 'retval'], POINTER(c_ulong), 'pdwRole' )), + COMMETHOD(['propget'], HRESULT, 'CurrentState', + ( ['out', 'retval'], POINTER(c_ulong), 'pdwState' )), + COMMETHOD(['propget'], HRESULT, 'CurrentHelp', + ( ['out', 'retval'], POINTER(BSTR), 'pszHelp' )), + COMMETHOD(['propget'], HRESULT, 'CurrentKeyboardShortcut', + ( ['out', 'retval'], POINTER(BSTR), 'pszKeyboardShortcut' )), + COMMETHOD([], HRESULT, 'GetCurrentSelection', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'pvarSelectedChildren' )), + COMMETHOD(['propget'], HRESULT, 'CurrentDefaultAction', + ( ['out', 'retval'], POINTER(BSTR), 'pszDefaultAction' )), + COMMETHOD(['propget'], HRESULT, 'CachedChildId', + ( ['out', 'retval'], POINTER(c_int), 'pRetVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedName', + ( ['out', 'retval'], POINTER(BSTR), 'pszName' )), + COMMETHOD(['propget'], HRESULT, 'CachedValue', + ( ['out', 'retval'], POINTER(BSTR), 'pszValue' )), + COMMETHOD(['propget'], HRESULT, 'CachedDescription', + ( ['out', 'retval'], POINTER(BSTR), 'pszDescription' )), + COMMETHOD(['propget'], HRESULT, 'CachedRole', + ( ['out', 'retval'], POINTER(c_ulong), 'pdwRole' )), + COMMETHOD(['propget'], HRESULT, 'CachedState', + ( ['out', 'retval'], POINTER(c_ulong), 'pdwState' )), + COMMETHOD(['propget'], HRESULT, 'CachedHelp', + ( ['out', 'retval'], POINTER(BSTR), 'pszHelp' )), + COMMETHOD(['propget'], HRESULT, 'CachedKeyboardShortcut', + ( ['out', 'retval'], POINTER(BSTR), 'pszKeyboardShortcut' )), + COMMETHOD([], HRESULT, 'GetCachedSelection', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'pvarSelectedChildren' )), + COMMETHOD(['propget'], HRESULT, 'CachedDefaultAction', + ( ['out', 'retval'], POINTER(BSTR), 'pszDefaultAction' )), + COMMETHOD([], HRESULT, 'GetIAccessible', + ( ['out', 'retval'], POINTER(POINTER(IAccessible)), 'ppAccessible' )), +] +################################################################ +## code template for IUIAutomationLegacyIAccessiblePattern implementation +##class IUIAutomationLegacyIAccessiblePattern_Impl(object): +## def Select(self, flagsSelect): ## '-no docstring-' -## #return retVal +## #return ## -## def GetClickablePoint(self): +## def DoDefaultAction(self): ## '-no docstring-' -## #return clickable, gotClickable +## #return ## -## def GetCurrentPropertyValueEx(self, propertyId, ignoreDefaultValue): +## def SetValue(self, szValue): ## '-no docstring-' -## #return retVal +## #return ## ## @property -## def CurrentProcessId(self): +## def CurrentChildId(self): ## '-no docstring-' -## #return retVal +## #return pRetVal ## ## @property -## def CurrentHasKeyboardFocus(self): +## def CurrentName(self): ## '-no docstring-' -## #return retVal +## #return pszName ## ## @property -## def CachedHasKeyboardFocus(self): +## def CurrentValue(self): ## '-no docstring-' -## #return retVal +## #return pszValue ## ## @property -## def CachedIsPassword(self): +## def CurrentDescription(self): ## '-no docstring-' -## #return retVal +## #return pszDescription ## ## @property -## def CachedBoundingRectangle(self): +## def CurrentRole(self): ## '-no docstring-' -## #return retVal +## #return pdwRole ## ## @property -## def CachedClassName(self): +## def CurrentState(self): ## '-no docstring-' -## #return retVal +## #return pdwState ## ## @property -## def CurrentCulture(self): +## def CurrentHelp(self): ## '-no docstring-' -## #return retVal +## #return pszHelp ## ## @property -## def CurrentLocalizedControlType(self): +## def CurrentKeyboardShortcut(self): ## '-no docstring-' -## #return retVal +## #return pszKeyboardShortcut ## -## @property -## def CurrentControlType(self): +## def GetCurrentSelection(self): ## '-no docstring-' -## #return retVal +## #return pvarSelectedChildren ## ## @property -## def CachedIsContentElement(self): +## def CurrentDefaultAction(self): ## '-no docstring-' -## #return retVal +## #return pszDefaultAction ## ## @property -## def CurrentAriaProperties(self): +## def CachedChildId(self): ## '-no docstring-' -## #return retVal +## #return pRetVal ## ## @property -## def CurrentIsRequiredForForm(self): +## def CachedName(self): ## '-no docstring-' -## #return retVal +## #return pszName ## ## @property -## def CurrentFlowsTo(self): +## def CachedValue(self): ## '-no docstring-' -## #return retVal +## #return pszValue ## ## @property -## def CachedOrientation(self): +## def CachedDescription(self): ## '-no docstring-' -## #return retVal +## #return pszDescription ## -## def GetCachedPropertyValue(self, propertyId): +## @property +## def CachedRole(self): ## '-no docstring-' -## #return retVal +## #return pdwRole ## ## @property -## def CachedItemStatus(self): +## def CachedState(self): ## '-no docstring-' -## #return retVal +## #return pdwState ## ## @property -## def CachedFrameworkId(self): +## def CachedHelp(self): ## '-no docstring-' -## #return retVal +## #return pszHelp ## ## @property -## def CurrentNativeWindowHandle(self): +## def CachedKeyboardShortcut(self): ## '-no docstring-' -## #return retVal +## #return pszKeyboardShortcut ## -## @property -## def CurrentLabeledBy(self): +## def GetCachedSelection(self): ## '-no docstring-' -## #return retVal +## #return pvarSelectedChildren ## ## @property -## def CurrentItemType(self): +## def CachedDefaultAction(self): ## '-no docstring-' -## #return retVal +## #return pszDefaultAction ## -## @property -## def CachedItemType(self): +## def GetIAccessible(self): ## '-no docstring-' -## #return retVal +## #return ppAccessible ## -## @property -## def CurrentControllerFor(self): + +class IUIAutomationScrollPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{88F4D42A-E881-459D-A77C-73BBBB7E02DC}') + _idlflags_ = [] + +# values for enumeration 'ScrollAmount' +ScrollAmount_LargeDecrement = 0 +ScrollAmount_SmallDecrement = 1 +ScrollAmount_NoAmount = 2 +ScrollAmount_LargeIncrement = 3 +ScrollAmount_SmallIncrement = 4 +ScrollAmount = c_int # enum +IUIAutomationScrollPattern._methods_ = [ + COMMETHOD([], HRESULT, 'Scroll', + ( ['in'], ScrollAmount, 'horizontalAmount' ), + ( ['in'], ScrollAmount, 'verticalAmount' )), + COMMETHOD([], HRESULT, 'SetScrollPercent', + ( ['in'], c_double, 'horizontalPercent' ), + ( ['in'], c_double, 'verticalPercent' )), + COMMETHOD(['propget'], HRESULT, 'CurrentHorizontalScrollPercent', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentVerticalScrollPercent', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentHorizontalViewSize', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentVerticalViewSize', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentHorizontallyScrollable', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentVerticallyScrollable', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedHorizontalScrollPercent', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedVerticalScrollPercent', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedHorizontalViewSize', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedVerticalViewSize', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedHorizontallyScrollable', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedVerticallyScrollable', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), +] +################################################################ +## code template for IUIAutomationScrollPattern implementation +##class IUIAutomationScrollPattern_Impl(object): +## def Scroll(self, horizontalAmount, verticalAmount): ## '-no docstring-' -## #return retVal +## #return ## -## @property -## def CachedFlowsTo(self): +## def SetScrollPercent(self, horizontalPercent, verticalPercent): ## '-no docstring-' -## #return retVal +## #return ## ## @property -## def CachedDescribedBy(self): +## def CurrentHorizontalScrollPercent(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentAutomationId(self): +## def CurrentVerticalScrollPercent(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedIsEnabled(self): +## def CurrentHorizontalViewSize(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentIsContentElement(self): +## def CurrentVerticalViewSize(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentDescribedBy(self): +## def CurrentHorizontallyScrollable(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentBoundingRectangle(self): +## def CurrentVerticallyScrollable(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedIsOffscreen(self): +## def CachedHorizontalScrollPercent(self): ## '-no docstring-' ## #return retVal ## -## def GetCachedParent(self): -## '-no docstring-' -## #return parent -## -## def GetCachedPatternAs(self, patternId, riid): +## @property +## def CachedVerticalScrollPercent(self): ## '-no docstring-' -## #return patternObject +## #return retVal ## ## @property -## def CachedIsDataValidForForm(self): +## def CachedHorizontalViewSize(self): ## '-no docstring-' ## #return retVal ## - - -# values for enumeration 'LiveSetting' -Off = 0 -Polite = 1 -Assertive = 2 -LiveSetting = c_int # enum -IUIAutomationElement2._methods_ = [ - COMMETHOD(['propget'], HRESULT, 'CurrentOptimizeForVisualContent', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedOptimizeForVisualContent', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentLiveSetting', - ( ['retval', 'out'], POINTER(LiveSetting), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedLiveSetting', - ( ['retval', 'out'], POINTER(LiveSetting), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentFlowsFrom', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedFlowsFrom', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), -] -################################################################ -## code template for IUIAutomationElement2 implementation -##class IUIAutomationElement2_Impl(object): ## @property -## def CurrentFlowsFrom(self): +## def CachedVerticalViewSize(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentLiveSetting(self): +## def CachedHorizontallyScrollable(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedLiveSetting(self): +## def CachedVerticallyScrollable(self): ## '-no docstring-' ## #return retVal ## -## @property -## def CachedOptimizeForVisualContent(self): + +class IUIAutomationTablePattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{620E691C-EA96-4710-A850-754B24CE2417}') + _idlflags_ = [] + +# values for enumeration 'RowOrColumnMajor' +RowOrColumnMajor_RowMajor = 0 +RowOrColumnMajor_ColumnMajor = 1 +RowOrColumnMajor_Indeterminate = 2 +RowOrColumnMajor = c_int # enum +IUIAutomationTablePattern._methods_ = [ + COMMETHOD([], HRESULT, 'GetCurrentRowHeaders', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), + COMMETHOD([], HRESULT, 'GetCurrentColumnHeaders', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentRowOrColumnMajor', + ( ['out', 'retval'], POINTER(RowOrColumnMajor), 'retVal' )), + COMMETHOD([], HRESULT, 'GetCachedRowHeaders', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), + COMMETHOD([], HRESULT, 'GetCachedColumnHeaders', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedRowOrColumnMajor', + ( ['out', 'retval'], POINTER(RowOrColumnMajor), 'retVal' )), +] +################################################################ +## code template for IUIAutomationTablePattern implementation +##class IUIAutomationTablePattern_Impl(object): +## def GetCurrentRowHeaders(self): ## '-no docstring-' ## #return retVal ## -## @property -## def CachedFlowsFrom(self): +## def GetCurrentColumnHeaders(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentOptimizeForVisualContent(self): +## def CurrentRowOrColumnMajor(self): ## '-no docstring-' ## #return retVal ## - -IUIAutomationElement3._methods_ = [ - COMMETHOD([], HRESULT, 'ShowContextMenu'), - COMMETHOD(['propget'], HRESULT, 'CurrentIsPeripheral', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedIsPeripheral', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), -] -################################################################ -## code template for IUIAutomationElement3 implementation -##class IUIAutomationElement3_Impl(object): -## @property -## def CurrentIsPeripheral(self): +## def GetCachedRowHeaders(self): ## '-no docstring-' ## #return retVal ## -## @property -## def CachedIsPeripheral(self): +## def GetCachedColumnHeaders(self): ## '-no docstring-' ## #return retVal ## -## def ShowContextMenu(self): +## @property +## def CachedRowOrColumnMajor(self): ## '-no docstring-' -## #return +## #return retVal ## -HeadingLevel_None = 80050 # Constant c_int -UIA_ClickablePointPropertyId = 30014 # Constant c_int -UIA_SelectionPatternId = 10001 # Constant c_int -UIA_IndentationFirstLineAttributeId = 40010 # Constant c_int -AnnotationType_Author = 60019 # Constant c_int -class IUIAutomationAndCondition(IUIAutomationCondition): +class IUIAutomationOrCondition(IUIAutomationCondition): _case_insensitive_ = True - _iid_ = GUID('{A7D0AF36-B912-45FE-9855-091DDC174AEC}') + _iid_ = GUID('{8753F032-3DB1-47B5-A1FC-6E34A266C712}') _idlflags_ = [] -IUIAutomationAndCondition._methods_ = [ +IUIAutomationOrCondition._methods_ = [ COMMETHOD(['propget'], HRESULT, 'ChildCount', - ( ['retval', 'out'], POINTER(c_int), 'ChildCount' )), + ( ['out', 'retval'], POINTER(c_int), 'ChildCount' )), COMMETHOD([], HRESULT, 'GetChildrenAsNativeArray', ( ['out'], POINTER(POINTER(POINTER(IUIAutomationCondition))), 'childArray' ), ( ['out'], POINTER(c_int), 'childArrayCount' )), COMMETHOD([], HRESULT, 'GetChildren', - ( ['retval', 'out'], POINTER(_midlSAFEARRAY(POINTER(IUIAutomationCondition))), 'childArray' )), + ( ['out', 'retval'], POINTER(_midlSAFEARRAY(POINTER(IUIAutomationCondition))), 'childArray' )), ] ################################################################ -## code template for IUIAutomationAndCondition implementation -##class IUIAutomationAndCondition_Impl(object): -## def GetChildren(self): +## code template for IUIAutomationOrCondition implementation +##class IUIAutomationOrCondition_Impl(object): +## @property +## def ChildCount(self): ## '-no docstring-' -## #return childArray +## #return ChildCount ## ## def GetChildrenAsNativeArray(self): ## '-no docstring-' ## #return childArray, childArrayCount ## -## @property -## def ChildCount(self): +## def GetChildren(self): ## '-no docstring-' -## #return ChildCount +## #return childArray ## -class IUIAutomationElement4(IUIAutomationElement3): +class IUIAutomationTableItemPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): _case_insensitive_ = True - _iid_ = GUID('{3B6E233C-52FB-4063-A4C9-77C075C2A06B}') + _iid_ = GUID('{0B964EB3-EF2E-4464-9C79-61D61737A27E}') _idlflags_ = [] -IUIAutomationElement4._methods_ = [ - COMMETHOD(['propget'], HRESULT, 'CurrentPositionInSet', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentSizeOfSet', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentLevel', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentAnnotationTypes', - ( ['retval', 'out'], POINTER(_midlSAFEARRAY(c_int)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentAnnotationObjects', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedPositionInSet', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedSizeOfSet', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedLevel', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedAnnotationTypes', - ( ['retval', 'out'], POINTER(_midlSAFEARRAY(c_int)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedAnnotationObjects', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), -] -################################################################ -## code template for IUIAutomationElement4 implementation -##class IUIAutomationElement4_Impl(object): -## @property -## def CachedPositionInSet(self): -## '-no docstring-' -## #return retVal -## -## @property -## def CurrentLevel(self): -## '-no docstring-' -## #return retVal -## -## @property -## def CachedSizeOfSet(self): -## '-no docstring-' -## #return retVal -## -## @property -## def CurrentSizeOfSet(self): -## '-no docstring-' -## #return retVal -## -## @property -## def CachedAnnotationObjects(self): -## '-no docstring-' -## #return retVal -## -## @property -## def CachedLevel(self): -## '-no docstring-' -## #return retVal -## -## @property -## def CurrentAnnotationObjects(self): -## '-no docstring-' -## #return retVal -## -## @property -## def CurrentPositionInSet(self): -## '-no docstring-' -## #return retVal -## -## @property -## def CachedAnnotationTypes(self): -## '-no docstring-' -## #return retVal -## -## @property -## def CurrentAnnotationTypes(self): -## '-no docstring-' -## #return retVal -## - -UIA_IndentationTrailingAttributeId = 40012 # Constant c_int -class IUIAutomationOrCondition(IUIAutomationCondition): - _case_insensitive_ = True - _iid_ = GUID('{8753F032-3DB1-47B5-A1FC-6E34A266C712}') - _idlflags_ = [] -IUIAutomationOrCondition._methods_ = [ - COMMETHOD(['propget'], HRESULT, 'ChildCount', - ( ['retval', 'out'], POINTER(c_int), 'ChildCount' )), - COMMETHOD([], HRESULT, 'GetChildrenAsNativeArray', - ( ['out'], POINTER(POINTER(POINTER(IUIAutomationCondition))), 'childArray' ), - ( ['out'], POINTER(c_int), 'childArrayCount' )), - COMMETHOD([], HRESULT, 'GetChildren', - ( ['retval', 'out'], POINTER(_midlSAFEARRAY(POINTER(IUIAutomationCondition))), 'childArray' )), -] -################################################################ -## code template for IUIAutomationOrCondition implementation -##class IUIAutomationOrCondition_Impl(object): -## def GetChildren(self): -## '-no docstring-' -## #return childArray -## -## def GetChildrenAsNativeArray(self): -## '-no docstring-' -## #return childArray, childArrayCount -## -## @property -## def ChildCount(self): -## '-no docstring-' -## #return ChildCount -## - -HeadingLevel4 = 80054 # Constant c_int -UIA_IsPasswordPropertyId = 30019 # Constant c_int -class IUIAutomationCustomNavigationPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{01EA217A-1766-47ED-A6CC-ACF492854B1F}') - _idlflags_ = [] - -# values for enumeration 'NavigateDirection' -NavigateDirection_Parent = 0 -NavigateDirection_NextSibling = 1 -NavigateDirection_PreviousSibling = 2 -NavigateDirection_FirstChild = 3 -NavigateDirection_LastChild = 4 -NavigateDirection = c_int # enum -IUIAutomationCustomNavigationPattern._methods_ = [ - COMMETHOD([], HRESULT, 'Navigate', - ( ['in'], NavigateDirection, 'direction' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'pRetVal' )), -] -################################################################ -## code template for IUIAutomationCustomNavigationPattern implementation -##class IUIAutomationCustomNavigationPattern_Impl(object): -## def Navigate(self, direction): -## '-no docstring-' -## #return pRetVal -## - -UIA_StylesStyleIdPropertyId = 30120 # Constant c_int -class IUIAutomationNotCondition(IUIAutomationCondition): - _case_insensitive_ = True - _iid_ = GUID('{F528B657-847B-498C-8896-D52B565407A1}') - _idlflags_ = [] -IUIAutomationNotCondition._methods_ = [ - COMMETHOD([], HRESULT, 'GetChild', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationCondition)), 'condition' )), -] -################################################################ -## code template for IUIAutomationNotCondition implementation -##class IUIAutomationNotCondition_Impl(object): -## def GetChild(self): -## '-no docstring-' -## #return condition -## - -UIA_ThumbControlTypeId = 50027 # Constant c_int -HeadingLevel5 = 80055 # Constant c_int -class IUIAutomationElement5(IUIAutomationElement4): - _case_insensitive_ = True - _iid_ = GUID('{98141C1D-0D0E-4175-BBE2-6BFF455842A7}') - _idlflags_ = [] -IUIAutomationElement5._methods_ = [ - COMMETHOD(['propget'], HRESULT, 'CurrentLandmarkType', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentLocalizedLandmarkType', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedLandmarkType', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedLocalizedLandmarkType', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), +IUIAutomationTableItemPattern._methods_ = [ + COMMETHOD([], HRESULT, 'GetCurrentRowHeaderItems', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), + COMMETHOD([], HRESULT, 'GetCurrentColumnHeaderItems', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), + COMMETHOD([], HRESULT, 'GetCachedRowHeaderItems', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), + COMMETHOD([], HRESULT, 'GetCachedColumnHeaderItems', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), ] ################################################################ -## code template for IUIAutomationElement5 implementation -##class IUIAutomationElement5_Impl(object): -## @property -## def CachedLandmarkType(self): +## code template for IUIAutomationTableItemPattern implementation +##class IUIAutomationTableItemPattern_Impl(object): +## def GetCurrentRowHeaderItems(self): ## '-no docstring-' ## #return retVal ## -## @property -## def CachedLocalizedLandmarkType(self): +## def GetCurrentColumnHeaderItems(self): ## '-no docstring-' ## #return retVal ## -## @property -## def CurrentLandmarkType(self): +## def GetCachedRowHeaderItems(self): ## '-no docstring-' ## #return retVal ## -## @property -## def CurrentLocalizedLandmarkType(self): +## def GetCachedColumnHeaderItems(self): ## '-no docstring-' ## #return retVal ## -class IUIAutomationTreeWalker(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): +UIA_FormLandmarkTypeId = 80001 # Constant c_int +class IUIAutomationBoolCondition(IUIAutomationCondition): _case_insensitive_ = True - _iid_ = GUID('{4042C624-389C-4AFC-A630-9DF854A541FC}') + _iid_ = GUID('{1B4E1F2E-75EB-4D0B-8952-5A69988E2307}') _idlflags_ = [] -IUIAutomationTreeWalker._methods_ = [ - COMMETHOD([], HRESULT, 'GetParentElement', - ( ['in'], POINTER(IUIAutomationElement), 'element' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'parent' )), - COMMETHOD([], HRESULT, 'GetFirstChildElement', - ( ['in'], POINTER(IUIAutomationElement), 'element' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'first' )), - COMMETHOD([], HRESULT, 'GetLastChildElement', - ( ['in'], POINTER(IUIAutomationElement), 'element' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'last' )), - COMMETHOD([], HRESULT, 'GetNextSiblingElement', - ( ['in'], POINTER(IUIAutomationElement), 'element' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'next' )), - COMMETHOD([], HRESULT, 'GetPreviousSiblingElement', - ( ['in'], POINTER(IUIAutomationElement), 'element' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'previous' )), - COMMETHOD([], HRESULT, 'NormalizeElement', - ( ['in'], POINTER(IUIAutomationElement), 'element' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'normalized' )), - COMMETHOD([], HRESULT, 'GetParentElementBuildCache', - ( ['in'], POINTER(IUIAutomationElement), 'element' ), - ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'parent' )), - COMMETHOD([], HRESULT, 'GetFirstChildElementBuildCache', - ( ['in'], POINTER(IUIAutomationElement), 'element' ), - ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'first' )), - COMMETHOD([], HRESULT, 'GetLastChildElementBuildCache', - ( ['in'], POINTER(IUIAutomationElement), 'element' ), - ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'last' )), - COMMETHOD([], HRESULT, 'GetNextSiblingElementBuildCache', - ( ['in'], POINTER(IUIAutomationElement), 'element' ), - ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'next' )), - COMMETHOD([], HRESULT, 'GetPreviousSiblingElementBuildCache', - ( ['in'], POINTER(IUIAutomationElement), 'element' ), - ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'previous' )), - COMMETHOD([], HRESULT, 'NormalizeElementBuildCache', - ( ['in'], POINTER(IUIAutomationElement), 'element' ), - ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'normalized' )), - COMMETHOD(['propget'], HRESULT, 'condition', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationCondition)), 'condition' )), +IUIAutomationBoolCondition._methods_ = [ + COMMETHOD(['propget'], HRESULT, 'BooleanValue', + ( ['out', 'retval'], POINTER(c_int), 'boolVal' )), ] ################################################################ -## code template for IUIAutomationTreeWalker implementation -##class IUIAutomationTreeWalker_Impl(object): -## def GetFirstChildElementBuildCache(self, element, cacheRequest): -## '-no docstring-' -## #return first -## -## def GetParentElement(self, element): -## '-no docstring-' -## #return parent -## -## def GetLastChildElement(self, element): -## '-no docstring-' -## #return last -## -## def GetPreviousSiblingElementBuildCache(self, element, cacheRequest): -## '-no docstring-' -## #return previous -## -## def GetParentElementBuildCache(self, element, cacheRequest): -## '-no docstring-' -## #return parent -## -## def GetNextSiblingElementBuildCache(self, element, cacheRequest): -## '-no docstring-' -## #return next -## -## def GetNextSiblingElement(self, element): -## '-no docstring-' -## #return next -## -## def GetPreviousSiblingElement(self, element): -## '-no docstring-' -## #return previous -## -## def GetLastChildElementBuildCache(self, element, cacheRequest): -## '-no docstring-' -## #return last -## -## def GetFirstChildElement(self, element): -## '-no docstring-' -## #return first -## -## def NormalizeElementBuildCache(self, element, cacheRequest): -## '-no docstring-' -## #return normalized -## +## code template for IUIAutomationBoolCondition implementation +##class IUIAutomationBoolCondition_Impl(object): ## @property -## def condition(self): -## '-no docstring-' -## #return condition -## -## def NormalizeElement(self, element): +## def BooleanValue(self): ## '-no docstring-' -## #return normalized -## - -UIA_IsOffscreenPropertyId = 30022 # Constant c_int -UIA_MarginBottomAttributeId = 40018 # Constant c_int -UIA_IsDialogPropertyId = 30174 # Constant c_int -class IUIAutomationElement6(IUIAutomationElement5): - _case_insensitive_ = True - _iid_ = GUID('{4780D450-8BCA-4977-AFA5-A4A517F555E3}') - _idlflags_ = [] -IUIAutomationElement6._methods_ = [ - COMMETHOD(['propget'], HRESULT, 'CurrentFullDescription', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedFullDescription', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), -] -################################################################ -## code template for IUIAutomationElement6 implementation -##class IUIAutomationElement6_Impl(object): -## @property -## def CachedFullDescription(self): -## '-no docstring-' -## #return retVal -## -## @property -## def CurrentFullDescription(self): -## '-no docstring-' -## #return retVal +## #return boolVal ## +UIA_NavigationLandmarkTypeId = 80003 # Constant c_int +UIA_MainLandmarkTypeId = 80002 # Constant c_int +UIA_SearchLandmarkTypeId = 80004 # Constant c_int +UIA_RangeValueMaximumPropertyId = 30050 # Constant c_int +UIA_RangeValueIsReadOnlyPropertyId = 30048 # Constant c_int +UIA_FontSizeAttributeId = 40006 # Constant c_int +UIA_RangeValueLargeChangePropertyId = 30051 # Constant c_int +UIA_FontWeightAttributeId = 40007 # Constant c_int +UIA_ScrollHorizontalScrollPercentPropertyId = 30053 # Constant c_int +UIA_ForegroundColorAttributeId = 40008 # Constant c_int +UIA_RangeValueSmallChangePropertyId = 30052 # Constant c_int +UIA_HorizontalTextAlignmentAttributeId = 40009 # Constant c_int +UIA_RangeValueMinimumPropertyId = 30049 # Constant c_int +UIA_IndentationFirstLineAttributeId = 40010 # Constant c_int +UIA_ScrollPatternId = 10004 # Constant c_int +UIA_IndentationLeadingAttributeId = 40011 # Constant c_int +UIA_ExpandCollapsePatternId = 10005 # Constant c_int +UIA_IndentationTrailingAttributeId = 40012 # Constant c_int +UIA_GridPatternId = 10006 # Constant c_int +UIA_IsHiddenAttributeId = 40013 # Constant c_int +UIA_GridItemPatternId = 10007 # Constant c_int +UIA_IsItalicAttributeId = 40014 # Constant c_int +UIA_MultipleViewPatternId = 10008 # Constant c_int +UIA_IsReadOnlyAttributeId = 40015 # Constant c_int +UIA_WindowPatternId = 10009 # Constant c_int +UIA_IsSubscriptAttributeId = 40016 # Constant c_int +UIA_SelectionItemPatternId = 10010 # Constant c_int +UIA_IsSuperscriptAttributeId = 40017 # Constant c_int +UIA_DockPatternId = 10011 # Constant c_int +UIA_MarginBottomAttributeId = 40018 # Constant c_int +UIA_TablePatternId = 10012 # Constant c_int +UIA_MarginLeadingAttributeId = 40019 # Constant c_int +UIA_TableItemPatternId = 10013 # Constant c_int UIA_MarginTopAttributeId = 40020 # Constant c_int -class IUIAutomationElement7(IUIAutomationElement6): +UIA_TextPatternId = 10014 # Constant c_int +UIA_MarginTrailingAttributeId = 40021 # Constant c_int +UIA_TogglePatternId = 10015 # Constant c_int +UIA_OutlineStylesAttributeId = 40022 # Constant c_int +UIA_TransformPatternId = 10016 # Constant c_int +UIA_OverlineColorAttributeId = 40023 # Constant c_int +UIA_ScrollItemPatternId = 10017 # Constant c_int +UIA_OverlineStyleAttributeId = 40024 # Constant c_int +UIA_LegacyIAccessiblePatternId = 10018 # Constant c_int +UIA_StrikethroughColorAttributeId = 40025 # Constant c_int +UIA_ItemContainerPatternId = 10019 # Constant c_int +UIA_StrikethroughStyleAttributeId = 40026 # Constant c_int +UIA_VirtualizedItemPatternId = 10020 # Constant c_int +UIA_TabsAttributeId = 40027 # Constant c_int +UIA_SynchronizedInputPatternId = 10021 # Constant c_int +UIA_TextFlowDirectionsAttributeId = 40028 # Constant c_int +UIA_ObjectModelPatternId = 10022 # Constant c_int +UIA_UnderlineColorAttributeId = 40029 # Constant c_int +UIA_AnnotationPatternId = 10023 # Constant c_int +UIA_UnderlineStyleAttributeId = 40030 # Constant c_int +UIA_TextPattern2Id = 10024 # Constant c_int +UIA_AnnotationTypesAttributeId = 40031 # Constant c_int +UIA_StylesPatternId = 10025 # Constant c_int +UIA_AnnotationObjectsAttributeId = 40032 # Constant c_int +UIA_SpreadsheetPatternId = 10026 # Constant c_int +UIA_StyleNameAttributeId = 40033 # Constant c_int +UIA_SpreadsheetItemPatternId = 10027 # Constant c_int +UIA_StyleIdAttributeId = 40034 # Constant c_int +UIA_TransformPattern2Id = 10028 # Constant c_int +UIA_LinkAttributeId = 40035 # Constant c_int +UIA_TextChildPatternId = 10029 # Constant c_int +UIA_IsActiveAttributeId = 40036 # Constant c_int +UIA_DragPatternId = 10030 # Constant c_int +UIA_SelectionActiveEndAttributeId = 40037 # Constant c_int +UIA_DropTargetPatternId = 10031 # Constant c_int +UIA_CaretPositionAttributeId = 40038 # Constant c_int +UIA_TextEditPatternId = 10032 # Constant c_int +UIA_CaretBidiModeAttributeId = 40039 # Constant c_int +UIA_CustomNavigationPatternId = 10033 # Constant c_int +UIA_LineSpacingAttributeId = 40040 # Constant c_int +UIA_SelectionPattern2Id = 10034 # Constant c_int +UIA_BeforeParagraphSpacingAttributeId = 40041 # Constant c_int +UIA_ToolTipOpenedEventId = 20000 # Constant c_int +UIA_AfterParagraphSpacingAttributeId = 40042 # Constant c_int +UIA_ToolTipClosedEventId = 20001 # Constant c_int +UIA_SayAsInterpretAsAttributeId = 40043 # Constant c_int +UIA_StructureChangedEventId = 20002 # Constant c_int +UIA_ButtonControlTypeId = 50000 # Constant c_int +UIA_MenuOpenedEventId = 20003 # Constant c_int +UIA_CalendarControlTypeId = 50001 # Constant c_int +UIA_AutomationPropertyChangedEventId = 20004 # Constant c_int +UIA_CheckBoxControlTypeId = 50002 # Constant c_int +UIA_AutomationFocusChangedEventId = 20005 # Constant c_int +UIA_ComboBoxControlTypeId = 50003 # Constant c_int +UIA_AsyncContentLoadedEventId = 20006 # Constant c_int +UIA_EditControlTypeId = 50004 # Constant c_int +UIA_MenuClosedEventId = 20007 # Constant c_int +UIA_HyperlinkControlTypeId = 50005 # Constant c_int +UIA_LayoutInvalidatedEventId = 20008 # Constant c_int +UIA_ImageControlTypeId = 50006 # Constant c_int +UIA_Invoke_InvokedEventId = 20009 # Constant c_int +UIA_ListItemControlTypeId = 50007 # Constant c_int +UIA_SelectionItem_ElementAddedToSelectionEventId = 20010 # Constant c_int +UIA_ListControlTypeId = 50008 # Constant c_int +UIA_SelectionItem_ElementRemovedFromSelectionEventId = 20011 # Constant c_int +UIA_MenuControlTypeId = 50009 # Constant c_int +UIA_SelectionItem_ElementSelectedEventId = 20012 # Constant c_int +UIA_MenuBarControlTypeId = 50010 # Constant c_int +UIA_Selection_InvalidatedEventId = 20013 # Constant c_int +UIA_MenuItemControlTypeId = 50011 # Constant c_int +UIA_Text_TextSelectionChangedEventId = 20014 # Constant c_int +UIA_ProgressBarControlTypeId = 50012 # Constant c_int +UIA_Text_TextChangedEventId = 20015 # Constant c_int +UIA_RadioButtonControlTypeId = 50013 # Constant c_int +UIA_Window_WindowOpenedEventId = 20016 # Constant c_int +UIA_ScrollBarControlTypeId = 50014 # Constant c_int +UIA_Window_WindowClosedEventId = 20017 # Constant c_int +UIA_SliderControlTypeId = 50015 # Constant c_int +UIA_MenuModeStartEventId = 20018 # Constant c_int +UIA_SpinnerControlTypeId = 50016 # Constant c_int +UIA_MenuModeEndEventId = 20019 # Constant c_int +UIA_StatusBarControlTypeId = 50017 # Constant c_int +UIA_InputReachedTargetEventId = 20020 # Constant c_int +UIA_TabControlTypeId = 50018 # Constant c_int +UIA_InputReachedOtherElementEventId = 20021 # Constant c_int +UIA_TabItemControlTypeId = 50019 # Constant c_int +UIA_InputDiscardedEventId = 20022 # Constant c_int +UIA_TextControlTypeId = 50020 # Constant c_int +UIA_SystemAlertEventId = 20023 # Constant c_int +UIA_ToolBarControlTypeId = 50021 # Constant c_int +UIA_LiveRegionChangedEventId = 20024 # Constant c_int +UIA_ToolTipControlTypeId = 50022 # Constant c_int +UIA_HostedFragmentRootsInvalidatedEventId = 20025 # Constant c_int +UIA_TreeControlTypeId = 50023 # Constant c_int +UIA_Drag_DragStartEventId = 20026 # Constant c_int +UIA_TreeItemControlTypeId = 50024 # Constant c_int +UIA_Drag_DragCancelEventId = 20027 # Constant c_int +UIA_CustomControlTypeId = 50025 # Constant c_int +UIA_Drag_DragCompleteEventId = 20028 # Constant c_int +UIA_GroupControlTypeId = 50026 # Constant c_int +UIA_DropTarget_DragEnterEventId = 20029 # Constant c_int +UIA_ThumbControlTypeId = 50027 # Constant c_int +UIA_DropTarget_DragLeaveEventId = 20030 # Constant c_int +UIA_DataGridControlTypeId = 50028 # Constant c_int +UIA_DropTarget_DroppedEventId = 20031 # Constant c_int +UIA_DataItemControlTypeId = 50029 # Constant c_int +UIA_TextEdit_TextChangedEventId = 20032 # Constant c_int +UIA_DocumentControlTypeId = 50030 # Constant c_int +UIA_TextEdit_ConversionTargetChangedEventId = 20033 # Constant c_int +UIA_SplitButtonControlTypeId = 50031 # Constant c_int +UIA_ChangesEventId = 20034 # Constant c_int +UIA_WindowControlTypeId = 50032 # Constant c_int +UIA_NotificationEventId = 20035 # Constant c_int +UIA_PaneControlTypeId = 50033 # Constant c_int +UIA_ActiveTextPositionChangedEventId = 20036 # Constant c_int +UIA_HeaderControlTypeId = 50034 # Constant c_int +UIA_RuntimeIdPropertyId = 30000 # Constant c_int +UIA_HeaderItemControlTypeId = 50035 # Constant c_int +UIA_BoundingRectanglePropertyId = 30001 # Constant c_int +UIA_TableControlTypeId = 50036 # Constant c_int +UIA_ProcessIdPropertyId = 30002 # Constant c_int +UIA_TitleBarControlTypeId = 50037 # Constant c_int +UIA_ControlTypePropertyId = 30003 # Constant c_int +UIA_SeparatorControlTypeId = 50038 # Constant c_int +UIA_LocalizedControlTypePropertyId = 30004 # Constant c_int +UIA_SemanticZoomControlTypeId = 50039 # Constant c_int +UIA_NamePropertyId = 30005 # Constant c_int +UIA_AppBarControlTypeId = 50040 # Constant c_int +UIA_AcceleratorKeyPropertyId = 30006 # Constant c_int +AnnotationType_Unknown = 60000 # Constant c_int +UIA_AccessKeyPropertyId = 30007 # Constant c_int +AnnotationType_SpellingError = 60001 # Constant c_int +UIA_HasKeyboardFocusPropertyId = 30008 # Constant c_int +AnnotationType_GrammarError = 60002 # Constant c_int +UIA_IsKeyboardFocusablePropertyId = 30009 # Constant c_int +AnnotationType_Comment = 60003 # Constant c_int +UIA_IsEnabledPropertyId = 30010 # Constant c_int +AnnotationType_FormulaError = 60004 # Constant c_int +UIA_AutomationIdPropertyId = 30011 # Constant c_int +AnnotationType_TrackChanges = 60005 # Constant c_int +UIA_ClassNamePropertyId = 30012 # Constant c_int +AnnotationType_Header = 60006 # Constant c_int +UIA_HelpTextPropertyId = 30013 # Constant c_int +AnnotationType_Footer = 60007 # Constant c_int +UIA_ClickablePointPropertyId = 30014 # Constant c_int +AnnotationType_Highlighted = 60008 # Constant c_int +UIA_CulturePropertyId = 30015 # Constant c_int +AnnotationType_Endnote = 60009 # Constant c_int +UIA_IsControlElementPropertyId = 30016 # Constant c_int +AnnotationType_Footnote = 60010 # Constant c_int +UIA_IsContentElementPropertyId = 30017 # Constant c_int +AnnotationType_InsertionChange = 60011 # Constant c_int +UIA_LabeledByPropertyId = 30018 # Constant c_int +AnnotationType_DeletionChange = 60012 # Constant c_int +UIA_IsPasswordPropertyId = 30019 # Constant c_int +AnnotationType_MoveChange = 60013 # Constant c_int +UIA_NativeWindowHandlePropertyId = 30020 # Constant c_int +AnnotationType_FormatChange = 60014 # Constant c_int +UIA_ItemTypePropertyId = 30021 # Constant c_int +AnnotationType_UnsyncedChange = 60015 # Constant c_int +UIA_IsOffscreenPropertyId = 30022 # Constant c_int +AnnotationType_EditingLockedChange = 60016 # Constant c_int +UIA_OrientationPropertyId = 30023 # Constant c_int +AnnotationType_ExternalChange = 60017 # Constant c_int +UIA_FrameworkIdPropertyId = 30024 # Constant c_int +AnnotationType_ConflictingChange = 60018 # Constant c_int +UIA_IsRequiredForFormPropertyId = 30025 # Constant c_int +AnnotationType_Author = 60019 # Constant c_int +UIA_ItemStatusPropertyId = 30026 # Constant c_int +AnnotationType_AdvancedProofingIssue = 60020 # Constant c_int +UIA_IsDockPatternAvailablePropertyId = 30027 # Constant c_int +AnnotationType_DataValidationError = 60021 # Constant c_int +UIA_IsExpandCollapsePatternAvailablePropertyId = 30028 # Constant c_int +AnnotationType_CircularReferenceError = 60022 # Constant c_int +UIA_IsGridItemPatternAvailablePropertyId = 30029 # Constant c_int +AnnotationType_Mathematics = 60023 # Constant c_int +UIA_IsGridPatternAvailablePropertyId = 30030 # Constant c_int +StyleId_Custom = 70000 # Constant c_int +UIA_IsInvokePatternAvailablePropertyId = 30031 # Constant c_int +StyleId_Heading1 = 70001 # Constant c_int +UIA_IsMultipleViewPatternAvailablePropertyId = 30032 # Constant c_int +StyleId_Heading2 = 70002 # Constant c_int +UIA_IsRangeValuePatternAvailablePropertyId = 30033 # Constant c_int +StyleId_Heading3 = 70003 # Constant c_int +UIA_IsScrollPatternAvailablePropertyId = 30034 # Constant c_int +StyleId_Heading4 = 70004 # Constant c_int +UIA_IsScrollItemPatternAvailablePropertyId = 30035 # Constant c_int +StyleId_Heading5 = 70005 # Constant c_int +UIA_IsSelectionItemPatternAvailablePropertyId = 30036 # Constant c_int +StyleId_Heading6 = 70006 # Constant c_int +UIA_IsSelectionPatternAvailablePropertyId = 30037 # Constant c_int +StyleId_Heading7 = 70007 # Constant c_int +UIA_IsTablePatternAvailablePropertyId = 30038 # Constant c_int +StyleId_Heading8 = 70008 # Constant c_int +UIA_IsTableItemPatternAvailablePropertyId = 30039 # Constant c_int +StyleId_Heading9 = 70009 # Constant c_int +UIA_IsTextPatternAvailablePropertyId = 30040 # Constant c_int +StyleId_Title = 70010 # Constant c_int +UIA_IsTogglePatternAvailablePropertyId = 30041 # Constant c_int +StyleId_Subtitle = 70011 # Constant c_int +UIA_IsTransformPatternAvailablePropertyId = 30042 # Constant c_int +StyleId_Normal = 70012 # Constant c_int +UIA_IsValuePatternAvailablePropertyId = 30043 # Constant c_int +StyleId_Emphasis = 70013 # Constant c_int +UIA_IsWindowPatternAvailablePropertyId = 30044 # Constant c_int +StyleId_Quote = 70014 # Constant c_int +UIA_ValueValuePropertyId = 30045 # Constant c_int +StyleId_BulletedList = 70015 # Constant c_int +UIA_ValueIsReadOnlyPropertyId = 30046 # Constant c_int +StyleId_NumberedList = 70016 # Constant c_int +UIA_RangeValueValuePropertyId = 30047 # Constant c_int +UIA_CustomLandmarkTypeId = 80000 # Constant c_int +HeadingLevel1 = 80051 # Constant c_int +class Library(object): + name = 'UIAutomationClient' + _reg_typelib_ = ('{944DE083-8FB8-45CF-BCB7-C477ACB2F897}', 1, 0) + +class IUIAutomationElement2(IUIAutomationElement): _case_insensitive_ = True - _iid_ = GUID('{204E8572-CFC3-4C11-B0C8-7DA7420750B7}') + _iid_ = GUID('{6749C683-F70D-4487-A698-5F79D55290D6}') + _idlflags_ = [] +class IUIAutomationElement3(IUIAutomationElement2): + _case_insensitive_ = True + _iid_ = GUID('{8471DF34-AEE0-4A01-A7DE-7DB9AF12C296}') + _idlflags_ = [] +class IUIAutomationElement4(IUIAutomationElement3): + _case_insensitive_ = True + _iid_ = GUID('{3B6E233C-52FB-4063-A4C9-77C075C2A06B}') + _idlflags_ = [] +class IUIAutomationElement5(IUIAutomationElement4): + _case_insensitive_ = True + _iid_ = GUID('{98141C1D-0D0E-4175-BBE2-6BFF455842A7}') _idlflags_ = [] -# values for enumeration 'TreeTraversalOptions' -TreeTraversalOptions_Default = 0 -TreeTraversalOptions_PostOrder = 1 -TreeTraversalOptions_LastToFirstOrder = 2 -TreeTraversalOptions = c_int # enum -IUIAutomationElement7._methods_ = [ - COMMETHOD([], HRESULT, 'FindFirstWithOptions', +# values for enumeration 'TreeScope' +TreeScope_None = 0 +TreeScope_Element = 1 +TreeScope_Children = 2 +TreeScope_Descendants = 4 +TreeScope_Parent = 8 +TreeScope_Ancestors = 16 +TreeScope_Subtree = 7 +TreeScope = c_int # enum +class IUIAutomationCacheRequest(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{B32A92B5-BC25-4078-9C08-D7EE95C48E03}') + _idlflags_ = [] + +# values for enumeration 'OrientationType' +OrientationType_None = 0 +OrientationType_Horizontal = 1 +OrientationType_Vertical = 2 +OrientationType = c_int # enum +IUIAutomationElement._methods_ = [ + COMMETHOD([], HRESULT, 'SetFocus'), + COMMETHOD([], HRESULT, 'GetRuntimeId', + ( ['out', 'retval'], POINTER(_midlSAFEARRAY(c_int)), 'runtimeId' )), + COMMETHOD([], HRESULT, 'FindFirst', ( ['in'], TreeScope, 'scope' ), ( ['in'], POINTER(IUIAutomationCondition), 'condition' ), - ( ['in'], TreeTraversalOptions, 'traversalOptions' ), - ( ['in'], POINTER(IUIAutomationElement), 'root' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'found' )), - COMMETHOD([], HRESULT, 'FindAllWithOptions', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'found' )), + COMMETHOD([], HRESULT, 'FindAll', ( ['in'], TreeScope, 'scope' ), ( ['in'], POINTER(IUIAutomationCondition), 'condition' ), - ( ['in'], TreeTraversalOptions, 'traversalOptions' ), - ( ['in'], POINTER(IUIAutomationElement), 'root' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'found' )), - COMMETHOD([], HRESULT, 'FindFirstWithOptionsBuildCache', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'found' )), + COMMETHOD([], HRESULT, 'FindFirstBuildCache', ( ['in'], TreeScope, 'scope' ), ( ['in'], POINTER(IUIAutomationCondition), 'condition' ), ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['in'], TreeTraversalOptions, 'traversalOptions' ), - ( ['in'], POINTER(IUIAutomationElement), 'root' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'found' )), - COMMETHOD([], HRESULT, 'FindAllWithOptionsBuildCache', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'found' )), + COMMETHOD([], HRESULT, 'FindAllBuildCache', ( ['in'], TreeScope, 'scope' ), ( ['in'], POINTER(IUIAutomationCondition), 'condition' ), ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['in'], TreeTraversalOptions, 'traversalOptions' ), - ( ['in'], POINTER(IUIAutomationElement), 'root' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'found' )), - COMMETHOD([], HRESULT, 'GetCurrentMetadataValue', - ( ['in'], c_int, 'targetId' ), - ( ['in'], c_int, 'metadataId' ), - ( ['retval', 'out'], POINTER(VARIANT), 'returnVal' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'found' )), + COMMETHOD([], HRESULT, 'BuildUpdatedCache', + ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'updatedElement' )), + COMMETHOD([], HRESULT, 'GetCurrentPropertyValue', + ( ['in'], c_int, 'propertyId' ), + ( ['out', 'retval'], POINTER(VARIANT), 'retVal' )), + COMMETHOD([], HRESULT, 'GetCurrentPropertyValueEx', + ( ['in'], c_int, 'propertyId' ), + ( ['in'], c_int, 'ignoreDefaultValue' ), + ( ['out', 'retval'], POINTER(VARIANT), 'retVal' )), + COMMETHOD([], HRESULT, 'GetCachedPropertyValue', + ( ['in'], c_int, 'propertyId' ), + ( ['out', 'retval'], POINTER(VARIANT), 'retVal' )), + COMMETHOD([], HRESULT, 'GetCachedPropertyValueEx', + ( ['in'], c_int, 'propertyId' ), + ( ['in'], c_int, 'ignoreDefaultValue' ), + ( ['out', 'retval'], POINTER(VARIANT), 'retVal' )), + COMMETHOD([], HRESULT, 'GetCurrentPatternAs', + ( ['in'], c_int, 'patternId' ), + ( ['in'], POINTER(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.GUID), 'riid' ), + ( ['out', 'retval'], POINTER(c_void_p), 'patternObject' )), + COMMETHOD([], HRESULT, 'GetCachedPatternAs', + ( ['in'], c_int, 'patternId' ), + ( ['in'], POINTER(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.GUID), 'riid' ), + ( ['out', 'retval'], POINTER(c_void_p), 'patternObject' )), + COMMETHOD([], HRESULT, 'GetCurrentPattern', + ( ['in'], c_int, 'patternId' ), + ( ['out', 'retval'], POINTER(POINTER(IUnknown)), 'patternObject' )), + COMMETHOD([], HRESULT, 'GetCachedPattern', + ( ['in'], c_int, 'patternId' ), + ( ['out', 'retval'], POINTER(POINTER(IUnknown)), 'patternObject' )), + COMMETHOD([], HRESULT, 'GetCachedParent', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'parent' )), + COMMETHOD([], HRESULT, 'GetCachedChildren', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'children' )), + COMMETHOD(['propget'], HRESULT, 'CurrentProcessId', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentControlType', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentLocalizedControlType', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentName', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentAcceleratorKey', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentAccessKey', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentHasKeyboardFocus', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentIsKeyboardFocusable', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentIsEnabled', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentAutomationId', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentClassName', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentHelpText', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentCulture', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentIsControlElement', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentIsContentElement', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentIsPassword', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentNativeWindowHandle', + ( ['out', 'retval'], POINTER(c_void_p), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentItemType', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentIsOffscreen', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentOrientation', + ( ['out', 'retval'], POINTER(OrientationType), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentFrameworkId', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentIsRequiredForForm', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentItemStatus', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentBoundingRectangle', + ( ['out', 'retval'], POINTER(tagRECT), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentLabeledBy', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentAriaRole', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentAriaProperties', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentIsDataValidForForm', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentControllerFor', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentDescribedBy', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentFlowsTo', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentProviderDescription', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedProcessId', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedControlType', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedLocalizedControlType', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedName', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedAcceleratorKey', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedAccessKey', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedHasKeyboardFocus', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedIsKeyboardFocusable', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedIsEnabled', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedAutomationId', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedClassName', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedHelpText', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedCulture', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedIsControlElement', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedIsContentElement', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedIsPassword', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedNativeWindowHandle', + ( ['out', 'retval'], POINTER(c_void_p), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedItemType', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedIsOffscreen', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedOrientation', + ( ['out', 'retval'], POINTER(OrientationType), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedFrameworkId', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedIsRequiredForForm', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedItemStatus', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedBoundingRectangle', + ( ['out', 'retval'], POINTER(tagRECT), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedLabeledBy', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedAriaRole', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedAriaProperties', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedIsDataValidForForm', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedControllerFor', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedDescribedBy', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedFlowsTo', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedProviderDescription', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD([], HRESULT, 'GetClickablePoint', + ( ['out'], POINTER(tagPOINT), 'clickable' ), + ( ['out', 'retval'], POINTER(c_int), 'gotClickable' )), ] ################################################################ -## code template for IUIAutomationElement7 implementation -##class IUIAutomationElement7_Impl(object): -## def FindAllWithOptionsBuildCache(self, scope, condition, cacheRequest, traversalOptions, root): +## code template for IUIAutomationElement implementation +##class IUIAutomationElement_Impl(object): +## def SetFocus(self): ## '-no docstring-' -## #return found +## #return ## -## def GetCurrentMetadataValue(self, targetId, metadataId): +## def GetRuntimeId(self): ## '-no docstring-' -## #return returnVal +## #return runtimeId ## -## def FindFirstWithOptions(self, scope, condition, traversalOptions, root): +## def FindFirst(self, scope, condition): ## '-no docstring-' ## #return found ## -## def FindAllWithOptions(self, scope, condition, traversalOptions, root): +## def FindAll(self, scope, condition): ## '-no docstring-' ## #return found ## -## def FindFirstWithOptionsBuildCache(self, scope, condition, cacheRequest, traversalOptions, root): +## def FindFirstBuildCache(self, scope, condition, cacheRequest): ## '-no docstring-' ## #return found ## - -HeadingLevel8 = 80058 # Constant c_int -UIA_OverlineStyleAttributeId = 40024 # Constant c_int -AnnotationType_Highlighted = 60008 # Constant c_int -UIA_StylesFillColorPropertyId = 30122 # Constant c_int -UIA_DataItemControlTypeId = 50029 # Constant c_int -UIA_StrikethroughStyleAttributeId = 40026 # Constant c_int -UIA_Drag_DragStartEventId = 20026 # Constant c_int -UIA_SummaryChangeId = 90000 # Constant c_int - -# values for enumeration 'ScrollAmount' -ScrollAmount_LargeDecrement = 0 -ScrollAmount_SmallDecrement = 1 -ScrollAmount_NoAmount = 2 -ScrollAmount_LargeIncrement = 3 -ScrollAmount_SmallIncrement = 4 -ScrollAmount = c_int # enum -UIA_SayAsInterpretAsMetadataId = 100000 # Constant c_int -UIA_UnderlineStyleAttributeId = 40030 # Constant c_int -class IUIAutomationPropertyChangedEventHandler(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{40CD37D4-C756-4B0C-8C6F-BDDFEEB13B50}') - _idlflags_ = ['oleautomation'] -IUIAutomationPropertyChangedEventHandler._methods_ = [ - COMMETHOD([], HRESULT, 'HandlePropertyChangedEvent', - ( ['in'], POINTER(IUIAutomationElement), 'sender' ), - ( ['in'], c_int, 'propertyId' ), - ( ['in'], VARIANT, 'newValue' )), -] -################################################################ -## code template for IUIAutomationPropertyChangedEventHandler implementation -##class IUIAutomationPropertyChangedEventHandler_Impl(object): -## def HandlePropertyChangedEvent(self, sender, propertyId, newValue): +## def FindAllBuildCache(self, scope, condition, cacheRequest): +## '-no docstring-' +## #return found +## +## def BuildUpdatedCache(self, cacheRequest): +## '-no docstring-' +## #return updatedElement +## +## def GetCurrentPropertyValue(self, propertyId): +## '-no docstring-' +## #return retVal +## +## def GetCurrentPropertyValueEx(self, propertyId, ignoreDefaultValue): +## '-no docstring-' +## #return retVal +## +## def GetCachedPropertyValue(self, propertyId): +## '-no docstring-' +## #return retVal +## +## def GetCachedPropertyValueEx(self, propertyId, ignoreDefaultValue): +## '-no docstring-' +## #return retVal +## +## def GetCurrentPatternAs(self, patternId, riid): ## '-no docstring-' -## #return +## #return patternObject ## - -class IUIAutomationStructureChangedEventHandler(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{E81D1B4E-11C5-42F8-9754-E7036C79F054}') - _idlflags_ = ['oleautomation'] - -# values for enumeration 'StructureChangeType' -StructureChangeType_ChildAdded = 0 -StructureChangeType_ChildRemoved = 1 -StructureChangeType_ChildrenInvalidated = 2 -StructureChangeType_ChildrenBulkAdded = 3 -StructureChangeType_ChildrenBulkRemoved = 4 -StructureChangeType_ChildrenReordered = 5 -StructureChangeType = c_int # enum -IUIAutomationStructureChangedEventHandler._methods_ = [ - COMMETHOD([], HRESULT, 'HandleStructureChangedEvent', - ( ['in'], POINTER(IUIAutomationElement), 'sender' ), - ( ['in'], StructureChangeType, 'changeType' ), - ( ['in'], _midlSAFEARRAY(c_int), 'runtimeId' )), -] -################################################################ -## code template for IUIAutomationStructureChangedEventHandler implementation -##class IUIAutomationStructureChangedEventHandler_Impl(object): -## def HandleStructureChangedEvent(self, sender, changeType, runtimeId): +## def GetCachedPatternAs(self, patternId, riid): ## '-no docstring-' -## #return +## #return patternObject ## - -class IUIAutomationSpreadsheetPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{7517A7C8-FAAE-4DE9-9F08-29B91E8595C1}') - _idlflags_ = [] -IUIAutomationSpreadsheetPattern._methods_ = [ - COMMETHOD([], HRESULT, 'GetItemByName', - ( ['in'], BSTR, 'name' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'element' )), -] -################################################################ -## code template for IUIAutomationSpreadsheetPattern implementation -##class IUIAutomationSpreadsheetPattern_Impl(object): -## def GetItemByName(self, name): +## def GetCurrentPattern(self, patternId): ## '-no docstring-' -## #return element +## #return patternObject ## - -class IUIAutomationNotificationEventHandler(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{C7CB2637-E6C2-4D0C-85DE-4948C02175C7}') - _idlflags_ = ['oleautomation'] - -# values for enumeration 'NotificationKind' -NotificationKind_ItemAdded = 0 -NotificationKind_ItemRemoved = 1 -NotificationKind_ActionCompleted = 2 -NotificationKind_ActionAborted = 3 -NotificationKind_Other = 4 -NotificationKind = c_int # enum - -# values for enumeration 'NotificationProcessing' -NotificationProcessing_ImportantAll = 0 -NotificationProcessing_ImportantMostRecent = 1 -NotificationProcessing_All = 2 -NotificationProcessing_MostRecent = 3 -NotificationProcessing_CurrentThenMostRecent = 4 -NotificationProcessing = c_int # enum -IUIAutomationNotificationEventHandler._methods_ = [ - COMMETHOD([], HRESULT, 'HandleNotificationEvent', - ( ['in'], POINTER(IUIAutomationElement), 'sender' ), - ( [], NotificationKind, 'NotificationKind' ), - ( [], NotificationProcessing, 'NotificationProcessing' ), - ( ['in'], BSTR, 'displayString' ), - ( ['in'], BSTR, 'activityId' )), -] -################################################################ -## code template for IUIAutomationNotificationEventHandler implementation -##class IUIAutomationNotificationEventHandler_Impl(object): -## def HandleNotificationEvent(self, sender, NotificationKind, NotificationProcessing, displayString, activityId): +## def GetCachedPattern(self, patternId): ## '-no docstring-' -## #return +## #return patternObject ## - -class IUIAutomationScrollItemPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{B488300F-D015-4F19-9C29-BB595E3645EF}') - _idlflags_ = [] -IUIAutomationScrollItemPattern._methods_ = [ - COMMETHOD([], HRESULT, 'ScrollIntoView'), -] -################################################################ -## code template for IUIAutomationScrollItemPattern implementation -##class IUIAutomationScrollItemPattern_Impl(object): -## def ScrollIntoView(self): +## def GetCachedParent(self): ## '-no docstring-' -## #return +## #return parent ## - -class IUIAutomationFocusChangedEventHandler(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{C270F6B5-5C69-4290-9745-7A7F97169468}') - _idlflags_ = ['oleautomation'] -IUIAutomationFocusChangedEventHandler._methods_ = [ - COMMETHOD([], HRESULT, 'HandleFocusChangedEvent', - ( ['in'], POINTER(IUIAutomationElement), 'sender' )), -] -################################################################ -## code template for IUIAutomationFocusChangedEventHandler implementation -##class IUIAutomationFocusChangedEventHandler_Impl(object): -## def HandleFocusChangedEvent(self, sender): +## def GetCachedChildren(self): ## '-no docstring-' -## #return +## #return children ## - -class IUIAutomationTablePattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{620E691C-EA96-4710-A850-754B24CE2417}') - _idlflags_ = [] - -# values for enumeration 'RowOrColumnMajor' -RowOrColumnMajor_RowMajor = 0 -RowOrColumnMajor_ColumnMajor = 1 -RowOrColumnMajor_Indeterminate = 2 -RowOrColumnMajor = c_int # enum -IUIAutomationTablePattern._methods_ = [ - COMMETHOD([], HRESULT, 'GetCurrentRowHeaders', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), - COMMETHOD([], HRESULT, 'GetCurrentColumnHeaders', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentRowOrColumnMajor', - ( ['retval', 'out'], POINTER(RowOrColumnMajor), 'retVal' )), - COMMETHOD([], HRESULT, 'GetCachedRowHeaders', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), - COMMETHOD([], HRESULT, 'GetCachedColumnHeaders', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedRowOrColumnMajor', - ( ['retval', 'out'], POINTER(RowOrColumnMajor), 'retVal' )), -] -################################################################ -## code template for IUIAutomationTablePattern implementation -##class IUIAutomationTablePattern_Impl(object): ## @property -## def CachedRowOrColumnMajor(self): +## def CurrentProcessId(self): ## '-no docstring-' ## #return retVal ## -## def GetCachedColumnHeaders(self): +## @property +## def CurrentControlType(self): ## '-no docstring-' ## #return retVal ## -## def GetCachedRowHeaders(self): +## @property +## def CurrentLocalizedControlType(self): ## '-no docstring-' ## #return retVal ## -## def GetCurrentColumnHeaders(self): +## @property +## def CurrentName(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentRowOrColumnMajor(self): +## def CurrentAcceleratorKey(self): ## '-no docstring-' ## #return retVal ## -## def GetCurrentRowHeaders(self): +## @property +## def CurrentAccessKey(self): ## '-no docstring-' ## #return retVal ## - -class IUIAutomationSelectionPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{5ED5202E-B2AC-47A6-B638-4B0BF140D78E}') - _idlflags_ = [] -IUIAutomationSelectionPattern._methods_ = [ - COMMETHOD([], HRESULT, 'GetCurrentSelection', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentCanSelectMultiple', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentIsSelectionRequired', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD([], HRESULT, 'GetCachedSelection', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedCanSelectMultiple', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedIsSelectionRequired', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), -] -################################################################ -## code template for IUIAutomationSelectionPattern implementation -##class IUIAutomationSelectionPattern_Impl(object): -## def GetCurrentSelection(self): +## @property +## def CurrentHasKeyboardFocus(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentIsSelectionRequired(self): +## def CurrentIsKeyboardFocusable(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedIsSelectionRequired(self): +## def CurrentIsEnabled(self): ## '-no docstring-' ## #return retVal ## -## def GetCachedSelection(self): +## @property +## def CurrentAutomationId(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedCanSelectMultiple(self): +## def CurrentClassName(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentCanSelectMultiple(self): +## def CurrentHelpText(self): ## '-no docstring-' ## #return retVal ## - -class IUIAutomationTextEditTextChangedEventHandler(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{92FAA680-E704-4156-931A-E32D5BB38F3F}') - _idlflags_ = ['oleautomation'] - -# values for enumeration 'TextEditChangeType' -TextEditChangeType_None = 0 -TextEditChangeType_AutoCorrect = 1 -TextEditChangeType_Composition = 2 -TextEditChangeType_CompositionFinalized = 3 -TextEditChangeType_AutoComplete = 4 -TextEditChangeType = c_int # enum -IUIAutomationTextEditTextChangedEventHandler._methods_ = [ - COMMETHOD([], HRESULT, 'HandleTextEditTextChangedEvent', - ( ['in'], POINTER(IUIAutomationElement), 'sender' ), - ( ['in'], TextEditChangeType, 'TextEditChangeType' ), - ( ['in'], _midlSAFEARRAY(BSTR), 'eventStrings' )), -] -################################################################ -## code template for IUIAutomationTextEditTextChangedEventHandler implementation -##class IUIAutomationTextEditTextChangedEventHandler_Impl(object): -## def HandleTextEditTextChangedEvent(self, sender, TextEditChangeType, eventStrings): +## @property +## def CurrentCulture(self): ## '-no docstring-' -## #return +## #return retVal ## - -UIA_IsTableItemPatternAvailablePropertyId = 30039 # Constant c_int -UIA_GridPatternId = 10006 # Constant c_int -StyleId_Custom = 70000 # Constant c_int -UIA_IsActiveAttributeId = 40036 # Constant c_int -class IUIAutomationChangesEventHandler(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{58EDCA55-2C3E-4980-B1B9-56C17F27A2A0}') - _idlflags_ = ['oleautomation'] -class UiaChangeInfo(Structure): - pass -IUIAutomationChangesEventHandler._methods_ = [ - COMMETHOD([], HRESULT, 'HandleChangesEvent', - ( ['in'], POINTER(IUIAutomationElement), 'sender' ), - ( ['in'], POINTER(UiaChangeInfo), 'uiaChanges' ), - ( ['in'], c_int, 'changesCount' )), -] -################################################################ -## code template for IUIAutomationChangesEventHandler implementation -##class IUIAutomationChangesEventHandler_Impl(object): -## def HandleChangesEvent(self, sender, uiaChanges, changesCount): +## @property +## def CurrentIsControlElement(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CurrentIsContentElement(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CurrentIsPassword(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CurrentNativeWindowHandle(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CurrentItemType(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CurrentIsOffscreen(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CurrentOrientation(self): ## '-no docstring-' -## #return +## #return retVal ## - -class IUIAutomationSelectionPattern2(IUIAutomationSelectionPattern): - _case_insensitive_ = True - _iid_ = GUID('{0532BFAE-C011-4E32-A343-6D642D798555}') - _idlflags_ = [] -IUIAutomationSelectionPattern2._methods_ = [ - COMMETHOD(['propget'], HRESULT, 'CurrentFirstSelectedItem', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentLastSelectedItem', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentCurrentSelectedItem', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentItemCount', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedFirstSelectedItem', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedLastSelectedItem', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedCurrentSelectedItem', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedItemCount', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), -] -################################################################ -## code template for IUIAutomationSelectionPattern2 implementation -##class IUIAutomationSelectionPattern2_Impl(object): ## @property -## def CachedFirstSelectedItem(self): +## def CurrentFrameworkId(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedCurrentSelectedItem(self): +## def CurrentIsRequiredForForm(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentCurrentSelectedItem(self): +## def CurrentItemStatus(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedLastSelectedItem(self): +## def CurrentBoundingRectangle(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentItemCount(self): +## def CurrentLabeledBy(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedItemCount(self): +## def CurrentAriaRole(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentFirstSelectedItem(self): +## def CurrentAriaProperties(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentLastSelectedItem(self): +## def CurrentIsDataValidForForm(self): ## '-no docstring-' ## #return retVal ## - -class IUIAutomationSelectionItemPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{A8EFA66A-0FDA-421A-9194-38021F3578EA}') - _idlflags_ = [] -IUIAutomationSelectionItemPattern._methods_ = [ - COMMETHOD([], HRESULT, 'Select'), - COMMETHOD([], HRESULT, 'AddToSelection'), - COMMETHOD([], HRESULT, 'RemoveFromSelection'), - COMMETHOD(['propget'], HRESULT, 'CurrentIsSelected', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentSelectionContainer', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedIsSelected', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedSelectionContainer', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), -] -################################################################ -## code template for IUIAutomationSelectionItemPattern implementation -##class IUIAutomationSelectionItemPattern_Impl(object): -## def RemoveFromSelection(self): +## @property +## def CurrentControllerFor(self): ## '-no docstring-' -## #return +## #return retVal ## ## @property -## def CachedSelectionContainer(self): +## def CurrentDescribedBy(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedIsSelected(self): +## def CurrentFlowsTo(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentIsSelected(self): +## def CurrentProviderDescription(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentSelectionContainer(self): +## def CachedProcessId(self): ## '-no docstring-' ## #return retVal ## -## def AddToSelection(self): +## @property +## def CachedControlType(self): ## '-no docstring-' -## #return +## #return retVal ## -## def Select(self): +## @property +## def CachedLocalizedControlType(self): ## '-no docstring-' -## #return +## #return retVal ## - -UIA_AutomationPropertyChangedEventId = 20004 # Constant c_int -UiaChangeInfo._fields_ = [ - ('uiaId', c_int), - ('payload', VARIANT), - ('extraInfo', VARIANT), -] -assert sizeof(UiaChangeInfo) == 40, sizeof(UiaChangeInfo) -assert alignment(UiaChangeInfo) == 8, alignment(UiaChangeInfo) -UIA_ValueValuePropertyId = 30045 # Constant c_int -UIA_WindowControlTypeId = 50032 # Constant c_int -class IUIAutomationTextRange(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{A543CC6A-F4AE-494B-8239-C814481187A8}') - _idlflags_ = [] -class IUIAutomationTextRange2(IUIAutomationTextRange): - _case_insensitive_ = True - _iid_ = GUID('{BB9B40E0-5E04-46BD-9BE0-4B601B9AFAD4}') - _idlflags_ = [] -class IUIAutomationTextRange3(IUIAutomationTextRange2): - _case_insensitive_ = True - _iid_ = GUID('{6A315D69-5512-4C2E-85F0-53FCE6DD4BC2}') - _idlflags_ = [] - -# values for enumeration 'TextPatternRangeEndpoint' -TextPatternRangeEndpoint_Start = 0 -TextPatternRangeEndpoint_End = 1 -TextPatternRangeEndpoint = c_int # enum - -# values for enumeration 'TextUnit' -TextUnit_Character = 0 -TextUnit_Format = 1 -TextUnit_Word = 2 -TextUnit_Line = 3 -TextUnit_Paragraph = 4 -TextUnit_Page = 5 -TextUnit_Document = 6 -TextUnit = c_int # enum -IUIAutomationTextRange._methods_ = [ - COMMETHOD([], HRESULT, 'Clone', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationTextRange)), 'clonedRange' )), - COMMETHOD([], HRESULT, 'Compare', - ( ['in'], POINTER(IUIAutomationTextRange), 'range' ), - ( ['retval', 'out'], POINTER(c_int), 'areSame' )), - COMMETHOD([], HRESULT, 'CompareEndpoints', - ( ['in'], TextPatternRangeEndpoint, 'srcEndPoint' ), - ( ['in'], POINTER(IUIAutomationTextRange), 'range' ), - ( ['in'], TextPatternRangeEndpoint, 'targetEndPoint' ), - ( ['retval', 'out'], POINTER(c_int), 'compValue' )), - COMMETHOD([], HRESULT, 'ExpandToEnclosingUnit', - ( ['in'], TextUnit, 'TextUnit' )), - COMMETHOD([], HRESULT, 'FindAttribute', - ( ['in'], c_int, 'attr' ), - ( ['in'], VARIANT, 'val' ), - ( ['in'], c_int, 'backward' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationTextRange)), 'found' )), - COMMETHOD([], HRESULT, 'FindText', - ( ['in'], BSTR, 'text' ), - ( ['in'], c_int, 'backward' ), - ( ['in'], c_int, 'ignoreCase' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationTextRange)), 'found' )), - COMMETHOD([], HRESULT, 'GetAttributeValue', - ( ['in'], c_int, 'attr' ), - ( ['retval', 'out'], POINTER(VARIANT), 'value' )), - COMMETHOD([], HRESULT, 'GetBoundingRectangles', - ( ['retval', 'out'], POINTER(_midlSAFEARRAY(c_double)), 'boundingRects' )), - COMMETHOD([], HRESULT, 'GetEnclosingElement', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'enclosingElement' )), - COMMETHOD([], HRESULT, 'GetText', - ( ['in'], c_int, 'maxLength' ), - ( ['retval', 'out'], POINTER(BSTR), 'text' )), - COMMETHOD([], HRESULT, 'Move', - ( ['in'], TextUnit, 'unit' ), - ( ['in'], c_int, 'count' ), - ( ['retval', 'out'], POINTER(c_int), 'moved' )), - COMMETHOD([], HRESULT, 'MoveEndpointByUnit', - ( ['in'], TextPatternRangeEndpoint, 'endpoint' ), - ( ['in'], TextUnit, 'unit' ), - ( ['in'], c_int, 'count' ), - ( ['retval', 'out'], POINTER(c_int), 'moved' )), - COMMETHOD([], HRESULT, 'MoveEndpointByRange', - ( ['in'], TextPatternRangeEndpoint, 'srcEndPoint' ), - ( ['in'], POINTER(IUIAutomationTextRange), 'range' ), - ( ['in'], TextPatternRangeEndpoint, 'targetEndPoint' )), - COMMETHOD([], HRESULT, 'Select'), - COMMETHOD([], HRESULT, 'AddToSelection'), - COMMETHOD([], HRESULT, 'RemoveFromSelection'), - COMMETHOD([], HRESULT, 'ScrollIntoView', - ( ['in'], c_int, 'alignToTop' )), - COMMETHOD([], HRESULT, 'GetChildren', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'children' )), -] -################################################################ -## code template for IUIAutomationTextRange implementation -##class IUIAutomationTextRange_Impl(object): -## def CompareEndpoints(self, srcEndPoint, range, targetEndPoint): +## @property +## def CachedName(self): ## '-no docstring-' -## #return compValue +## #return retVal ## -## def Compare(self, range): +## @property +## def CachedAcceleratorKey(self): ## '-no docstring-' -## #return areSame +## #return retVal ## -## def MoveEndpointByUnit(self, endpoint, unit, count): +## @property +## def CachedAccessKey(self): ## '-no docstring-' -## #return moved +## #return retVal ## -## def ScrollIntoView(self, alignToTop): +## @property +## def CachedHasKeyboardFocus(self): ## '-no docstring-' -## #return +## #return retVal ## -## def AddToSelection(self): +## @property +## def CachedIsKeyboardFocusable(self): ## '-no docstring-' -## #return +## #return retVal ## -## def FindAttribute(self, attr, val, backward): +## @property +## def CachedIsEnabled(self): ## '-no docstring-' -## #return found +## #return retVal ## -## def GetEnclosingElement(self): +## @property +## def CachedAutomationId(self): ## '-no docstring-' -## #return enclosingElement +## #return retVal ## -## def ExpandToEnclosingUnit(self, TextUnit): +## @property +## def CachedClassName(self): ## '-no docstring-' -## #return +## #return retVal ## -## def Clone(self): +## @property +## def CachedHelpText(self): ## '-no docstring-' -## #return clonedRange +## #return retVal ## -## def Move(self, unit, count): +## @property +## def CachedCulture(self): ## '-no docstring-' -## #return moved +## #return retVal ## -## def FindText(self, text, backward, ignoreCase): +## @property +## def CachedIsControlElement(self): ## '-no docstring-' -## #return found +## #return retVal ## -## def GetText(self, maxLength): +## @property +## def CachedIsContentElement(self): ## '-no docstring-' -## #return text +## #return retVal ## -## def RemoveFromSelection(self): +## @property +## def CachedIsPassword(self): ## '-no docstring-' -## #return +## #return retVal ## -## def GetChildren(self): +## @property +## def CachedNativeWindowHandle(self): ## '-no docstring-' -## #return children +## #return retVal ## -## def GetAttributeValue(self, attr): +## @property +## def CachedItemType(self): ## '-no docstring-' -## #return value +## #return retVal ## -## def MoveEndpointByRange(self, srcEndPoint, range, targetEndPoint): +## @property +## def CachedIsOffscreen(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CachedOrientation(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CachedFrameworkId(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CachedIsRequiredForForm(self): ## '-no docstring-' -## #return +## #return retVal ## -## def Select(self): +## @property +## def CachedItemStatus(self): ## '-no docstring-' -## #return +## #return retVal ## -## def GetBoundingRectangles(self): +## @property +## def CachedBoundingRectangle(self): ## '-no docstring-' -## #return boundingRects +## #return retVal ## - -IUIAutomationTextRange2._methods_ = [ - COMMETHOD([], HRESULT, 'ShowContextMenu'), -] -################################################################ -## code template for IUIAutomationTextRange2 implementation -##class IUIAutomationTextRange2_Impl(object): -## def ShowContextMenu(self): +## @property +## def CachedLabeledBy(self): ## '-no docstring-' -## #return +## #return retVal ## - -IUIAutomationTextRange3._methods_ = [ - COMMETHOD([], HRESULT, 'GetEnclosingElementBuildCache', - ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'enclosingElement' )), - COMMETHOD([], HRESULT, 'GetChildrenBuildCache', - ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'children' )), - COMMETHOD([], HRESULT, 'GetAttributeValues', - ( ['in'], POINTER(c_int), 'attributeIds' ), - ( ['in'], c_int, 'attributeIdCount' ), - ( ['retval', 'out'], POINTER(_midlSAFEARRAY(VARIANT)), 'attributeValues' )), -] -################################################################ -## code template for IUIAutomationTextRange3 implementation -##class IUIAutomationTextRange3_Impl(object): -## def GetEnclosingElementBuildCache(self, cacheRequest): +## @property +## def CachedAriaRole(self): ## '-no docstring-' -## #return enclosingElement +## #return retVal ## -## def GetAttributeValues(self, attributeIds, attributeIdCount): +## @property +## def CachedAriaProperties(self): ## '-no docstring-' -## #return attributeValues +## #return retVal ## -## def GetChildrenBuildCache(self, cacheRequest): +## @property +## def CachedIsDataValidForForm(self): ## '-no docstring-' -## #return children +## #return retVal ## - -UIA_AsyncContentLoadedEventId = 20006 # Constant c_int -class IUIAutomationSynchronizedInputPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{2233BE0B-AFB7-448B-9FDA-3B378AA5EAE1}') - _idlflags_ = [] - -# values for enumeration 'SynchronizedInputType' -SynchronizedInputType_KeyUp = 1 -SynchronizedInputType_KeyDown = 2 -SynchronizedInputType_LeftMouseUp = 4 -SynchronizedInputType_LeftMouseDown = 8 -SynchronizedInputType_RightMouseUp = 16 -SynchronizedInputType_RightMouseDown = 32 -SynchronizedInputType = c_int # enum -IUIAutomationSynchronizedInputPattern._methods_ = [ - COMMETHOD([], HRESULT, 'StartListening', - ( ['in'], SynchronizedInputType, 'inputType' )), - COMMETHOD([], HRESULT, 'Cancel'), -] -################################################################ -## code template for IUIAutomationSynchronizedInputPattern implementation -##class IUIAutomationSynchronizedInputPattern_Impl(object): -## def Cancel(self): +## @property +## def CachedControllerFor(self): ## '-no docstring-' -## #return +## #return retVal ## -## def StartListening(self, inputType): +## @property +## def CachedDescribedBy(self): ## '-no docstring-' -## #return +## #return retVal ## - -UIA_AfterParagraphSpacingAttributeId = 40042 # Constant c_int -class Library(object): - name = u'UIAutomationClient' - _reg_typelib_ = ('{944DE083-8FB8-45CF-BCB7-C477ACB2F897}', 1, 0) - -class IUIAutomationInvokePattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{FB377FBE-8EA6-46D5-9C73-6499642D3059}') - _idlflags_ = [] -IUIAutomationInvokePattern._methods_ = [ - COMMETHOD([], HRESULT, 'Invoke'), -] -################################################################ -## code template for IUIAutomationInvokePattern implementation -##class IUIAutomationInvokePattern_Impl(object): -## def Invoke(self): +## @property +## def CachedFlowsTo(self): ## '-no docstring-' -## #return +## #return retVal ## - -class IUIAutomationBoolCondition(IUIAutomationCondition): - _case_insensitive_ = True - _iid_ = GUID('{1B4E1F2E-75EB-4D0B-8952-5A69988E2307}') - _idlflags_ = [] -IUIAutomationBoolCondition._methods_ = [ - COMMETHOD(['propget'], HRESULT, 'BooleanValue', - ( ['retval', 'out'], POINTER(c_int), 'boolVal' )), -] -################################################################ -## code template for IUIAutomationBoolCondition implementation -##class IUIAutomationBoolCondition_Impl(object): ## @property -## def BooleanValue(self): +## def CachedProviderDescription(self): ## '-no docstring-' -## #return boolVal +## #return retVal +## +## def GetClickablePoint(self): +## '-no docstring-' +## #return clickable, gotClickable ## -UIA_RangeValueMinimumPropertyId = 30049 # Constant c_int -UIA_AutomationFocusChangedEventId = 20005 # Constant c_int -UIA_PaneControlTypeId = 50033 # Constant c_int -class IUIAutomationTogglePattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{94CF8058-9B8D-4AB9-8BFD-4CD0A33C8C70}') - _idlflags_ = [] -# values for enumeration 'ToggleState' -ToggleState_Off = 0 -ToggleState_On = 1 -ToggleState_Indeterminate = 2 -ToggleState = c_int # enum -IUIAutomationTogglePattern._methods_ = [ - COMMETHOD([], HRESULT, 'Toggle'), - COMMETHOD(['propget'], HRESULT, 'CurrentToggleState', - ( ['retval', 'out'], POINTER(ToggleState), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedToggleState', - ( ['retval', 'out'], POINTER(ToggleState), 'retVal' )), +# values for enumeration 'LiveSetting' +Off = 0 +Polite = 1 +Assertive = 2 +LiveSetting = c_int # enum +IUIAutomationElement2._methods_ = [ + COMMETHOD(['propget'], HRESULT, 'CurrentOptimizeForVisualContent', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedOptimizeForVisualContent', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentLiveSetting', + ( ['out', 'retval'], POINTER(LiveSetting), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedLiveSetting', + ( ['out', 'retval'], POINTER(LiveSetting), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentFlowsFrom', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedFlowsFrom', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), ] ################################################################ -## code template for IUIAutomationTogglePattern implementation -##class IUIAutomationTogglePattern_Impl(object): +## code template for IUIAutomationElement2 implementation +##class IUIAutomationElement2_Impl(object): ## @property -## def CurrentToggleState(self): +## def CurrentOptimizeForVisualContent(self): ## '-no docstring-' ## #return retVal ## -## def Toggle(self): +## @property +## def CachedOptimizeForVisualContent(self): ## '-no docstring-' -## #return +## #return retVal ## ## @property -## def CachedToggleState(self): +## def CurrentLiveSetting(self): ## '-no docstring-' ## #return retVal ## - -class IUIAutomationGridPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{414C3CDC-856B-4F5B-8538-3131C6302550}') - _idlflags_ = [] -IUIAutomationGridPattern._methods_ = [ - COMMETHOD([], HRESULT, 'GetItem', - ( ['in'], c_int, 'row' ), - ( ['in'], c_int, 'column' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'element' )), - COMMETHOD(['propget'], HRESULT, 'CurrentRowCount', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentColumnCount', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedRowCount', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedColumnCount', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), -] -################################################################ -## code template for IUIAutomationGridPattern implementation -##class IUIAutomationGridPattern_Impl(object): ## @property -## def CurrentColumnCount(self): +## def CachedLiveSetting(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentRowCount(self): +## def CurrentFlowsFrom(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedColumnCount(self): +## def CachedFlowsFrom(self): ## '-no docstring-' ## #return retVal ## -## def GetItem(self, row, column): + +IUIAutomationElement3._methods_ = [ + COMMETHOD([], HRESULT, 'ShowContextMenu'), + COMMETHOD(['propget'], HRESULT, 'CurrentIsPeripheral', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedIsPeripheral', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), +] +################################################################ +## code template for IUIAutomationElement3 implementation +##class IUIAutomationElement3_Impl(object): +## def ShowContextMenu(self): ## '-no docstring-' -## #return element +## #return ## ## @property -## def CachedRowCount(self): +## def CurrentIsPeripheral(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CachedIsPeripheral(self): ## '-no docstring-' ## #return retVal ## -class IUIAutomationProxyFactory(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{85B94ECD-849D-42B6-B94D-D6DB23FDF5A4}') - _idlflags_ = [] -IUIAutomationProxyFactoryEntry._methods_ = [ - COMMETHOD(['propget'], HRESULT, 'ProxyFactory', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationProxyFactory)), 'factory' )), - COMMETHOD(['propget'], HRESULT, 'ClassName', - ( ['retval', 'out'], POINTER(BSTR), 'ClassName' )), - COMMETHOD(['propget'], HRESULT, 'ImageName', - ( ['retval', 'out'], POINTER(BSTR), 'ImageName' )), - COMMETHOD(['propget'], HRESULT, 'AllowSubstringMatch', - ( ['retval', 'out'], POINTER(c_int), 'AllowSubstringMatch' )), - COMMETHOD(['propget'], HRESULT, 'CanCheckBaseClass', - ( ['retval', 'out'], POINTER(c_int), 'CanCheckBaseClass' )), - COMMETHOD(['propget'], HRESULT, 'NeedsAdviseEvents', - ( ['retval', 'out'], POINTER(c_int), 'adviseEvents' )), - COMMETHOD(['propput'], HRESULT, 'ClassName', - ( ['in'], WSTRING, 'ClassName' )), - COMMETHOD(['propput'], HRESULT, 'ImageName', - ( ['in'], WSTRING, 'ImageName' )), - COMMETHOD(['propput'], HRESULT, 'AllowSubstringMatch', - ( ['in'], c_int, 'AllowSubstringMatch' )), - COMMETHOD(['propput'], HRESULT, 'CanCheckBaseClass', - ( ['in'], c_int, 'CanCheckBaseClass' )), - COMMETHOD(['propput'], HRESULT, 'NeedsAdviseEvents', - ( ['in'], c_int, 'adviseEvents' )), - COMMETHOD([], HRESULT, 'SetWinEventsForAutomationEvent', - ( ['in'], c_int, 'eventId' ), - ( ['in'], c_int, 'propertyId' ), - ( ['in'], _midlSAFEARRAY(c_uint), 'winEvents' )), - COMMETHOD([], HRESULT, 'GetWinEventsForAutomationEvent', - ( ['in'], c_int, 'eventId' ), - ( ['in'], c_int, 'propertyId' ), - ( ['retval', 'out'], POINTER(_midlSAFEARRAY(c_uint)), 'winEvents' )), +IUIAutomationElement4._methods_ = [ + COMMETHOD(['propget'], HRESULT, 'CurrentPositionInSet', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentSizeOfSet', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentLevel', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentAnnotationTypes', + ( ['out', 'retval'], POINTER(_midlSAFEARRAY(c_int)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentAnnotationObjects', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedPositionInSet', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedSizeOfSet', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedLevel', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedAnnotationTypes', + ( ['out', 'retval'], POINTER(_midlSAFEARRAY(c_int)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedAnnotationObjects', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), ] ################################################################ -## code template for IUIAutomationProxyFactoryEntry implementation -##class IUIAutomationProxyFactoryEntry_Impl(object): -## def _get(self): +## code template for IUIAutomationElement4 implementation +##class IUIAutomationElement4_Impl(object): +## @property +## def CurrentPositionInSet(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CurrentSizeOfSet(self): ## '-no docstring-' -## #return CanCheckBaseClass -## def _set(self, CanCheckBaseClass): +## #return retVal +## +## @property +## def CurrentLevel(self): ## '-no docstring-' -## CanCheckBaseClass = property(_get, _set, doc = _set.__doc__) +## #return retVal ## -## def _get(self): +## @property +## def CurrentAnnotationTypes(self): ## '-no docstring-' -## #return ClassName -## def _set(self, ClassName): +## #return retVal +## +## @property +## def CurrentAnnotationObjects(self): ## '-no docstring-' -## ClassName = property(_get, _set, doc = _set.__doc__) +## #return retVal ## -## def _get(self): +## @property +## def CachedPositionInSet(self): ## '-no docstring-' -## #return ImageName -## def _set(self, ImageName): +## #return retVal +## +## @property +## def CachedSizeOfSet(self): ## '-no docstring-' -## ImageName = property(_get, _set, doc = _set.__doc__) +## #return retVal ## ## @property -## def ProxyFactory(self): +## def CachedLevel(self): ## '-no docstring-' -## #return factory +## #return retVal ## -## def SetWinEventsForAutomationEvent(self, eventId, propertyId, winEvents): +## @property +## def CachedAnnotationTypes(self): ## '-no docstring-' -## #return +## #return retVal ## -## def _get(self): +## @property +## def CachedAnnotationObjects(self): ## '-no docstring-' -## #return adviseEvents -## def _set(self, adviseEvents): +## #return retVal +## + +IUIAutomationElement5._methods_ = [ + COMMETHOD(['propget'], HRESULT, 'CurrentLandmarkType', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentLocalizedLandmarkType', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedLandmarkType', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedLocalizedLandmarkType', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), +] +################################################################ +## code template for IUIAutomationElement5 implementation +##class IUIAutomationElement5_Impl(object): +## @property +## def CurrentLandmarkType(self): ## '-no docstring-' -## NeedsAdviseEvents = property(_get, _set, doc = _set.__doc__) +## #return retVal ## -## def _get(self): +## @property +## def CurrentLocalizedLandmarkType(self): ## '-no docstring-' -## #return AllowSubstringMatch -## def _set(self, AllowSubstringMatch): +## #return retVal +## +## @property +## def CachedLandmarkType(self): ## '-no docstring-' -## AllowSubstringMatch = property(_get, _set, doc = _set.__doc__) +## #return retVal ## -## def GetWinEventsForAutomationEvent(self, eventId, propertyId): +## @property +## def CachedLocalizedLandmarkType(self): ## '-no docstring-' -## #return winEvents +## #return retVal ## -UIA_ScrollHorizontalScrollPercentPropertyId = 30053 # Constant c_int -AnnotationType_Endnote = 60009 # Constant c_int -UIA_InvokePatternId = 10000 # Constant c_int -UIA_IsStylesPatternAvailablePropertyId = 30127 # Constant c_int -UIA_ScrollVerticalScrollPercentPropertyId = 30055 # Constant c_int -UIA_HeaderControlTypeId = 50034 # Constant c_int -class IUIAutomation(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{30CBE57D-D9D0-452A-AB13-7AC5AC4825EE}') - _idlflags_ = [] -class IUIAutomation2(IUIAutomation): +class IUIAutomationTreeWalker(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): _case_insensitive_ = True - _iid_ = GUID('{34723AFF-0C9D-49D0-9896-7AB52DF8CD8A}') + _iid_ = GUID('{4042C624-389C-4AFC-A630-9DF854A541FC}') _idlflags_ = [] class IUIAutomationEventHandler(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): _case_insensitive_ = True _iid_ = GUID('{146C3C17-F12E-4E22-8C27-F894B9B79C69}') _idlflags_ = ['oleautomation'] -class IAccessible(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IDispatch): +class IUIAutomationPropertyChangedEventHandler(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): _case_insensitive_ = True - _iid_ = GUID('{618736E0-3C3D-11CF-810C-00AA00389B71}') - _idlflags_ = ['dual', 'oleautomation', 'hidden'] + _iid_ = GUID('{40CD37D4-C756-4B0C-8C6F-BDDFEEB13B50}') + _idlflags_ = ['oleautomation'] +class IUIAutomationStructureChangedEventHandler(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{E81D1B4E-11C5-42F8-9754-E7036C79F054}') + _idlflags_ = ['oleautomation'] +class IUIAutomationFocusChangedEventHandler(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{C270F6B5-5C69-4290-9745-7A7F97169468}') + _idlflags_ = ['oleautomation'] +class IUIAutomationProxyFactory(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{85B94ECD-849D-42B6-B94D-D6DB23FDF5A4}') + _idlflags_ = [] +class IUIAutomationProxyFactoryEntry(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{D50E472E-B64B-490C-BCA1-D30696F9F289}') + _idlflags_ = [] +class IUIAutomationProxyFactoryMapping(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{09E31E18-872D-4873-93D1-1E541EC133FD}') + _idlflags_ = [] IUIAutomation._methods_ = [ COMMETHOD([], HRESULT, 'CompareElements', ( ['in'], POINTER(IUIAutomationElement), 'el1' ), ( ['in'], POINTER(IUIAutomationElement), 'el2' ), - ( ['retval', 'out'], POINTER(c_int), 'areSame' )), + ( ['out', 'retval'], POINTER(c_int), 'areSame' )), COMMETHOD([], HRESULT, 'CompareRuntimeIds', ( ['in'], _midlSAFEARRAY(c_int), 'runtimeId1' ), ( ['in'], _midlSAFEARRAY(c_int), 'runtimeId2' ), - ( ['retval', 'out'], POINTER(c_int), 'areSame' )), + ( ['out', 'retval'], POINTER(c_int), 'areSame' )), COMMETHOD([], HRESULT, 'GetRootElement', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'root' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'root' )), COMMETHOD([], HRESULT, 'ElementFromHandle', ( ['in'], c_void_p, 'hwnd' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'element' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'element' )), COMMETHOD([], HRESULT, 'ElementFromPoint', ( ['in'], tagPOINT, 'pt' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'element' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'element' )), COMMETHOD([], HRESULT, 'GetFocusedElement', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'element' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'element' )), COMMETHOD([], HRESULT, 'GetRootElementBuildCache', ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'root' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'root' )), COMMETHOD([], HRESULT, 'ElementFromHandleBuildCache', ( ['in'], c_void_p, 'hwnd' ), ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'element' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'element' )), COMMETHOD([], HRESULT, 'ElementFromPointBuildCache', ( ['in'], tagPOINT, 'pt' ), ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'element' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'element' )), COMMETHOD([], HRESULT, 'GetFocusedElementBuildCache', ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'element' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'element' )), COMMETHOD([], HRESULT, 'CreateTreeWalker', ( ['in'], POINTER(IUIAutomationCondition), 'pCondition' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationTreeWalker)), 'walker' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationTreeWalker)), 'walker' )), COMMETHOD(['propget'], HRESULT, 'ControlViewWalker', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationTreeWalker)), 'walker' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationTreeWalker)), 'walker' )), COMMETHOD(['propget'], HRESULT, 'ContentViewWalker', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationTreeWalker)), 'walker' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationTreeWalker)), 'walker' )), COMMETHOD(['propget'], HRESULT, 'RawViewWalker', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationTreeWalker)), 'walker' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationTreeWalker)), 'walker' )), COMMETHOD(['propget'], HRESULT, 'RawViewCondition', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationCondition)), 'condition' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationCondition)), 'condition' )), COMMETHOD(['propget'], HRESULT, 'ControlViewCondition', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationCondition)), 'condition' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationCondition)), 'condition' )), COMMETHOD(['propget'], HRESULT, 'ContentViewCondition', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationCondition)), 'condition' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationCondition)), 'condition' )), COMMETHOD([], HRESULT, 'CreateCacheRequest', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationCacheRequest)), 'cacheRequest' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationCacheRequest)), 'cacheRequest' )), COMMETHOD([], HRESULT, 'CreateTrueCondition', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationCondition)), 'newCondition' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationCondition)), 'newCondition' )), COMMETHOD([], HRESULT, 'CreateFalseCondition', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationCondition)), 'newCondition' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationCondition)), 'newCondition' )), COMMETHOD([], HRESULT, 'CreatePropertyCondition', ( ['in'], c_int, 'propertyId' ), ( ['in'], VARIANT, 'value' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationCondition)), 'newCondition' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationCondition)), 'newCondition' )), COMMETHOD([], HRESULT, 'CreatePropertyConditionEx', ( ['in'], c_int, 'propertyId' ), ( ['in'], VARIANT, 'value' ), ( ['in'], PropertyConditionFlags, 'flags' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationCondition)), 'newCondition' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationCondition)), 'newCondition' )), COMMETHOD([], HRESULT, 'CreateAndCondition', ( ['in'], POINTER(IUIAutomationCondition), 'condition1' ), ( ['in'], POINTER(IUIAutomationCondition), 'condition2' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationCondition)), 'newCondition' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationCondition)), 'newCondition' )), COMMETHOD([], HRESULT, 'CreateAndConditionFromArray', ( ['in'], _midlSAFEARRAY(POINTER(IUIAutomationCondition)), 'conditions' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationCondition)), 'newCondition' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationCondition)), 'newCondition' )), COMMETHOD([], HRESULT, 'CreateAndConditionFromNativeArray', ( ['in'], POINTER(POINTER(IUIAutomationCondition)), 'conditions' ), ( ['in'], c_int, 'conditionCount' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationCondition)), 'newCondition' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationCondition)), 'newCondition' )), COMMETHOD([], HRESULT, 'CreateOrCondition', ( ['in'], POINTER(IUIAutomationCondition), 'condition1' ), ( ['in'], POINTER(IUIAutomationCondition), 'condition2' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationCondition)), 'newCondition' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationCondition)), 'newCondition' )), COMMETHOD([], HRESULT, 'CreateOrConditionFromArray', ( ['in'], _midlSAFEARRAY(POINTER(IUIAutomationCondition)), 'conditions' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationCondition)), 'newCondition' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationCondition)), 'newCondition' )), COMMETHOD([], HRESULT, 'CreateOrConditionFromNativeArray', ( ['in'], POINTER(POINTER(IUIAutomationCondition)), 'conditions' ), ( ['in'], c_int, 'conditionCount' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationCondition)), 'newCondition' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationCondition)), 'newCondition' )), COMMETHOD([], HRESULT, 'CreateNotCondition', ( ['in'], POINTER(IUIAutomationCondition), 'condition' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationCondition)), 'newCondition' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationCondition)), 'newCondition' )), COMMETHOD([], HRESULT, 'AddAutomationEventHandler', ( ['in'], c_int, 'eventId' ), ( ['in'], POINTER(IUIAutomationElement), 'element' ), @@ -2303,32 +2227,32 @@ class IAccessible(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IDisp COMMETHOD([], HRESULT, 'IntNativeArrayToSafeArray', ( ['in'], POINTER(c_int), 'array' ), ( ['in'], c_int, 'arrayCount' ), - ( ['retval', 'out'], POINTER(_midlSAFEARRAY(c_int)), 'safeArray' )), + ( ['out', 'retval'], POINTER(_midlSAFEARRAY(c_int)), 'safeArray' )), COMMETHOD([], HRESULT, 'IntSafeArrayToNativeArray', ( ['in'], _midlSAFEARRAY(c_int), 'intArray' ), ( ['out'], POINTER(POINTER(c_int)), 'array' ), - ( ['retval', 'out'], POINTER(c_int), 'arrayCount' )), + ( ['out', 'retval'], POINTER(c_int), 'arrayCount' )), COMMETHOD([], HRESULT, 'RectToVariant', ( ['in'], tagRECT, 'rc' ), - ( ['retval', 'out'], POINTER(VARIANT), 'var' )), + ( ['out', 'retval'], POINTER(VARIANT), 'var' )), COMMETHOD([], HRESULT, 'VariantToRect', ( ['in'], VARIANT, 'var' ), - ( ['retval', 'out'], POINTER(tagRECT), 'rc' )), + ( ['out', 'retval'], POINTER(tagRECT), 'rc' )), COMMETHOD([], HRESULT, 'SafeArrayToRectNativeArray', ( ['in'], _midlSAFEARRAY(c_double), 'rects' ), ( ['out'], POINTER(POINTER(tagRECT)), 'rectArray' ), - ( ['retval', 'out'], POINTER(c_int), 'rectArrayCount' )), + ( ['out', 'retval'], POINTER(c_int), 'rectArrayCount' )), COMMETHOD([], HRESULT, 'CreateProxyFactoryEntry', ( ['in'], POINTER(IUIAutomationProxyFactory), 'factory' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationProxyFactoryEntry)), 'factoryEntry' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationProxyFactoryEntry)), 'factoryEntry' )), COMMETHOD(['propget'], HRESULT, 'ProxyFactoryMapping', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationProxyFactoryMapping)), 'factoryMapping' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationProxyFactoryMapping)), 'factoryMapping' )), COMMETHOD([], HRESULT, 'GetPropertyProgrammaticName', ( ['in'], c_int, 'property' ), - ( ['retval', 'out'], POINTER(BSTR), 'name' )), + ( ['out', 'retval'], POINTER(BSTR), 'name' )), COMMETHOD([], HRESULT, 'GetPatternProgrammaticName', ( ['in'], c_int, 'pattern' ), - ( ['retval', 'out'], POINTER(BSTR), 'name' )), + ( ['out', 'retval'], POINTER(BSTR), 'name' )), COMMETHOD([], HRESULT, 'PollForPotentialSupportedPatterns', ( ['in'], POINTER(IUIAutomationElement), 'pElement' ), ( ['out'], POINTER(_midlSAFEARRAY(c_int)), 'patternIds' ), @@ -2339,265 +2263,265 @@ class IAccessible(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IDisp ( ['out'], POINTER(_midlSAFEARRAY(BSTR)), 'propertyNames' )), COMMETHOD([], HRESULT, 'CheckNotSupported', ( ['in'], VARIANT, 'value' ), - ( ['retval', 'out'], POINTER(c_int), 'isNotSupported' )), + ( ['out', 'retval'], POINTER(c_int), 'isNotSupported' )), COMMETHOD(['propget'], HRESULT, 'ReservedNotSupportedValue', - ( ['retval', 'out'], POINTER(POINTER(IUnknown)), 'notSupportedValue' )), + ( ['out', 'retval'], POINTER(POINTER(IUnknown)), 'notSupportedValue' )), COMMETHOD(['propget'], HRESULT, 'ReservedMixedAttributeValue', - ( ['retval', 'out'], POINTER(POINTER(IUnknown)), 'mixedAttributeValue' )), + ( ['out', 'retval'], POINTER(POINTER(IUnknown)), 'mixedAttributeValue' )), COMMETHOD([], HRESULT, 'ElementFromIAccessible', ( ['in'], POINTER(IAccessible), 'accessible' ), ( ['in'], c_int, 'childId' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'element' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'element' )), COMMETHOD([], HRESULT, 'ElementFromIAccessibleBuildCache', ( ['in'], POINTER(IAccessible), 'accessible' ), ( ['in'], c_int, 'childId' ), ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'element' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'element' )), ] ################################################################ ## code template for IUIAutomation implementation ##class IUIAutomation_Impl(object): -## def IntSafeArrayToNativeArray(self, intArray): +## def CompareElements(self, el1, el2): ## '-no docstring-' -## #return array, arrayCount +## #return areSame ## -## def AddPropertyChangedEventHandlerNativeArray(self, element, scope, cacheRequest, handler, propertyArray, propertyCount): +## def CompareRuntimeIds(self, runtimeId1, runtimeId2): ## '-no docstring-' -## #return +## #return areSame ## -## def IntNativeArrayToSafeArray(self, array, arrayCount): +## def GetRootElement(self): ## '-no docstring-' -## #return safeArray +## #return root ## -## def ElementFromHandleBuildCache(self, hwnd, cacheRequest): +## def ElementFromHandle(self, hwnd): ## '-no docstring-' ## #return element ## -## def ElementFromHandle(self, hwnd): +## def ElementFromPoint(self, pt): ## '-no docstring-' ## #return element ## -## def CreateOrCondition(self, condition1, condition2): +## def GetFocusedElement(self): ## '-no docstring-' -## #return newCondition +## #return element ## -## def PollForPotentialSupportedProperties(self, pElement): +## def GetRootElementBuildCache(self, cacheRequest): ## '-no docstring-' -## #return propertyIds, propertyNames +## #return root ## -## @property -## def ContentViewWalker(self): +## def ElementFromHandleBuildCache(self, hwnd, cacheRequest): ## '-no docstring-' -## #return walker +## #return element ## -## def CreateTrueCondition(self): +## def ElementFromPointBuildCache(self, pt, cacheRequest): ## '-no docstring-' -## #return newCondition +## #return element ## -## def AddAutomationEventHandler(self, eventId, element, scope, cacheRequest, handler): +## def GetFocusedElementBuildCache(self, cacheRequest): ## '-no docstring-' -## #return +## #return element +## +## def CreateTreeWalker(self, pCondition): +## '-no docstring-' +## #return walker ## ## @property -## def ReservedNotSupportedValue(self): +## def ControlViewWalker(self): ## '-no docstring-' -## #return notSupportedValue +## #return walker ## -## def CreatePropertyCondition(self, propertyId, value): +## @property +## def ContentViewWalker(self): ## '-no docstring-' -## #return newCondition +## #return walker ## -## def AddFocusChangedEventHandler(self, cacheRequest, handler): +## @property +## def RawViewWalker(self): ## '-no docstring-' -## #return +## #return walker ## ## @property ## def RawViewCondition(self): ## '-no docstring-' ## #return condition ## -## def CreateAndConditionFromNativeArray(self, conditions, conditionCount): +## @property +## def ControlViewCondition(self): ## '-no docstring-' -## #return newCondition +## #return condition ## -## def CreateOrConditionFromNativeArray(self, conditions, conditionCount): +## @property +## def ContentViewCondition(self): ## '-no docstring-' -## #return newCondition +## #return condition ## -## def ElementFromIAccessibleBuildCache(self, accessible, childId, cacheRequest): +## def CreateCacheRequest(self): ## '-no docstring-' -## #return element +## #return cacheRequest ## -## def CreateNotCondition(self, condition): +## def CreateTrueCondition(self): ## '-no docstring-' ## #return newCondition ## -## def CreateOrConditionFromArray(self, conditions): +## def CreateFalseCondition(self): ## '-no docstring-' ## #return newCondition ## -## def CreateAndConditionFromArray(self, conditions): +## def CreatePropertyCondition(self, propertyId, value): ## '-no docstring-' ## #return newCondition ## -## def CheckNotSupported(self, value): +## def CreatePropertyConditionEx(self, propertyId, value, flags): ## '-no docstring-' -## #return isNotSupported +## #return newCondition ## -## def RemoveStructureChangedEventHandler(self, element, handler): +## def CreateAndCondition(self, condition1, condition2): ## '-no docstring-' -## #return +## #return newCondition ## -## def CreatePropertyConditionEx(self, propertyId, value, flags): +## def CreateAndConditionFromArray(self, conditions): ## '-no docstring-' ## #return newCondition ## -## def RemovePropertyChangedEventHandler(self, element, handler): +## def CreateAndConditionFromNativeArray(self, conditions, conditionCount): ## '-no docstring-' -## #return +## #return newCondition ## -## def CreateTreeWalker(self, pCondition): +## def CreateOrCondition(self, condition1, condition2): ## '-no docstring-' -## #return walker +## #return newCondition ## -## def CreateCacheRequest(self): +## def CreateOrConditionFromArray(self, conditions): ## '-no docstring-' -## #return cacheRequest +## #return newCondition ## -## def ElementFromPointBuildCache(self, pt, cacheRequest): +## def CreateOrConditionFromNativeArray(self, conditions, conditionCount): ## '-no docstring-' -## #return element +## #return newCondition ## -## def GetPatternProgrammaticName(self, pattern): +## def CreateNotCondition(self, condition): ## '-no docstring-' -## #return name +## #return newCondition ## -## def RemoveAllEventHandlers(self): +## def AddAutomationEventHandler(self, eventId, element, scope, cacheRequest, handler): ## '-no docstring-' ## #return ## -## def ElementFromIAccessible(self, accessible, childId): -## '-no docstring-' -## #return element -## -## def AddStructureChangedEventHandler(self, element, scope, cacheRequest, handler): +## def RemoveAutomationEventHandler(self, eventId, element, handler): ## '-no docstring-' ## #return ## -## @property -## def ProxyFactoryMapping(self): +## def AddPropertyChangedEventHandlerNativeArray(self, element, scope, cacheRequest, handler, propertyArray, propertyCount): ## '-no docstring-' -## #return factoryMapping +## #return ## -## def CreateProxyFactoryEntry(self, factory): +## def AddPropertyChangedEventHandler(self, element, scope, cacheRequest, handler, propertyArray): ## '-no docstring-' -## #return factoryEntry +## #return ## -## def CompareRuntimeIds(self, runtimeId1, runtimeId2): +## def RemovePropertyChangedEventHandler(self, element, handler): ## '-no docstring-' -## #return areSame +## #return ## -## @property -## def ControlViewWalker(self): +## def AddStructureChangedEventHandler(self, element, scope, cacheRequest, handler): ## '-no docstring-' -## #return walker +## #return ## -## def CreateAndCondition(self, condition1, condition2): +## def RemoveStructureChangedEventHandler(self, element, handler): ## '-no docstring-' -## #return newCondition +## #return ## -## def GetRootElementBuildCache(self, cacheRequest): +## def AddFocusChangedEventHandler(self, cacheRequest, handler): ## '-no docstring-' -## #return root +## #return ## ## def RemoveFocusChangedEventHandler(self, handler): ## '-no docstring-' ## #return ## -## def ElementFromPoint(self, pt): +## def RemoveAllEventHandlers(self): ## '-no docstring-' -## #return element +## #return ## -## def GetPropertyProgrammaticName(self, property): +## def IntNativeArrayToSafeArray(self, array, arrayCount): ## '-no docstring-' -## #return name +## #return safeArray ## -## def VariantToRect(self, var): +## def IntSafeArrayToNativeArray(self, intArray): ## '-no docstring-' -## #return rc +## #return array, arrayCount ## -## def GetRootElement(self): +## def RectToVariant(self, rc): ## '-no docstring-' -## #return root +## #return var ## -## def SafeArrayToRectNativeArray(self, rects): +## def VariantToRect(self, var): ## '-no docstring-' -## #return rectArray, rectArrayCount +## #return rc ## -## def GetFocusedElementBuildCache(self, cacheRequest): +## def SafeArrayToRectNativeArray(self, rects): ## '-no docstring-' -## #return element +## #return rectArray, rectArrayCount ## -## @property -## def ReservedMixedAttributeValue(self): +## def CreateProxyFactoryEntry(self, factory): ## '-no docstring-' -## #return mixedAttributeValue +## #return factoryEntry ## ## @property -## def RawViewWalker(self): +## def ProxyFactoryMapping(self): ## '-no docstring-' -## #return walker +## #return factoryMapping ## -## @property -## def ControlViewCondition(self): +## def GetPropertyProgrammaticName(self, property): ## '-no docstring-' -## #return condition +## #return name ## -## def GetFocusedElement(self): +## def GetPatternProgrammaticName(self, pattern): ## '-no docstring-' -## #return element +## #return name ## -## def CompareElements(self, el1, el2): +## def PollForPotentialSupportedPatterns(self, pElement): ## '-no docstring-' -## #return areSame +## #return patternIds, patternNames ## -## def RectToVariant(self, rc): +## def PollForPotentialSupportedProperties(self, pElement): ## '-no docstring-' -## #return var +## #return propertyIds, propertyNames ## -## def CreateFalseCondition(self): +## def CheckNotSupported(self, value): ## '-no docstring-' -## #return newCondition +## #return isNotSupported ## -## def AddPropertyChangedEventHandler(self, element, scope, cacheRequest, handler, propertyArray): +## @property +## def ReservedNotSupportedValue(self): ## '-no docstring-' -## #return +## #return notSupportedValue ## ## @property -## def ContentViewCondition(self): +## def ReservedMixedAttributeValue(self): ## '-no docstring-' -## #return condition +## #return mixedAttributeValue ## -## def PollForPotentialSupportedPatterns(self, pElement): +## def ElementFromIAccessible(self, accessible, childId): ## '-no docstring-' -## #return patternIds, patternNames +## #return element ## -## def RemoveAutomationEventHandler(self, eventId, element, handler): +## def ElementFromIAccessibleBuildCache(self, accessible, childId, cacheRequest): ## '-no docstring-' -## #return +## #return element ## IUIAutomation2._methods_ = [ COMMETHOD(['propget'], HRESULT, 'AutoSetFocus', - ( ['retval', 'out'], POINTER(c_int), 'AutoSetFocus' )), + ( ['out', 'retval'], POINTER(c_int), 'AutoSetFocus' )), COMMETHOD(['propput'], HRESULT, 'AutoSetFocus', ( ['in'], c_int, 'AutoSetFocus' )), COMMETHOD(['propget'], HRESULT, 'ConnectionTimeout', - ( ['retval', 'out'], POINTER(c_ulong), 'timeout' )), + ( ['out', 'retval'], POINTER(c_ulong), 'timeout' )), COMMETHOD(['propput'], HRESULT, 'ConnectionTimeout', ( ['in'], c_ulong, 'timeout' )), COMMETHOD(['propget'], HRESULT, 'TransactionTimeout', - ( ['retval', 'out'], POINTER(c_ulong), 'timeout' )), + ( ['out', 'retval'], POINTER(c_ulong), 'timeout' )), COMMETHOD(['propput'], HRESULT, 'TransactionTimeout', ( ['in'], c_ulong, 'timeout' )), ] @@ -2606,6 +2530,13 @@ class IAccessible(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IDisp ##class IUIAutomation2_Impl(object): ## def _get(self): ## '-no docstring-' +## #return AutoSetFocus +## def _set(self, AutoSetFocus): +## '-no docstring-' +## AutoSetFocus = property(_get, _set, doc = _set.__doc__) +## +## def _get(self): +## '-no docstring-' ## #return timeout ## def _set(self, timeout): ## '-no docstring-' @@ -2618,18 +2549,109 @@ class IAccessible(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IDisp ## '-no docstring-' ## TransactionTimeout = property(_get, _set, doc = _set.__doc__) ## -## def _get(self): + +class IUIAutomationElement6(IUIAutomationElement5): + _case_insensitive_ = True + _iid_ = GUID('{4780D450-8BCA-4977-AFA5-A4A517F555E3}') + _idlflags_ = [] +IUIAutomationElement6._methods_ = [ + COMMETHOD(['propget'], HRESULT, 'CurrentFullDescription', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedFullDescription', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), +] +################################################################ +## code template for IUIAutomationElement6 implementation +##class IUIAutomationElement6_Impl(object): +## @property +## def CurrentFullDescription(self): ## '-no docstring-' -## #return AutoSetFocus -## def _set(self, AutoSetFocus): +## #return retVal +## +## @property +## def CachedFullDescription(self): ## '-no docstring-' -## AutoSetFocus = property(_get, _set, doc = _set.__doc__) +## #return retVal ## -class IUIAutomation3(IUIAutomation2): +class IUIAutomationElement7(IUIAutomationElement6): _case_insensitive_ = True - _iid_ = GUID('{73D768DA-9B51-4B89-936E-C209290973E7}') + _iid_ = GUID('{204E8572-CFC3-4C11-B0C8-7DA7420750B7}') _idlflags_ = [] + +# values for enumeration 'TreeTraversalOptions' +TreeTraversalOptions_Default = 0 +TreeTraversalOptions_PostOrder = 1 +TreeTraversalOptions_LastToFirstOrder = 2 +TreeTraversalOptions = c_int # enum +IUIAutomationElement7._methods_ = [ + COMMETHOD([], HRESULT, 'FindFirstWithOptions', + ( ['in'], TreeScope, 'scope' ), + ( ['in'], POINTER(IUIAutomationCondition), 'condition' ), + ( ['in'], TreeTraversalOptions, 'traversalOptions' ), + ( ['in'], POINTER(IUIAutomationElement), 'root' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'found' )), + COMMETHOD([], HRESULT, 'FindAllWithOptions', + ( ['in'], TreeScope, 'scope' ), + ( ['in'], POINTER(IUIAutomationCondition), 'condition' ), + ( ['in'], TreeTraversalOptions, 'traversalOptions' ), + ( ['in'], POINTER(IUIAutomationElement), 'root' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'found' )), + COMMETHOD([], HRESULT, 'FindFirstWithOptionsBuildCache', + ( ['in'], TreeScope, 'scope' ), + ( ['in'], POINTER(IUIAutomationCondition), 'condition' ), + ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), + ( ['in'], TreeTraversalOptions, 'traversalOptions' ), + ( ['in'], POINTER(IUIAutomationElement), 'root' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'found' )), + COMMETHOD([], HRESULT, 'FindAllWithOptionsBuildCache', + ( ['in'], TreeScope, 'scope' ), + ( ['in'], POINTER(IUIAutomationCondition), 'condition' ), + ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), + ( ['in'], TreeTraversalOptions, 'traversalOptions' ), + ( ['in'], POINTER(IUIAutomationElement), 'root' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'found' )), + COMMETHOD([], HRESULT, 'GetCurrentMetadataValue', + ( ['in'], c_int, 'targetId' ), + ( ['in'], c_int, 'metadataId' ), + ( ['out', 'retval'], POINTER(VARIANT), 'returnVal' )), +] +################################################################ +## code template for IUIAutomationElement7 implementation +##class IUIAutomationElement7_Impl(object): +## def FindFirstWithOptions(self, scope, condition, traversalOptions, root): +## '-no docstring-' +## #return found +## +## def FindAllWithOptions(self, scope, condition, traversalOptions, root): +## '-no docstring-' +## #return found +## +## def FindFirstWithOptionsBuildCache(self, scope, condition, cacheRequest, traversalOptions, root): +## '-no docstring-' +## #return found +## +## def FindAllWithOptionsBuildCache(self, scope, condition, cacheRequest, traversalOptions, root): +## '-no docstring-' +## #return found +## +## def GetCurrentMetadataValue(self, targetId, metadataId): +## '-no docstring-' +## #return returnVal +## + + +# values for enumeration 'TextEditChangeType' +TextEditChangeType_None = 0 +TextEditChangeType_AutoCorrect = 1 +TextEditChangeType_Composition = 2 +TextEditChangeType_CompositionFinalized = 3 +TextEditChangeType_AutoComplete = 4 +TextEditChangeType = c_int # enum +class IUIAutomationTextEditTextChangedEventHandler(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{92FAA680-E704-4156-931A-E32D5BB38F3F}') + _idlflags_ = ['oleautomation'] IUIAutomation3._methods_ = [ COMMETHOD([], HRESULT, 'AddTextEditTextChangedEventHandler', ( ['in'], POINTER(IUIAutomationElement), 'element' ), @@ -2653,16 +2675,10 @@ class IUIAutomation3(IUIAutomation2): ## #return ## -UIA_ScrollHorizontallyScrollablePropertyId = 30057 # Constant c_int -UIA_ScrollVerticallyScrollablePropertyId = 30058 # Constant c_int -class IUIAutomation4(IUIAutomation3): - _case_insensitive_ = True - _iid_ = GUID('{1189C02A-05F8-4319-8E21-E817E3DB2860}') - _idlflags_ = [] -class IUIAutomation5(IUIAutomation4): +class IUIAutomationChangesEventHandler(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): _case_insensitive_ = True - _iid_ = GUID('{25F700C8-D816-4057-A9DC-3CBDEE77E256}') - _idlflags_ = [] + _iid_ = GUID('{58EDCA55-2C3E-4980-B1B9-56C17F27A2A0}') + _idlflags_ = ['oleautomation'] IUIAutomation4._methods_ = [ COMMETHOD([], HRESULT, 'AddChangesEventHandler', ( ['in'], POINTER(IUIAutomationElement), 'element' ), @@ -2671,596 +2687,535 @@ class IUIAutomation5(IUIAutomation4): ( ['in'], c_int, 'changesCount' ), ( ['in'], POINTER(IUIAutomationCacheRequest), 'pCacheRequest' ), ( ['in'], POINTER(IUIAutomationChangesEventHandler), 'handler' )), - COMMETHOD([], HRESULT, 'RemoveChangesEventHandler', - ( ['in'], POINTER(IUIAutomationElement), 'element' ), - ( ['in'], POINTER(IUIAutomationChangesEventHandler), 'handler' )), -] -################################################################ -## code template for IUIAutomation4 implementation -##class IUIAutomation4_Impl(object): -## def RemoveChangesEventHandler(self, element, handler): -## '-no docstring-' -## #return -## -## def AddChangesEventHandler(self, element, scope, changeTypes, changesCount, pCacheRequest, handler): -## '-no docstring-' -## #return -## - -IUIAutomation5._methods_ = [ - COMMETHOD([], HRESULT, 'AddNotificationEventHandler', - ( ['in'], POINTER(IUIAutomationElement), 'element' ), - ( ['in'], TreeScope, 'scope' ), - ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['in'], POINTER(IUIAutomationNotificationEventHandler), 'handler' )), - COMMETHOD([], HRESULT, 'RemoveNotificationEventHandler', - ( ['in'], POINTER(IUIAutomationElement), 'element' ), - ( ['in'], POINTER(IUIAutomationNotificationEventHandler), 'handler' )), -] -################################################################ -## code template for IUIAutomation5 implementation -##class IUIAutomation5_Impl(object): -## def AddNotificationEventHandler(self, element, scope, cacheRequest, handler): -## '-no docstring-' -## #return -## -## def RemoveNotificationEventHandler(self, element, handler): -## '-no docstring-' -## #return -## - -UIA_SelectionSelectionPropertyId = 30059 # Constant c_int -UIA_IsSpreadsheetPatternAvailablePropertyId = 30128 # Constant c_int -class IUIAutomationTransformPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{A9B55844-A55D-4EF0-926D-569C16FF89BB}') - _idlflags_ = [] -IUIAutomationTransformPattern._methods_ = [ - COMMETHOD([], HRESULT, 'Move', - ( ['in'], c_double, 'x' ), - ( ['in'], c_double, 'y' )), - COMMETHOD([], HRESULT, 'Resize', - ( ['in'], c_double, 'width' ), - ( ['in'], c_double, 'height' )), - COMMETHOD([], HRESULT, 'Rotate', - ( ['in'], c_double, 'degrees' )), - COMMETHOD(['propget'], HRESULT, 'CurrentCanMove', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentCanResize', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentCanRotate', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedCanMove', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedCanResize', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedCanRotate', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), -] -################################################################ -## code template for IUIAutomationTransformPattern implementation -##class IUIAutomationTransformPattern_Impl(object): -## @property -## def CachedCanMove(self): -## '-no docstring-' -## #return retVal -## -## def Rotate(self, degrees): + COMMETHOD([], HRESULT, 'RemoveChangesEventHandler', + ( ['in'], POINTER(IUIAutomationElement), 'element' ), + ( ['in'], POINTER(IUIAutomationChangesEventHandler), 'handler' )), +] +################################################################ +## code template for IUIAutomation4 implementation +##class IUIAutomation4_Impl(object): +## def AddChangesEventHandler(self, element, scope, changeTypes, changesCount, pCacheRequest, handler): ## '-no docstring-' ## #return ## -## @property -## def CachedCanRotate(self): -## '-no docstring-' -## #return retVal -## -## def Move(self, x, y): +## def RemoveChangesEventHandler(self, element, handler): ## '-no docstring-' ## #return ## + +class IUIAutomationElement8(IUIAutomationElement7): + _case_insensitive_ = True + _iid_ = GUID('{8C60217D-5411-4CDE-BCC0-1CEDA223830C}') + _idlflags_ = [] +IUIAutomationElement8._methods_ = [ + COMMETHOD(['propget'], HRESULT, 'CurrentHeadingLevel', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedHeadingLevel', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), +] +################################################################ +## code template for IUIAutomationElement8 implementation +##class IUIAutomationElement8_Impl(object): ## @property -## def CurrentCanRotate(self): -## '-no docstring-' -## #return retVal -## -## @property -## def CurrentCanMove(self): -## '-no docstring-' -## #return retVal -## -## @property -## def CachedCanResize(self): +## def CurrentHeadingLevel(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentCanResize(self): +## def CachedHeadingLevel(self): ## '-no docstring-' ## #return retVal ## -## def Resize(self, width, height): -## '-no docstring-' -## #return -## - -UIA_SelectionCanSelectMultiplePropertyId = 30060 # Constant c_int -UIA_HeaderItemControlTypeId = 50035 # Constant c_int -class IUIAutomation6(IUIAutomation5): - _case_insensitive_ = True - _iid_ = GUID('{AAE072DA-29E3-413D-87A7-192DBF81ED10}') - _idlflags_ = [] -class IUIAutomationEventHandlerGroup(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{C9EE12F2-C13B-4408-997C-639914377F4E}') - _idlflags_ = [] -# values for enumeration 'ConnectionRecoveryBehaviorOptions' -ConnectionRecoveryBehaviorOptions_Disabled = 0 -ConnectionRecoveryBehaviorOptions_Enabled = 1 -ConnectionRecoveryBehaviorOptions = c_int # enum - -# values for enumeration 'CoalesceEventsOptions' -CoalesceEventsOptions_Disabled = 0 -CoalesceEventsOptions_Enabled = 1 -CoalesceEventsOptions = c_int # enum -class IUIAutomationActiveTextPositionChangedEventHandler(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): +class IUIAutomationNotificationEventHandler(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): _case_insensitive_ = True - _iid_ = GUID('{F97933B0-8DAE-4496-8997-5BA015FE0D82}') + _iid_ = GUID('{C7CB2637-E6C2-4D0C-85DE-4948C02175C7}') _idlflags_ = ['oleautomation'] -IUIAutomation6._methods_ = [ - COMMETHOD([], HRESULT, 'CreateEventHandlerGroup', - ( ['out'], POINTER(POINTER(IUIAutomationEventHandlerGroup)), 'handlerGroup' )), - COMMETHOD([], HRESULT, 'AddEventHandlerGroup', - ( ['in'], POINTER(IUIAutomationElement), 'element' ), - ( ['in'], POINTER(IUIAutomationEventHandlerGroup), 'handlerGroup' )), - COMMETHOD([], HRESULT, 'RemoveEventHandlerGroup', - ( ['in'], POINTER(IUIAutomationElement), 'element' ), - ( ['in'], POINTER(IUIAutomationEventHandlerGroup), 'handlerGroup' )), - COMMETHOD(['propget'], HRESULT, 'ConnectionRecoveryBehavior', - ( ['retval', 'out'], POINTER(ConnectionRecoveryBehaviorOptions), 'ConnectionRecoveryBehaviorOptions' )), - COMMETHOD(['propput'], HRESULT, 'ConnectionRecoveryBehavior', - ( ['in'], ConnectionRecoveryBehaviorOptions, 'ConnectionRecoveryBehaviorOptions' )), - COMMETHOD(['propget'], HRESULT, 'CoalesceEvents', - ( ['retval', 'out'], POINTER(CoalesceEventsOptions), 'CoalesceEventsOptions' )), - COMMETHOD(['propput'], HRESULT, 'CoalesceEvents', - ( ['in'], CoalesceEventsOptions, 'CoalesceEventsOptions' )), - COMMETHOD([], HRESULT, 'AddActiveTextPositionChangedEventHandler', +IUIAutomation5._methods_ = [ + COMMETHOD([], HRESULT, 'AddNotificationEventHandler', ( ['in'], POINTER(IUIAutomationElement), 'element' ), ( ['in'], TreeScope, 'scope' ), ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['in'], POINTER(IUIAutomationActiveTextPositionChangedEventHandler), 'handler' )), - COMMETHOD([], HRESULT, 'RemoveActiveTextPositionChangedEventHandler', + ( ['in'], POINTER(IUIAutomationNotificationEventHandler), 'handler' )), + COMMETHOD([], HRESULT, 'RemoveNotificationEventHandler', ( ['in'], POINTER(IUIAutomationElement), 'element' ), - ( ['in'], POINTER(IUIAutomationActiveTextPositionChangedEventHandler), 'handler' )), + ( ['in'], POINTER(IUIAutomationNotificationEventHandler), 'handler' )), ] ################################################################ -## code template for IUIAutomation6 implementation -##class IUIAutomation6_Impl(object): -## def _get(self): -## '-no docstring-' -## #return ConnectionRecoveryBehaviorOptions -## def _set(self, ConnectionRecoveryBehaviorOptions): -## '-no docstring-' -## ConnectionRecoveryBehavior = property(_get, _set, doc = _set.__doc__) -## -## def AddActiveTextPositionChangedEventHandler(self, element, scope, cacheRequest, handler): +## code template for IUIAutomation5 implementation +##class IUIAutomation5_Impl(object): +## def AddNotificationEventHandler(self, element, scope, cacheRequest, handler): ## '-no docstring-' ## #return ## -## def RemoveEventHandlerGroup(self, element, handlerGroup): +## def RemoveNotificationEventHandler(self, element, handler): ## '-no docstring-' ## #return ## -## def _get(self): -## '-no docstring-' -## #return CoalesceEventsOptions -## def _set(self, CoalesceEventsOptions): + +class IUIAutomationObjectModelPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{71C284B3-C14D-4D14-981E-19751B0D756D}') + _idlflags_ = [] +IUIAutomationObjectModelPattern._methods_ = [ + COMMETHOD([], HRESULT, 'GetUnderlyingObjectModel', + ( ['out', 'retval'], POINTER(POINTER(IUnknown)), 'retVal' )), +] +################################################################ +## code template for IUIAutomationObjectModelPattern implementation +##class IUIAutomationObjectModelPattern_Impl(object): +## def GetUnderlyingObjectModel(self): ## '-no docstring-' -## CoalesceEvents = property(_get, _set, doc = _set.__doc__) +## #return retVal ## -## def CreateEventHandlerGroup(self): + +class IUIAutomationElement9(IUIAutomationElement8): + _case_insensitive_ = True + _iid_ = GUID('{39325FAC-039D-440E-A3A3-5EB81A5CECC3}') + _idlflags_ = [] +IUIAutomationElement9._methods_ = [ + COMMETHOD(['propget'], HRESULT, 'CurrentIsDialog', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedIsDialog', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), +] +################################################################ +## code template for IUIAutomationElement9 implementation +##class IUIAutomationElement9_Impl(object): +## @property +## def CurrentIsDialog(self): ## '-no docstring-' -## #return handlerGroup +## #return retVal ## -## def RemoveActiveTextPositionChangedEventHandler(self, element, handler): +## @property +## def CachedIsDialog(self): ## '-no docstring-' -## #return +## #return retVal ## -## def AddEventHandlerGroup(self, element, handlerGroup): + +class UiaChangeInfo(Structure): + pass +IUIAutomationChangesEventHandler._methods_ = [ + COMMETHOD([], HRESULT, 'HandleChangesEvent', + ( ['in'], POINTER(IUIAutomationElement), 'sender' ), + ( ['in'], POINTER(UiaChangeInfo), 'uiaChanges' ), + ( ['in'], c_int, 'changesCount' )), +] +################################################################ +## code template for IUIAutomationChangesEventHandler implementation +##class IUIAutomationChangesEventHandler_Impl(object): +## def HandleChangesEvent(self, sender, uiaChanges, changesCount): ## '-no docstring-' ## #return ## -UIA_GridRowCountPropertyId = 30062 # Constant c_int -# values for enumeration 'ProviderOptions' -ProviderOptions_ClientSideProvider = 1 -ProviderOptions_ServerSideProvider = 2 -ProviderOptions_NonClientAreaProvider = 4 -ProviderOptions_OverrideProvider = 8 -ProviderOptions_ProviderOwnsSetFocus = 16 -ProviderOptions_UseComThreading = 32 -ProviderOptions_RefuseNonClientSupport = 64 -ProviderOptions_HasNativeIAccessible = 128 -ProviderOptions_UseClientCoordinates = 256 -ProviderOptions = c_int # enum -UIA_GridColumnCountPropertyId = 30063 # Constant c_int -UIA_GridItemRowPropertyId = 30064 # Constant c_int -class IUIAutomationValuePattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{A94CD8B1-0844-4CD6-9D2D-640537AB39E9}') - _idlflags_ = [] -IUIAutomationValuePattern._methods_ = [ - COMMETHOD([], HRESULT, 'SetValue', - ( ['in'], BSTR, 'val' )), - COMMETHOD(['propget'], HRESULT, 'CurrentValue', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentIsReadOnly', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedValue', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedIsReadOnly', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), +# values for enumeration 'TextPatternRangeEndpoint' +TextPatternRangeEndpoint_Start = 0 +TextPatternRangeEndpoint_End = 1 +TextPatternRangeEndpoint = c_int # enum + +# values for enumeration 'TextUnit' +TextUnit_Character = 0 +TextUnit_Format = 1 +TextUnit_Word = 2 +TextUnit_Line = 3 +TextUnit_Paragraph = 4 +TextUnit_Page = 5 +TextUnit_Document = 6 +TextUnit = c_int # enum +IUIAutomationTextRange._methods_ = [ + COMMETHOD([], HRESULT, 'Clone', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationTextRange)), 'clonedRange' )), + COMMETHOD([], HRESULT, 'Compare', + ( ['in'], POINTER(IUIAutomationTextRange), 'range' ), + ( ['out', 'retval'], POINTER(c_int), 'areSame' )), + COMMETHOD([], HRESULT, 'CompareEndpoints', + ( ['in'], TextPatternRangeEndpoint, 'srcEndPoint' ), + ( ['in'], POINTER(IUIAutomationTextRange), 'range' ), + ( ['in'], TextPatternRangeEndpoint, 'targetEndPoint' ), + ( ['out', 'retval'], POINTER(c_int), 'compValue' )), + COMMETHOD([], HRESULT, 'ExpandToEnclosingUnit', + ( ['in'], TextUnit, 'TextUnit' )), + COMMETHOD([], HRESULT, 'FindAttribute', + ( ['in'], c_int, 'attr' ), + ( ['in'], VARIANT, 'val' ), + ( ['in'], c_int, 'backward' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationTextRange)), 'found' )), + COMMETHOD([], HRESULT, 'FindText', + ( ['in'], BSTR, 'text' ), + ( ['in'], c_int, 'backward' ), + ( ['in'], c_int, 'ignoreCase' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationTextRange)), 'found' )), + COMMETHOD([], HRESULT, 'GetAttributeValue', + ( ['in'], c_int, 'attr' ), + ( ['out', 'retval'], POINTER(VARIANT), 'value' )), + COMMETHOD([], HRESULT, 'GetBoundingRectangles', + ( ['out', 'retval'], POINTER(_midlSAFEARRAY(c_double)), 'boundingRects' )), + COMMETHOD([], HRESULT, 'GetEnclosingElement', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'enclosingElement' )), + COMMETHOD([], HRESULT, 'GetText', + ( ['in'], c_int, 'maxLength' ), + ( ['out', 'retval'], POINTER(BSTR), 'text' )), + COMMETHOD([], HRESULT, 'Move', + ( ['in'], TextUnit, 'unit' ), + ( ['in'], c_int, 'count' ), + ( ['out', 'retval'], POINTER(c_int), 'moved' )), + COMMETHOD([], HRESULT, 'MoveEndpointByUnit', + ( ['in'], TextPatternRangeEndpoint, 'endpoint' ), + ( ['in'], TextUnit, 'unit' ), + ( ['in'], c_int, 'count' ), + ( ['out', 'retval'], POINTER(c_int), 'moved' )), + COMMETHOD([], HRESULT, 'MoveEndpointByRange', + ( ['in'], TextPatternRangeEndpoint, 'srcEndPoint' ), + ( ['in'], POINTER(IUIAutomationTextRange), 'range' ), + ( ['in'], TextPatternRangeEndpoint, 'targetEndPoint' )), + COMMETHOD([], HRESULT, 'Select'), + COMMETHOD([], HRESULT, 'AddToSelection'), + COMMETHOD([], HRESULT, 'RemoveFromSelection'), + COMMETHOD([], HRESULT, 'ScrollIntoView', + ( ['in'], c_int, 'alignToTop' )), + COMMETHOD([], HRESULT, 'GetChildren', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'children' )), ] ################################################################ -## code template for IUIAutomationValuePattern implementation -##class IUIAutomationValuePattern_Impl(object): -## @property -## def CachedIsReadOnly(self): +## code template for IUIAutomationTextRange implementation +##class IUIAutomationTextRange_Impl(object): +## def Clone(self): ## '-no docstring-' -## #return retVal +## #return clonedRange ## -## @property -## def CurrentValue(self): +## def Compare(self, range): +## '-no docstring-' +## #return areSame +## +## def CompareEndpoints(self, srcEndPoint, range, targetEndPoint): ## '-no docstring-' -## #return retVal +## #return compValue ## -## def SetValue(self, val): +## def ExpandToEnclosingUnit(self, TextUnit): ## '-no docstring-' ## #return ## -## @property -## def CurrentIsReadOnly(self): +## def FindAttribute(self, attr, val, backward): ## '-no docstring-' -## #return retVal +## #return found ## -## @property -## def CachedValue(self): +## def FindText(self, text, backward, ignoreCase): ## '-no docstring-' -## #return retVal +## #return found ## - -UIA_GridItemColumnPropertyId = 30065 # Constant c_int -UIA_DockPatternId = 10011 # Constant c_int -UIA_TablePatternId = 10012 # Constant c_int -class IUIAutomationWindowPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{0FAEF453-9208-43EF-BBB2-3B485177864F}') - _idlflags_ = [] - -# values for enumeration 'WindowVisualState' -WindowVisualState_Normal = 0 -WindowVisualState_Maximized = 1 -WindowVisualState_Minimized = 2 -WindowVisualState = c_int # enum - -# values for enumeration 'WindowInteractionState' -WindowInteractionState_Running = 0 -WindowInteractionState_Closing = 1 -WindowInteractionState_ReadyForUserInteraction = 2 -WindowInteractionState_BlockedByModalWindow = 3 -WindowInteractionState_NotResponding = 4 -WindowInteractionState = c_int # enum -IUIAutomationWindowPattern._methods_ = [ - COMMETHOD([], HRESULT, 'Close'), - COMMETHOD([], HRESULT, 'WaitForInputIdle', - ( ['in'], c_int, 'milliseconds' ), - ( ['retval', 'out'], POINTER(c_int), 'success' )), - COMMETHOD([], HRESULT, 'SetWindowVisualState', - ( ['in'], WindowVisualState, 'state' )), - COMMETHOD(['propget'], HRESULT, 'CurrentCanMaximize', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentCanMinimize', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentIsModal', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentIsTopmost', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentWindowVisualState', - ( ['retval', 'out'], POINTER(WindowVisualState), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentWindowInteractionState', - ( ['retval', 'out'], POINTER(WindowInteractionState), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedCanMaximize', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedCanMinimize', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedIsModal', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedIsTopmost', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedWindowVisualState', - ( ['retval', 'out'], POINTER(WindowVisualState), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedWindowInteractionState', - ( ['retval', 'out'], POINTER(WindowInteractionState), 'retVal' )), -] -################################################################ -## code template for IUIAutomationWindowPattern implementation -##class IUIAutomationWindowPattern_Impl(object): -## @property -## def CurrentIsTopmost(self): +## def GetAttributeValue(self, attr): ## '-no docstring-' -## #return retVal +## #return value ## -## def SetWindowVisualState(self, state): +## def GetBoundingRectangles(self): ## '-no docstring-' -## #return +## #return boundingRects ## -## @property -## def CurrentIsModal(self): +## def GetEnclosingElement(self): ## '-no docstring-' -## #return retVal +## #return enclosingElement ## -## @property -## def CachedIsTopmost(self): +## def GetText(self, maxLength): ## '-no docstring-' -## #return retVal +## #return text ## -## @property -## def CurrentWindowInteractionState(self): +## def Move(self, unit, count): ## '-no docstring-' -## #return retVal +## #return moved ## -## @property -## def CachedIsModal(self): +## def MoveEndpointByUnit(self, endpoint, unit, count): ## '-no docstring-' -## #return retVal +## #return moved ## -## @property -## def CurrentCanMinimize(self): +## def MoveEndpointByRange(self, srcEndPoint, range, targetEndPoint): ## '-no docstring-' -## #return retVal +## #return ## -## def WaitForInputIdle(self, milliseconds): +## def Select(self): ## '-no docstring-' -## #return success +## #return ## -## @property -## def CachedCanMaximize(self): +## def AddToSelection(self): ## '-no docstring-' -## #return retVal +## #return ## -## @property -## def CachedCanMinimize(self): +## def RemoveFromSelection(self): ## '-no docstring-' -## #return retVal +## #return ## -## @property -## def CachedWindowVisualState(self): +## def ScrollIntoView(self, alignToTop): ## '-no docstring-' -## #return retVal +## #return ## -## @property -## def CurrentWindowVisualState(self): +## def GetChildren(self): ## '-no docstring-' -## #return retVal +## #return children ## -## @property -## def CurrentCanMaximize(self): + +UIA_RangeValuePatternId = 10003 # Constant c_int +class IUIAutomationScrollItemPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{B488300F-D015-4F19-9C29-BB595E3645EF}') + _idlflags_ = [] +IUIAutomationScrollItemPattern._methods_ = [ + COMMETHOD([], HRESULT, 'ScrollIntoView'), +] +################################################################ +## code template for IUIAutomationScrollItemPattern implementation +##class IUIAutomationScrollItemPattern_Impl(object): +## def ScrollIntoView(self): ## '-no docstring-' -## #return retVal +## #return ## -## def Close(self): + +class IUIAutomationTextRange2(IUIAutomationTextRange): + _case_insensitive_ = True + _iid_ = GUID('{BB9B40E0-5E04-46BD-9BE0-4B601B9AFAD4}') + _idlflags_ = [] +IUIAutomationTextRange2._methods_ = [ + COMMETHOD([], HRESULT, 'ShowContextMenu'), +] +################################################################ +## code template for IUIAutomationTextRange2 implementation +##class IUIAutomationTextRange2_Impl(object): +## def ShowContextMenu(self): ## '-no docstring-' ## #return ## -## @property -## def CachedWindowInteractionState(self): + +class IUIAutomationTextRange3(IUIAutomationTextRange2): + _case_insensitive_ = True + _iid_ = GUID('{6A315D69-5512-4C2E-85F0-53FCE6DD4BC2}') + _idlflags_ = [] +IUIAutomationTextRange3._methods_ = [ + COMMETHOD([], HRESULT, 'GetEnclosingElementBuildCache', + ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'enclosingElement' )), + COMMETHOD([], HRESULT, 'GetChildrenBuildCache', + ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'children' )), + COMMETHOD([], HRESULT, 'GetAttributeValues', + ( ['in'], POINTER(c_int), 'attributeIds' ), + ( ['in'], c_int, 'attributeIdCount' ), + ( ['out', 'retval'], POINTER(_midlSAFEARRAY(VARIANT)), 'attributeValues' )), +] +################################################################ +## code template for IUIAutomationTextRange3 implementation +##class IUIAutomationTextRange3_Impl(object): +## def GetEnclosingElementBuildCache(self, cacheRequest): ## '-no docstring-' -## #return retVal +## #return enclosingElement +## +## def GetChildrenBuildCache(self, cacheRequest): +## '-no docstring-' +## #return children +## +## def GetAttributeValues(self, attributeIds, attributeIdCount): +## '-no docstring-' +## #return attributeValues ## -UIA_DockDockPositionPropertyId = 30069 # Constant c_int -UIA_ExpandCollapseExpandCollapseStatePropertyId = 30070 # Constant c_int -class CUIAutomation8(CoClass): - u'The Central Class for UIAutomation8' - _reg_clsid_ = GUID('{E22AD333-B25F-460C-83D0-0581107395C9}') - _idlflags_ = [] - _typelib_path_ = typelib_path - _reg_typelib_ = ('{944DE083-8FB8-45CF-BCB7-C477ACB2F897}', 1, 0) -CUIAutomation8._com_interfaces_ = [IUIAutomation2, IUIAutomation3, IUIAutomation4, IUIAutomation5, IUIAutomation6] +IUIAutomationTextRangeArray._methods_ = [ + COMMETHOD(['propget'], HRESULT, 'Length', + ( ['out', 'retval'], POINTER(c_int), 'Length' )), + COMMETHOD([], HRESULT, 'GetElement', + ( ['in'], c_int, 'index' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationTextRange)), 'element' )), +] +################################################################ +## code template for IUIAutomationTextRangeArray implementation +##class IUIAutomationTextRangeArray_Impl(object): +## @property +## def Length(self): +## '-no docstring-' +## #return Length +## +## def GetElement(self, index): +## '-no docstring-' +## #return element +## -UIA_MultipleViewSupportedViewsPropertyId = 30072 # Constant c_int -UIA_SpreadsheetPatternId = 10026 # Constant c_int -UIA_LegacyIAccessiblePatternId = 10018 # Constant c_int -UIA_WindowCanMinimizePropertyId = 30074 # Constant c_int -UIA_TableItemPatternId = 10013 # Constant c_int -StyleId_Heading5 = 70005 # Constant c_int -UIA_VirtualizedItemPatternId = 10020 # Constant c_int -UIA_DragGrabbedItemsPropertyId = 30144 # Constant c_int -UIA_SynchronizedInputPatternId = 10021 # Constant c_int -UIA_ObjectModelPatternId = 10022 # Constant c_int -UIA_AnnotationPatternId = 10023 # Constant c_int -UIA_SelectionItemIsSelectedPropertyId = 30079 # Constant c_int -UIA_IsSpreadsheetItemPatternAvailablePropertyId = 30132 # Constant c_int -StyleId_Heading6 = 70006 # Constant c_int -UIA_GridItemColumnSpanPropertyId = 30067 # Constant c_int -UIA_StylesPatternId = 10025 # Constant c_int -UIA_SemanticZoomControlTypeId = 50039 # Constant c_int -UIA_TableColumnHeadersPropertyId = 30082 # Constant c_int -UIA_TableRowOrColumnMajorPropertyId = 30083 # Constant c_int -AnnotationType_ExternalChange = 60017 # Constant c_int -UIA_TextChildPatternId = 10029 # Constant c_int -UIA_Transform2CanZoomPropertyId = 30133 # Constant c_int -UIA_DragPatternId = 10030 # Constant c_int -UIA_AppBarControlTypeId = 50040 # Constant c_int -UIA_ToggleToggleStatePropertyId = 30086 # Constant c_int -class IUIAutomationScrollPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): +UIA_InvokePatternId = 10000 # Constant c_int +UIA_SelectionPatternId = 10001 # Constant c_int +class IUIAutomationTogglePattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): _case_insensitive_ = True - _iid_ = GUID('{88F4D42A-E881-459D-A77C-73BBBB7E02DC}') + _iid_ = GUID('{94CF8058-9B8D-4AB9-8BFD-4CD0A33C8C70}') _idlflags_ = [] -IUIAutomationScrollPattern._methods_ = [ - COMMETHOD([], HRESULT, 'Scroll', - ( ['in'], ScrollAmount, 'horizontalAmount' ), - ( ['in'], ScrollAmount, 'verticalAmount' )), - COMMETHOD([], HRESULT, 'SetScrollPercent', - ( ['in'], c_double, 'horizontalPercent' ), - ( ['in'], c_double, 'verticalPercent' )), - COMMETHOD(['propget'], HRESULT, 'CurrentHorizontalScrollPercent', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentVerticalScrollPercent', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentHorizontalViewSize', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentVerticalViewSize', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentHorizontallyScrollable', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentVerticallyScrollable', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedHorizontalScrollPercent', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedVerticalScrollPercent', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedHorizontalViewSize', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedVerticalViewSize', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedHorizontallyScrollable', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedVerticallyScrollable', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), + +# values for enumeration 'ToggleState' +ToggleState_Off = 0 +ToggleState_On = 1 +ToggleState_Indeterminate = 2 +ToggleState = c_int # enum +IUIAutomationTogglePattern._methods_ = [ + COMMETHOD([], HRESULT, 'Toggle'), + COMMETHOD(['propget'], HRESULT, 'CurrentToggleState', + ( ['out', 'retval'], POINTER(ToggleState), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedToggleState', + ( ['out', 'retval'], POINTER(ToggleState), 'retVal' )), ] ################################################################ -## code template for IUIAutomationScrollPattern implementation -##class IUIAutomationScrollPattern_Impl(object): -## @property -## def CachedVerticalScrollPercent(self): +## code template for IUIAutomationTogglePattern implementation +##class IUIAutomationTogglePattern_Impl(object): +## def Toggle(self): ## '-no docstring-' -## #return retVal +## #return ## ## @property -## def CachedHorizontalViewSize(self): +## def CurrentToggleState(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedVerticalViewSize(self): +## def CachedToggleState(self): ## '-no docstring-' ## #return retVal ## -## @property -## def CurrentHorizontalViewSize(self): + +HeadingLevel_None = 80050 # Constant c_int +HeadingLevel2 = 80052 # Constant c_int +HeadingLevel4 = 80054 # Constant c_int +HeadingLevel5 = 80055 # Constant c_int +class IUIAutomationTransformPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{A9B55844-A55D-4EF0-926D-569C16FF89BB}') + _idlflags_ = [] +IUIAutomationTransformPattern._methods_ = [ + COMMETHOD([], HRESULT, 'Move', + ( ['in'], c_double, 'x' ), + ( ['in'], c_double, 'y' )), + COMMETHOD([], HRESULT, 'Resize', + ( ['in'], c_double, 'width' ), + ( ['in'], c_double, 'height' )), + COMMETHOD([], HRESULT, 'Rotate', + ( ['in'], c_double, 'degrees' )), + COMMETHOD(['propget'], HRESULT, 'CurrentCanMove', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentCanResize', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentCanRotate', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedCanMove', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedCanResize', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedCanRotate', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), +] +################################################################ +## code template for IUIAutomationTransformPattern implementation +##class IUIAutomationTransformPattern_Impl(object): +## def Move(self, x, y): ## '-no docstring-' -## #return retVal +## #return ## -## @property -## def CachedHorizontalScrollPercent(self): +## def Resize(self, width, height): ## '-no docstring-' -## #return retVal +## #return ## -## @property -## def CachedHorizontallyScrollable(self): +## def Rotate(self, degrees): ## '-no docstring-' -## #return retVal +## #return ## ## @property -## def CurrentHorizontalScrollPercent(self): +## def CurrentCanMove(self): ## '-no docstring-' ## #return retVal ## -## def Scroll(self, horizontalAmount, verticalAmount): -## '-no docstring-' -## #return -## ## @property -## def CurrentHorizontallyScrollable(self): +## def CurrentCanResize(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentVerticalViewSize(self): +## def CurrentCanRotate(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentVerticallyScrollable(self): +## def CachedCanMove(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedVerticallyScrollable(self): +## def CachedCanResize(self): ## '-no docstring-' ## #return retVal ## -## def SetScrollPercent(self, horizontalPercent, verticalPercent): -## '-no docstring-' -## #return -## ## @property -## def CurrentVerticalScrollPercent(self): +## def CachedCanRotate(self): ## '-no docstring-' ## #return retVal ## -UIA_TransformCanResizePropertyId = 30088 # Constant c_int -UIA_SelectionPattern2Id = 10034 # Constant c_int -UIA_IsSelectionPattern2AvailablePropertyId = 30168 # Constant c_int -UIA_TransformPatternId = 10016 # Constant c_int -UIA_IsTransformPattern2AvailablePropertyId = 30134 # Constant c_int -UIA_IsLegacyIAccessiblePatternAvailablePropertyId = 30090 # Constant c_int -UIA_LegacyIAccessibleChildIdPropertyId = 30091 # Constant c_int -UIA_CustomLandmarkTypeId = 80000 # Constant c_int -UIA_ComboBoxControlTypeId = 50003 # Constant c_int -UIA_HyperlinkControlTypeId = 50005 # Constant c_int -StyleId_Normal = 70012 # Constant c_int -StyleId_Title = 70010 # Constant c_int -UIA_ListItemControlTypeId = 50007 # Constant c_int -UIA_IsTextChildPatternAvailablePropertyId = 30136 # Constant c_int -UIA_LegacyIAccessibleSelectionPropertyId = 30099 # Constant c_int -UIA_AriaPropertiesPropertyId = 30102 # Constant c_int -UIA_Transform2ZoomLevelPropertyId = 30145 # Constant c_int -UIA_LegacyIAccessibleDefaultActionPropertyId = 30100 # Constant c_int -UIA_AriaRolePropertyId = 30101 # Constant c_int -UIA_MenuItemControlTypeId = 50011 # Constant c_int -UIA_IsDataValidForFormPropertyId = 30103 # Constant c_int -UIA_RadioButtonControlTypeId = 50013 # Constant c_int -UIA_DescribedByPropertyId = 30105 # Constant c_int -class IUIAutomationVirtualizedItemPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): +HeadingLevel6 = 80056 # Constant c_int +class IUIAutomationExpandCollapsePattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): _case_insensitive_ = True - _iid_ = GUID('{6BA3D7A6-04CF-4F11-8793-A8D1CDE9969F}') + _iid_ = GUID('{619BE086-1F4E-4EE4-BAFA-210128738730}') _idlflags_ = [] -IUIAutomationVirtualizedItemPattern._methods_ = [ - COMMETHOD([], HRESULT, 'Realize'), + +# values for enumeration 'ExpandCollapseState' +ExpandCollapseState_Collapsed = 0 +ExpandCollapseState_Expanded = 1 +ExpandCollapseState_PartiallyExpanded = 2 +ExpandCollapseState_LeafNode = 3 +ExpandCollapseState = c_int # enum +IUIAutomationExpandCollapsePattern._methods_ = [ + COMMETHOD([], HRESULT, 'Expand'), + COMMETHOD([], HRESULT, 'Collapse'), + COMMETHOD(['propget'], HRESULT, 'CurrentExpandCollapseState', + ( ['out', 'retval'], POINTER(ExpandCollapseState), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedExpandCollapseState', + ( ['out', 'retval'], POINTER(ExpandCollapseState), 'retVal' )), ] ################################################################ -## code template for IUIAutomationVirtualizedItemPattern implementation -##class IUIAutomationVirtualizedItemPattern_Impl(object): -## def Realize(self): +## code template for IUIAutomationExpandCollapsePattern implementation +##class IUIAutomationExpandCollapsePattern_Impl(object): +## def Expand(self): +## '-no docstring-' +## #return +## +## def Collapse(self): ## '-no docstring-' ## #return ## +## @property +## def CurrentExpandCollapseState(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CachedExpandCollapseState(self): +## '-no docstring-' +## #return retVal +## -UIA_ProviderDescriptionPropertyId = 30107 # Constant c_int -UIA_IsItemContainerPatternAvailablePropertyId = 30108 # Constant c_int -UIA_WindowCanMaximizePropertyId = 30073 # Constant c_int -UIA_IsVirtualizedItemPatternAvailablePropertyId = 30109 # Constant c_int -UIA_TabItemControlTypeId = 50019 # Constant c_int -UIA_LayoutInvalidatedEventId = 20008 # Constant c_int -UIA_OptimizeForVisualContentPropertyId = 30111 # Constant c_int -class IUIAutomationTextRangeArray(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{CE4AE76A-E717-4C98-81EA-47371D028EB6}') - _idlflags_ = [] -IUIAutomationTextRangeArray._methods_ = [ +HeadingLevel7 = 80057 # Constant c_int +HeadingLevel8 = 80058 # Constant c_int +HeadingLevel9 = 80059 # Constant c_int +UIA_SummaryChangeId = 90000 # Constant c_int +UIA_SayAsInterpretAsMetadataId = 100000 # Constant c_int + +# values for enumeration 'DockPosition' +DockPosition_Top = 0 +DockPosition_Left = 1 +DockPosition_Bottom = 2 +DockPosition_Right = 3 +DockPosition_Fill = 4 +DockPosition_None = 5 +DockPosition = c_int # enum +IUIAutomationElementArray._methods_ = [ COMMETHOD(['propget'], HRESULT, 'Length', - ( ['retval', 'out'], POINTER(c_int), 'Length' )), + ( ['out', 'retval'], POINTER(c_int), 'Length' )), COMMETHOD([], HRESULT, 'GetElement', ( ['in'], c_int, 'index' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationTextRange)), 'element' )), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'element' )), ] ################################################################ -## code template for IUIAutomationTextRangeArray implementation -##class IUIAutomationTextRangeArray_Impl(object): +## code template for IUIAutomationElementArray implementation +##class IUIAutomationElementArray_Impl(object): ## @property ## def Length(self): ## '-no docstring-' @@ -3271,752 +3226,560 @@ class IUIAutomationTextRangeArray(comtypes.gen._00020430_0000_0000_C000_00000000 ## #return element ## -class IUIAutomationElement8(IUIAutomationElement7): - _case_insensitive_ = True - _iid_ = GUID('{8C60217D-5411-4CDE-BCC0-1CEDA223830C}') - _idlflags_ = [] -IUIAutomationElement8._methods_ = [ - COMMETHOD(['propget'], HRESULT, 'CurrentHeadingLevel', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedHeadingLevel', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), -] -################################################################ -## code template for IUIAutomationElement8 implementation -##class IUIAutomationElement8_Impl(object): -## @property -## def CachedHeadingLevel(self): -## '-no docstring-' -## #return retVal -## -## @property -## def CurrentHeadingLevel(self): -## '-no docstring-' -## #return retVal -## -UIA_LegacyIAccessibleHelpPropertyId = 30097 # Constant c_int -UIA_LegacyIAccessibleNamePropertyId = 30092 # Constant c_int -UIA_LegacyIAccessibleValuePropertyId = 30093 # Constant c_int -UIA_LegacyIAccessibleDescriptionPropertyId = 30094 # Constant c_int -UIA_LegacyIAccessibleRolePropertyId = 30095 # Constant c_int -UIA_LegacyIAccessibleStatePropertyId = 30096 # Constant c_int -UIA_AnnotationAnnotationTypeIdPropertyId = 30113 # Constant c_int -UIA_Invoke_InvokedEventId = 20009 # Constant c_int -UIA_SelectionItem_ElementAddedToSelectionEventId = 20010 # Constant c_int -UIA_SelectionItem_ElementRemovedFromSelectionEventId = 20011 # Constant c_int -UIA_SelectionItem_ElementSelectedEventId = 20012 # Constant c_int -UIA_Selection_InvalidatedEventId = 20013 # Constant c_int -UIA_AnnotationAnnotationTypeNamePropertyId = 30114 # Constant c_int -UIA_Text_TextChangedEventId = 20015 # Constant c_int -AnnotationType_TrackChanges = 60005 # Constant c_int -UIA_Window_WindowOpenedEventId = 20016 # Constant c_int -UIA_Window_WindowClosedEventId = 20017 # Constant c_int -UIA_MenuModeStartEventId = 20018 # Constant c_int -UIA_MenuModeEndEventId = 20019 # Constant c_int -UIA_AnnotationAuthorPropertyId = 30115 # Constant c_int -UIA_InputReachedOtherElementEventId = 20021 # Constant c_int -UIA_InputDiscardedEventId = 20022 # Constant c_int -UIA_SystemAlertEventId = 20023 # Constant c_int -UIA_LiveRegionChangedEventId = 20024 # Constant c_int -UIA_HostedFragmentRootsInvalidatedEventId = 20025 # Constant c_int -UIA_CustomControlTypeId = 50025 # Constant c_int -class IRawElementProviderSimple(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{D6DD68D1-86FD-4332-8666-9ABEDEA2D24C}') - _idlflags_ = ['oleautomation'] -IUIAutomationProxyFactory._methods_ = [ - COMMETHOD([], HRESULT, 'CreateProvider', - ( ['in'], c_void_p, 'hwnd' ), - ( ['in'], c_int, 'idObject' ), - ( ['in'], c_int, 'idChild' ), - ( ['retval', 'out'], POINTER(POINTER(IRawElementProviderSimple)), 'provider' )), - COMMETHOD(['propget'], HRESULT, 'ProxyFactoryId', - ( ['retval', 'out'], POINTER(BSTR), 'factoryId' )), +# values for enumeration 'AutomationElementMode' +AutomationElementMode_None = 0 +AutomationElementMode_Full = 1 +AutomationElementMode = c_int # enum +IUIAutomationCacheRequest._methods_ = [ + COMMETHOD([], HRESULT, 'AddProperty', + ( ['in'], c_int, 'propertyId' )), + COMMETHOD([], HRESULT, 'AddPattern', + ( ['in'], c_int, 'patternId' )), + COMMETHOD([], HRESULT, 'Clone', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationCacheRequest)), 'clonedRequest' )), + COMMETHOD(['propget'], HRESULT, 'TreeScope', + ( ['out', 'retval'], POINTER(TreeScope), 'scope' )), + COMMETHOD(['propput'], HRESULT, 'TreeScope', + ( ['in'], TreeScope, 'scope' )), + COMMETHOD(['propget'], HRESULT, 'TreeFilter', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationCondition)), 'filter' )), + COMMETHOD(['propput'], HRESULT, 'TreeFilter', + ( ['in'], POINTER(IUIAutomationCondition), 'filter' )), + COMMETHOD(['propget'], HRESULT, 'AutomationElementMode', + ( ['out', 'retval'], POINTER(AutomationElementMode), 'mode' )), + COMMETHOD(['propput'], HRESULT, 'AutomationElementMode', + ( ['in'], AutomationElementMode, 'mode' )), ] ################################################################ -## code template for IUIAutomationProxyFactory implementation -##class IUIAutomationProxyFactory_Impl(object): -## def CreateProvider(self, hwnd, idObject, idChild): +## code template for IUIAutomationCacheRequest implementation +##class IUIAutomationCacheRequest_Impl(object): +## def AddProperty(self, propertyId): ## '-no docstring-' -## #return provider +## #return ## -## @property -## def ProxyFactoryId(self): +## def AddPattern(self, patternId): ## '-no docstring-' -## #return factoryId +## #return +## +## def Clone(self): +## '-no docstring-' +## #return clonedRequest +## +## def _get(self): +## '-no docstring-' +## #return scope +## def _set(self, scope): +## '-no docstring-' +## TreeScope = property(_get, _set, doc = _set.__doc__) +## +## def _get(self): +## '-no docstring-' +## #return filter +## def _set(self, filter): +## '-no docstring-' +## TreeFilter = property(_get, _set, doc = _set.__doc__) +## +## def _get(self): +## '-no docstring-' +## #return mode +## def _set(self, mode): +## '-no docstring-' +## AutomationElementMode = property(_get, _set, doc = _set.__doc__) ## -UIA_Drag_DragCompleteEventId = 20028 # Constant c_int -UIA_DropTarget_DragEnterEventId = 20029 # Constant c_int -UIA_DropTarget_DragLeaveEventId = 20030 # Constant c_int -UIA_DropTarget_DroppedEventId = 20031 # Constant c_int -UIA_TextEdit_TextChangedEventId = 20032 # Constant c_int -class IUIAutomationElement9(IUIAutomationElement8): +class IUIAutomationGridPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): _case_insensitive_ = True - _iid_ = GUID('{39325FAC-039D-440E-A3A3-5EB81A5CECC3}') + _iid_ = GUID('{414C3CDC-856B-4F5B-8538-3131C6302550}') _idlflags_ = [] -IUIAutomationElement9._methods_ = [ - COMMETHOD(['propget'], HRESULT, 'CurrentIsDialog', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedIsDialog', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), +IUIAutomationGridPattern._methods_ = [ + COMMETHOD([], HRESULT, 'GetItem', + ( ['in'], c_int, 'row' ), + ( ['in'], c_int, 'column' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'element' )), + COMMETHOD(['propget'], HRESULT, 'CurrentRowCount', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentColumnCount', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedRowCount', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedColumnCount', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), ] ################################################################ -## code template for IUIAutomationElement9 implementation -##class IUIAutomationElement9_Impl(object): -## @property -## def CachedIsDialog(self): +## code template for IUIAutomationGridPattern implementation +##class IUIAutomationGridPattern_Impl(object): +## def GetItem(self, row, column): ## '-no docstring-' -## #return retVal +## #return element ## ## @property -## def CurrentIsDialog(self): +## def CurrentRowCount(self): ## '-no docstring-' ## #return retVal ## - -UIA_ChangesEventId = 20034 # Constant c_int -UIA_NotificationEventId = 20035 # Constant c_int -UIA_ActiveTextPositionChangedEventId = 20036 # Constant c_int -UIA_RuntimeIdPropertyId = 30000 # Constant c_int -UIA_ProcessIdPropertyId = 30002 # Constant c_int -UIA_ControlTypePropertyId = 30003 # Constant c_int -UIA_LocalizedControlTypePropertyId = 30004 # Constant c_int -UIA_NamePropertyId = 30005 # Constant c_int -UIA_AcceleratorKeyPropertyId = 30006 # Constant c_int -UIA_IsTextPattern2AvailablePropertyId = 30119 # Constant c_int -UIA_FlowsToPropertyId = 30106 # Constant c_int -UIA_HasKeyboardFocusPropertyId = 30008 # Constant c_int -UIA_IsKeyboardFocusablePropertyId = 30009 # Constant c_int -UIA_IsEnabledPropertyId = 30010 # Constant c_int -UIA_AutomationIdPropertyId = 30011 # Constant c_int -UIA_ClassNamePropertyId = 30012 # Constant c_int -UIA_HelpTextPropertyId = 30013 # Constant c_int -AnnotationType_DeletionChange = 60012 # Constant c_int -UIA_CulturePropertyId = 30015 # Constant c_int -UIA_IsControlElementPropertyId = 30016 # Constant c_int -UIA_IsContentElementPropertyId = 30017 # Constant c_int -UIA_LabeledByPropertyId = 30018 # Constant c_int -UIA_StylesStyleNamePropertyId = 30121 # Constant c_int -UIA_NativeWindowHandlePropertyId = 30020 # Constant c_int -UIA_ItemTypePropertyId = 30021 # Constant c_int -IRawElementProviderSimple._methods_ = [ - COMMETHOD(['propget'], HRESULT, 'ProviderOptions', - ( ['retval', 'out'], POINTER(ProviderOptions), 'pRetVal' )), - COMMETHOD([], HRESULT, 'GetPatternProvider', - ( ['in'], c_int, 'patternId' ), - ( ['retval', 'out'], POINTER(POINTER(IUnknown)), 'pRetVal' )), - COMMETHOD([], HRESULT, 'GetPropertyValue', - ( ['in'], c_int, 'propertyId' ), - ( ['retval', 'out'], POINTER(VARIANT), 'pRetVal' )), - COMMETHOD(['propget'], HRESULT, 'HostRawElementProvider', - ( ['retval', 'out'], POINTER(POINTER(IRawElementProviderSimple)), 'pRetVal' )), -] -################################################################ -## code template for IRawElementProviderSimple implementation -##class IRawElementProviderSimple_Impl(object): ## @property -## def ProviderOptions(self): -## '-no docstring-' -## #return pRetVal -## -## def GetPatternProvider(self, patternId): +## def CurrentColumnCount(self): ## '-no docstring-' -## #return pRetVal +## #return retVal ## ## @property -## def HostRawElementProvider(self): +## def CachedRowCount(self): ## '-no docstring-' -## #return pRetVal +## #return retVal ## -## def GetPropertyValue(self, propertyId): +## @property +## def CachedColumnCount(self): ## '-no docstring-' -## #return pRetVal +## #return retVal ## -UIA_OrientationPropertyId = 30023 # Constant c_int -UIA_FrameworkIdPropertyId = 30024 # Constant c_int -UIA_IsRequiredForFormPropertyId = 30025 # Constant c_int -UIA_ItemStatusPropertyId = 30026 # Constant c_int -UIA_IsDockPatternAvailablePropertyId = 30027 # Constant c_int -UIA_IsExpandCollapsePatternAvailablePropertyId = 30028 # Constant c_int -UIA_IsGridItemPatternAvailablePropertyId = 30029 # Constant c_int -UIA_IsGridPatternAvailablePropertyId = 30030 # Constant c_int -UIA_IsInvokePatternAvailablePropertyId = 30031 # Constant c_int -UIA_IsMultipleViewPatternAvailablePropertyId = 30032 # Constant c_int -UIA_IsRangeValuePatternAvailablePropertyId = 30033 # Constant c_int -UIA_IsScrollPatternAvailablePropertyId = 30034 # Constant c_int -UIA_IsScrollItemPatternAvailablePropertyId = 30035 # Constant c_int -UIA_IsSelectionItemPatternAvailablePropertyId = 30036 # Constant c_int -UIA_IsSelectionPatternAvailablePropertyId = 30037 # Constant c_int -UIA_IsTablePatternAvailablePropertyId = 30038 # Constant c_int -AnnotationType_Footer = 60007 # Constant c_int -UIA_IsTransformPatternAvailablePropertyId = 30042 # Constant c_int -UIA_IsTextPatternAvailablePropertyId = 30040 # Constant c_int -UIA_IsTogglePatternAvailablePropertyId = 30041 # Constant c_int -UIA_StructureChangedEventId = 20002 # Constant c_int -UIA_IsValuePatternAvailablePropertyId = 30043 # Constant c_int -UIA_IsWindowPatternAvailablePropertyId = 30044 # Constant c_int -UIA_ValueIsReadOnlyPropertyId = 30046 # Constant c_int -UIA_RangeValueValuePropertyId = 30047 # Constant c_int -UIA_RangeValueIsReadOnlyPropertyId = 30048 # Constant c_int -UIA_MenuOpenedEventId = 20003 # Constant c_int -UIA_RangeValueMaximumPropertyId = 30050 # Constant c_int -UIA_RangeValueLargeChangePropertyId = 30051 # Constant c_int -UIA_RangeValueSmallChangePropertyId = 30052 # Constant c_int -class IUIAutomationDockPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): +class IUIAutomationValuePattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): _case_insensitive_ = True - _iid_ = GUID('{FDE5EF97-1464-48F6-90BF-43D0948E86EC}') + _iid_ = GUID('{A94CD8B1-0844-4CD6-9D2D-640537AB39E9}') _idlflags_ = [] - -# values for enumeration 'DockPosition' -DockPosition_Top = 0 -DockPosition_Left = 1 -DockPosition_Bottom = 2 -DockPosition_Right = 3 -DockPosition_Fill = 4 -DockPosition_None = 5 -DockPosition = c_int # enum -IUIAutomationDockPattern._methods_ = [ - COMMETHOD([], HRESULT, 'SetDockPosition', - ( ['in'], DockPosition, 'dockPos' )), - COMMETHOD(['propget'], HRESULT, 'CurrentDockPosition', - ( ['retval', 'out'], POINTER(DockPosition), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedDockPosition', - ( ['retval', 'out'], POINTER(DockPosition), 'retVal' )), +IUIAutomationValuePattern._methods_ = [ + COMMETHOD([], HRESULT, 'SetValue', + ( ['in'], BSTR, 'val' )), + COMMETHOD(['propget'], HRESULT, 'CurrentValue', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentIsReadOnly', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedValue', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedIsReadOnly', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), ] ################################################################ -## code template for IUIAutomationDockPattern implementation -##class IUIAutomationDockPattern_Impl(object): +## code template for IUIAutomationValuePattern implementation +##class IUIAutomationValuePattern_Impl(object): +## def SetValue(self, val): +## '-no docstring-' +## #return +## ## @property -## def CachedDockPosition(self): +## def CurrentValue(self): ## '-no docstring-' ## #return retVal ## -## def SetDockPosition(self, dockPos): +## @property +## def CurrentIsReadOnly(self): ## '-no docstring-' -## #return +## #return retVal ## ## @property -## def CurrentDockPosition(self): +## def CachedValue(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CachedIsReadOnly(self): ## '-no docstring-' ## #return retVal ## -UIA_ScrollHorizontalViewSizePropertyId = 30054 # Constant c_int -UIA_MenuClosedEventId = 20007 # Constant c_int -UIA_ScrollVerticalViewSizePropertyId = 30056 # Constant c_int UIA_ValuePatternId = 10002 # Constant c_int -UIA_RangeValuePatternId = 10003 # Constant c_int -UIA_ScrollPatternId = 10004 # Constant c_int -UIA_ExpandCollapsePatternId = 10005 # Constant c_int -UIA_SelectionIsSelectionRequiredPropertyId = 30061 # Constant c_int -UIA_GridItemPatternId = 10007 # Constant c_int -UIA_MultipleViewPatternId = 10008 # Constant c_int -UIA_WindowPatternId = 10009 # Constant c_int -UIA_SelectionItemPatternId = 10010 # Constant c_int -UIA_GridItemRowSpanPropertyId = 30066 # Constant c_int -UIA_SpreadsheetItemFormulaPropertyId = 30129 # Constant c_int -UIA_GridItemContainingGridPropertyId = 30068 # Constant c_int -UIA_TextPatternId = 10014 # Constant c_int -UIA_TogglePatternId = 10015 # Constant c_int -UIA_MultipleViewCurrentViewPropertyId = 30071 # Constant c_int -UIA_ScrollItemPatternId = 10017 # Constant c_int -class IUIAutomationTextPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{32EBA289-3583-42C9-9C59-3B6D9A1E9B6A}') - _idlflags_ = [] -class IUIAutomationTextPattern2(IUIAutomationTextPattern): +class IUIAutomationGridItemPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): _case_insensitive_ = True - _iid_ = GUID('{506A921A-FCC9-409F-B23B-37EB74106872}') + _iid_ = GUID('{78F8EF57-66C3-4E09-BD7C-E79B2004894D}') _idlflags_ = [] -IUIAutomationTextPattern._methods_ = [ - COMMETHOD([], HRESULT, 'RangeFromPoint', - ( ['in'], tagPOINT, 'pt' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationTextRange)), 'range' )), - COMMETHOD([], HRESULT, 'RangeFromChild', - ( ['in'], POINTER(IUIAutomationElement), 'child' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationTextRange)), 'range' )), - COMMETHOD([], HRESULT, 'GetSelection', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationTextRangeArray)), 'ranges' )), - COMMETHOD([], HRESULT, 'GetVisibleRanges', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationTextRangeArray)), 'ranges' )), - COMMETHOD(['propget'], HRESULT, 'DocumentRange', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationTextRange)), 'range' )), - COMMETHOD(['propget'], HRESULT, 'SupportedTextSelection', - ( ['retval', 'out'], POINTER(SupportedTextSelection), 'SupportedTextSelection' )), +IUIAutomationGridItemPattern._methods_ = [ + COMMETHOD(['propget'], HRESULT, 'CurrentContainingGrid', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentRow', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentColumn', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentRowSpan', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentColumnSpan', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedContainingGrid', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedRow', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedColumn', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedRowSpan', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedColumnSpan', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), ] ################################################################ -## code template for IUIAutomationTextPattern implementation -##class IUIAutomationTextPattern_Impl(object): -## def RangeFromChild(self, child): +## code template for IUIAutomationGridItemPattern implementation +##class IUIAutomationGridItemPattern_Impl(object): +## @property +## def CurrentContainingGrid(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CurrentRow(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CurrentColumn(self): ## '-no docstring-' -## #return range +## #return retVal ## -## def GetVisibleRanges(self): +## @property +## def CurrentRowSpan(self): ## '-no docstring-' -## #return ranges +## #return retVal ## -## def GetSelection(self): +## @property +## def CurrentColumnSpan(self): ## '-no docstring-' -## #return ranges +## #return retVal ## ## @property -## def DocumentRange(self): +## def CachedContainingGrid(self): ## '-no docstring-' -## #return range +## #return retVal ## ## @property -## def SupportedTextSelection(self): +## def CachedRow(self): ## '-no docstring-' -## #return SupportedTextSelection +## #return retVal ## -## def RangeFromPoint(self, pt): +## @property +## def CachedColumn(self): ## '-no docstring-' -## #return range +## #return retVal ## - -IUIAutomationTextPattern2._methods_ = [ - COMMETHOD([], HRESULT, 'RangeFromAnnotation', - ( ['in'], POINTER(IUIAutomationElement), 'annotation' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationTextRange)), 'range' )), - COMMETHOD([], HRESULT, 'GetCaretRange', - ( ['out'], POINTER(c_int), 'isActive' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationTextRange)), 'range' )), -] -################################################################ -## code template for IUIAutomationTextPattern2 implementation -##class IUIAutomationTextPattern2_Impl(object): -## def RangeFromAnnotation(self, annotation): +## @property +## def CachedRowSpan(self): ## '-no docstring-' -## #return range +## #return retVal ## -## def GetCaretRange(self): +## @property +## def CachedColumnSpan(self): ## '-no docstring-' -## #return isActive, range +## #return retVal ## -UIA_ItemContainerPatternId = 10019 # Constant c_int -UIA_WindowWindowVisualStatePropertyId = 30075 # Constant c_int -UIA_WindowWindowInteractionStatePropertyId = 30076 # Constant c_int -UIA_WindowIsModalPropertyId = 30077 # Constant c_int -UIA_WindowIsTopmostPropertyId = 30078 # Constant c_int -UIA_TextPattern2Id = 10024 # Constant c_int -UIA_SelectionItemSelectionContainerPropertyId = 30080 # Constant c_int -UIA_TableRowHeadersPropertyId = 30081 # Constant c_int -UIA_SpreadsheetItemPatternId = 10027 # Constant c_int -UIA_TransformPattern2Id = 10028 # Constant c_int -UIA_TableItemRowHeaderItemsPropertyId = 30084 # Constant c_int -UIA_TableItemColumnHeaderItemsPropertyId = 30085 # Constant c_int -UIA_DropTargetPatternId = 10031 # Constant c_int -UIA_TransformCanMovePropertyId = 30087 # Constant c_int -UIA_CustomNavigationPatternId = 10033 # Constant c_int -UIA_TransformCanRotatePropertyId = 30089 # Constant c_int -UIA_ToolTipOpenedEventId = 20000 # Constant c_int -UIA_ToolTipClosedEventId = 20001 # Constant c_int -UIA_CheckBoxControlTypeId = 50002 # Constant c_int -StyleId_Quote = 70014 # Constant c_int -HeadingLevel1 = 80051 # Constant c_int -UIA_EditControlTypeId = 50004 # Constant c_int -UIA_ImageControlTypeId = 50006 # Constant c_int -UIA_AnimationStyleAttributeId = 40000 # Constant c_int -UIA_LegacyIAccessibleKeyboardShortcutPropertyId = 30098 # Constant c_int -UIA_ListControlTypeId = 50008 # Constant c_int -UIA_MenuControlTypeId = 50009 # Constant c_int -UIA_MenuBarControlTypeId = 50010 # Constant c_int -UIA_LiveSettingPropertyId = 30135 # Constant c_int -UIA_ProgressBarControlTypeId = 50012 # Constant c_int -UIA_ControllerForPropertyId = 30104 # Constant c_int -UIA_ScrollBarControlTypeId = 50014 # Constant c_int -UIA_SliderControlTypeId = 50015 # Constant c_int -UIA_SpinnerControlTypeId = 50016 # Constant c_int -UIA_StatusBarControlTypeId = 50017 # Constant c_int -UIA_TabControlTypeId = 50018 # Constant c_int -UIA_IsSynchronizedInputPatternAvailablePropertyId = 30110 # Constant c_int -UIA_TextControlTypeId = 50020 # Constant c_int -UIA_IsObjectModelPatternAvailablePropertyId = 30112 # Constant c_int -UIA_ToolTipControlTypeId = 50022 # Constant c_int -IAccessible._methods_ = [ - COMMETHOD([dispid(-5000), 'hidden', 'propget'], HRESULT, 'accParent', - ( ['retval', 'out'], POINTER(POINTER(IDispatch)), 'ppdispParent' )), - COMMETHOD([dispid(-5001), 'hidden', 'propget'], HRESULT, 'accChildCount', - ( ['retval', 'out'], POINTER(c_int), 'pcountChildren' )), - COMMETHOD([dispid(-5002), 'hidden', 'propget'], HRESULT, 'accChild', - ( ['in'], VARIANT, 'varChild' ), - ( ['retval', 'out'], POINTER(POINTER(IDispatch)), 'ppdispChild' )), - COMMETHOD([dispid(-5003), 'hidden', 'propget'], HRESULT, 'accName', - ( ['in', 'optional'], VARIANT, 'varChild' ), - ( ['retval', 'out'], POINTER(BSTR), 'pszName' )), - COMMETHOD([dispid(-5004), 'hidden', 'propget'], HRESULT, 'accValue', - ( ['in', 'optional'], VARIANT, 'varChild' ), - ( ['retval', 'out'], POINTER(BSTR), 'pszValue' )), - COMMETHOD([dispid(-5005), 'hidden', 'propget'], HRESULT, 'accDescription', - ( ['in', 'optional'], VARIANT, 'varChild' ), - ( ['retval', 'out'], POINTER(BSTR), 'pszDescription' )), - COMMETHOD([dispid(-5006), 'hidden', 'propget'], HRESULT, 'accRole', - ( ['in', 'optional'], VARIANT, 'varChild' ), - ( ['retval', 'out'], POINTER(VARIANT), 'pvarRole' )), - COMMETHOD([dispid(-5007), 'hidden', 'propget'], HRESULT, 'accState', - ( ['in', 'optional'], VARIANT, 'varChild' ), - ( ['retval', 'out'], POINTER(VARIANT), 'pvarState' )), - COMMETHOD([dispid(-5008), 'hidden', 'propget'], HRESULT, 'accHelp', - ( ['in', 'optional'], VARIANT, 'varChild' ), - ( ['retval', 'out'], POINTER(BSTR), 'pszHelp' )), - COMMETHOD([dispid(-5009), 'hidden', 'propget'], HRESULT, 'accHelpTopic', - ( ['out'], POINTER(BSTR), 'pszHelpFile' ), - ( ['in', 'optional'], VARIANT, 'varChild' ), - ( ['retval', 'out'], POINTER(c_int), 'pidTopic' )), - COMMETHOD([dispid(-5010), 'hidden', 'propget'], HRESULT, 'accKeyboardShortcut', - ( ['in', 'optional'], VARIANT, 'varChild' ), - ( ['retval', 'out'], POINTER(BSTR), 'pszKeyboardShortcut' )), - COMMETHOD([dispid(-5011), 'hidden', 'propget'], HRESULT, 'accFocus', - ( ['retval', 'out'], POINTER(VARIANT), 'pvarChild' )), - COMMETHOD([dispid(-5012), 'hidden', 'propget'], HRESULT, 'accSelection', - ( ['retval', 'out'], POINTER(VARIANT), 'pvarChildren' )), - COMMETHOD([dispid(-5013), 'hidden', 'propget'], HRESULT, 'accDefaultAction', - ( ['in', 'optional'], VARIANT, 'varChild' ), - ( ['retval', 'out'], POINTER(BSTR), 'pszDefaultAction' )), - COMMETHOD([dispid(-5014), 'hidden'], HRESULT, 'accSelect', - ( ['in'], c_int, 'flagsSelect' ), - ( ['in', 'optional'], VARIANT, 'varChild' )), - COMMETHOD([dispid(-5015), 'hidden'], HRESULT, 'accLocation', - ( ['out'], POINTER(c_int), 'pxLeft' ), - ( ['out'], POINTER(c_int), 'pyTop' ), - ( ['out'], POINTER(c_int), 'pcxWidth' ), - ( ['out'], POINTER(c_int), 'pcyHeight' ), - ( ['in', 'optional'], VARIANT, 'varChild' )), - COMMETHOD([dispid(-5016), 'hidden'], HRESULT, 'accNavigate', - ( ['in'], c_int, 'navDir' ), - ( ['in', 'optional'], VARIANT, 'varStart' ), - ( ['retval', 'out'], POINTER(VARIANT), 'pvarEndUpAt' )), - COMMETHOD([dispid(-5017), 'hidden'], HRESULT, 'accHitTest', - ( ['in'], c_int, 'xLeft' ), - ( ['in'], c_int, 'yTop' ), - ( ['retval', 'out'], POINTER(VARIANT), 'pvarChild' )), - COMMETHOD([dispid(-5018), 'hidden'], HRESULT, 'accDoDefaultAction', - ( ['in', 'optional'], VARIANT, 'varChild' )), - COMMETHOD([dispid(-5003), 'hidden', 'propput'], HRESULT, 'accName', - ( ['in', 'optional'], VARIANT, 'varChild' ), - ( ['in'], BSTR, 'pszName' )), - COMMETHOD([dispid(-5004), 'hidden', 'propput'], HRESULT, 'accValue', - ( ['in', 'optional'], VARIANT, 'varChild' ), - ( ['in'], BSTR, 'pszValue' )), +HeadingLevel3 = 80053 # Constant c_int +class IUIAutomationWindowPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{0FAEF453-9208-43EF-BBB2-3B485177864F}') + _idlflags_ = [] + +# values for enumeration 'WindowVisualState' +WindowVisualState_Normal = 0 +WindowVisualState_Maximized = 1 +WindowVisualState_Minimized = 2 +WindowVisualState = c_int # enum + +# values for enumeration 'WindowInteractionState' +WindowInteractionState_Running = 0 +WindowInteractionState_Closing = 1 +WindowInteractionState_ReadyForUserInteraction = 2 +WindowInteractionState_BlockedByModalWindow = 3 +WindowInteractionState_NotResponding = 4 +WindowInteractionState = c_int # enum +IUIAutomationWindowPattern._methods_ = [ + COMMETHOD([], HRESULT, 'Close'), + COMMETHOD([], HRESULT, 'WaitForInputIdle', + ( ['in'], c_int, 'milliseconds' ), + ( ['out', 'retval'], POINTER(c_int), 'success' )), + COMMETHOD([], HRESULT, 'SetWindowVisualState', + ( ['in'], WindowVisualState, 'state' )), + COMMETHOD(['propget'], HRESULT, 'CurrentCanMaximize', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentCanMinimize', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentIsModal', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentIsTopmost', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentWindowVisualState', + ( ['out', 'retval'], POINTER(WindowVisualState), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentWindowInteractionState', + ( ['out', 'retval'], POINTER(WindowInteractionState), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedCanMaximize', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedCanMinimize', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedIsModal', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedIsTopmost', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedWindowVisualState', + ( ['out', 'retval'], POINTER(WindowVisualState), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedWindowInteractionState', + ( ['out', 'retval'], POINTER(WindowInteractionState), 'retVal' )), ] ################################################################ -## code template for IAccessible implementation -##class IAccessible_Impl(object): +## code template for IUIAutomationWindowPattern implementation +##class IUIAutomationWindowPattern_Impl(object): +## def Close(self): +## '-no docstring-' +## #return +## +## def WaitForInputIdle(self, milliseconds): +## '-no docstring-' +## #return success +## +## def SetWindowVisualState(self, state): +## '-no docstring-' +## #return +## ## @property -## def accRole(self, varChild): +## def CurrentCanMaximize(self): ## '-no docstring-' -## #return pvarRole +## #return retVal ## ## @property -## def accDescription(self, varChild): +## def CurrentCanMinimize(self): ## '-no docstring-' -## #return pszDescription +## #return retVal ## -## def accLocation(self, varChild): +## @property +## def CurrentIsModal(self): ## '-no docstring-' -## #return pxLeft, pyTop, pcxWidth, pcyHeight +## #return retVal ## ## @property -## def accState(self, varChild): +## def CurrentIsTopmost(self): ## '-no docstring-' -## #return pvarState +## #return retVal ## -## def accNavigate(self, navDir, varStart): +## @property +## def CurrentWindowVisualState(self): ## '-no docstring-' -## #return pvarEndUpAt +## #return retVal ## -## def accDoDefaultAction(self, varChild): +## @property +## def CurrentWindowInteractionState(self): ## '-no docstring-' -## #return +## #return retVal ## ## @property -## def accChild(self, varChild): +## def CachedCanMaximize(self): ## '-no docstring-' -## #return ppdispChild +## #return retVal ## ## @property -## def accChildCount(self): +## def CachedCanMinimize(self): ## '-no docstring-' -## #return pcountChildren +## #return retVal ## ## @property -## def accHelp(self, varChild): +## def CachedIsModal(self): ## '-no docstring-' -## #return pszHelp +## #return retVal ## -## def _get(self, varChild): +## @property +## def CachedIsTopmost(self): ## '-no docstring-' -## #return pszName -## def _set(self, varChild, pszName): +## #return retVal +## +## @property +## def CachedWindowVisualState(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CachedWindowInteractionState(self): +## '-no docstring-' +## #return retVal +## + +class IUIAutomationMultipleViewPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{8D253C91-1DC5-4BB5-B18F-ADE16FA495E8}') + _idlflags_ = [] +IUIAutomationMultipleViewPattern._methods_ = [ + COMMETHOD([], HRESULT, 'GetViewName', + ( ['in'], c_int, 'view' ), + ( ['out', 'retval'], POINTER(BSTR), 'name' )), + COMMETHOD([], HRESULT, 'SetCurrentView', + ( ['in'], c_int, 'view' )), + COMMETHOD(['propget'], HRESULT, 'CurrentCurrentView', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD([], HRESULT, 'GetCurrentSupportedViews', + ( ['out', 'retval'], POINTER(_midlSAFEARRAY(c_int)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedCurrentView', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD([], HRESULT, 'GetCachedSupportedViews', + ( ['out', 'retval'], POINTER(_midlSAFEARRAY(c_int)), 'retVal' )), +] +################################################################ +## code template for IUIAutomationMultipleViewPattern implementation +##class IUIAutomationMultipleViewPattern_Impl(object): +## def GetViewName(self, view): ## '-no docstring-' -## accName = property(_get, _set, doc = _set.__doc__) +## #return name ## -## def accSelect(self, flagsSelect, varChild): +## def SetCurrentView(self, view): ## '-no docstring-' ## #return ## ## @property -## def accKeyboardShortcut(self, varChild): -## '-no docstring-' -## #return pszKeyboardShortcut -## -## def accHitTest(self, xLeft, yTop): +## def CurrentCurrentView(self): ## '-no docstring-' -## #return pvarChild +## #return retVal ## -## @property -## def accSelection(self): +## def GetCurrentSupportedViews(self): ## '-no docstring-' -## #return pvarChildren +## #return retVal ## ## @property -## def accDefaultAction(self, varChild): +## def CachedCurrentView(self): ## '-no docstring-' -## #return pszDefaultAction +## #return retVal ## -## @property -## def accParent(self): +## def GetCachedSupportedViews(self): ## '-no docstring-' -## #return ppdispParent +## #return retVal ## + +class IUIAutomationTextChildPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{6552B038-AE05-40C8-ABFD-AA08352AAB86}') + _idlflags_ = [] +IUIAutomationTextChildPattern._methods_ = [ + COMMETHOD(['propget'], HRESULT, 'TextContainer', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'container' )), + COMMETHOD(['propget'], HRESULT, 'TextRange', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationTextRange)), 'range' )), +] +################################################################ +## code template for IUIAutomationTextChildPattern implementation +##class IUIAutomationTextChildPattern_Impl(object): ## @property -## def accHelpTopic(self, varChild): -## '-no docstring-' -## #return pszHelpFile, pidTopic -## -## def _get(self, varChild): -## '-no docstring-' -## #return pszValue -## def _set(self, varChild, pszValue): +## def TextContainer(self): ## '-no docstring-' -## accValue = property(_get, _set, doc = _set.__doc__) +## #return container ## ## @property -## def accFocus(self): +## def TextRange(self): ## '-no docstring-' -## #return pvarChild +## #return range ## -UIA_TreeItemControlTypeId = 50024 # Constant c_int -UIA_AnnotationDateTimePropertyId = 30116 # Constant c_int -UIA_GroupControlTypeId = 50026 # Constant c_int -UIA_IsAnnotationPatternAvailablePropertyId = 30118 # Constant c_int -UIA_DataGridControlTypeId = 50028 # Constant c_int -AnnotationType_Header = 60006 # Constant c_int -UIA_DocumentControlTypeId = 50030 # Constant c_int -UIA_SplitButtonControlTypeId = 50031 # Constant c_int -UIA_StylesFillPatternStylePropertyId = 30123 # Constant c_int -UIA_StylesShapePropertyId = 30124 # Constant c_int -UIA_StylesFillPatternColorPropertyId = 30125 # Constant c_int -UIA_StylesExtendedPropertiesPropertyId = 30126 # Constant c_int -UIA_TableControlTypeId = 50036 # Constant c_int -UIA_TitleBarControlTypeId = 50037 # Constant c_int -UIA_SeparatorControlTypeId = 50038 # Constant c_int -UIA_SpreadsheetItemAnnotationObjectsPropertyId = 30130 # Constant c_int -UIA_SpreadsheetItemAnnotationTypesPropertyId = 30131 # Constant c_int -AnnotationType_Unknown = 60000 # Constant c_int -AnnotationType_SpellingError = 60001 # Constant c_int -AnnotationType_GrammarError = 60002 # Constant c_int -AnnotationType_Comment = 60003 # Constant c_int -AnnotationType_FormulaError = 60004 # Constant c_int -UIA_IsDragPatternAvailablePropertyId = 30137 # Constant c_int -UIA_DragIsGrabbedPropertyId = 30138 # Constant c_int -UIA_DragDropEffectPropertyId = 30139 # Constant c_int -UIA_DragDropEffectsPropertyId = 30140 # Constant c_int -UIA_IsDropTargetPatternAvailablePropertyId = 30141 # Constant c_int -UIA_DropTargetDropTargetEffectPropertyId = 30142 # Constant c_int -UIA_DropTargetDropTargetEffectsPropertyId = 30143 # Constant c_int -AnnotationType_Footnote = 60010 # Constant c_int -AnnotationType_MoveChange = 60013 # Constant c_int -UIA_Transform2ZoomMinimumPropertyId = 30146 # Constant c_int -AnnotationType_UnsyncedChange = 60015 # Constant c_int -AnnotationType_EditingLockedChange = 60016 # Constant c_int -UIA_IsTextEditPatternAvailablePropertyId = 30149 # Constant c_int -AnnotationType_InsertionChange = 60011 # Constant c_int -UIA_IsCustomNavigationPatternAvailablePropertyId = 30151 # Constant c_int -AnnotationType_AdvancedProofingIssue = 60020 # Constant c_int -UIA_SizeOfSetPropertyId = 30153 # Constant c_int -AnnotationType_CircularReferenceError = 60022 # Constant c_int -UIA_AnnotationTypesPropertyId = 30155 # Constant c_int -UIA_AnnotationObjectsPropertyId = 30156 # Constant c_int -UIA_LandmarkTypePropertyId = 30157 # Constant c_int -UIA_LocalizedLandmarkTypePropertyId = 30158 # Constant c_int -StyleId_Heading1 = 70001 # Constant c_int -class IUIAutomationTableItemPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): +class IUIAutomationDragPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): _case_insensitive_ = True - _iid_ = GUID('{0B964EB3-EF2E-4464-9C79-61D61737A27E}') + _iid_ = GUID('{1DC7B570-1F54-4BAD-BCDA-D36A722FB7BD}') _idlflags_ = [] -IUIAutomationTableItemPattern._methods_ = [ - COMMETHOD([], HRESULT, 'GetCurrentRowHeaderItems', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), - COMMETHOD([], HRESULT, 'GetCurrentColumnHeaderItems', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), - COMMETHOD([], HRESULT, 'GetCachedRowHeaderItems', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), - COMMETHOD([], HRESULT, 'GetCachedColumnHeaderItems', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), +IUIAutomationDragPattern._methods_ = [ + COMMETHOD(['propget'], HRESULT, 'CurrentIsGrabbed', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedIsGrabbed', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentDropEffect', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedDropEffect', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentDropEffects', + ( ['out', 'retval'], POINTER(_midlSAFEARRAY(BSTR)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedDropEffects', + ( ['out', 'retval'], POINTER(_midlSAFEARRAY(BSTR)), 'retVal' )), + COMMETHOD([], HRESULT, 'GetCurrentGrabbedItems', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), + COMMETHOD([], HRESULT, 'GetCachedGrabbedItems', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), ] ################################################################ -## code template for IUIAutomationTableItemPattern implementation -##class IUIAutomationTableItemPattern_Impl(object): -## def GetCachedRowHeaderItems(self): +## code template for IUIAutomationDragPattern implementation +##class IUIAutomationDragPattern_Impl(object): +## @property +## def CurrentIsGrabbed(self): ## '-no docstring-' ## #return retVal ## -## def GetCurrentColumnHeaderItems(self): +## @property +## def CachedIsGrabbed(self): ## '-no docstring-' ## #return retVal ## -## def GetCachedColumnHeaderItems(self): +## @property +## def CurrentDropEffect(self): ## '-no docstring-' ## #return retVal ## -## def GetCurrentRowHeaderItems(self): +## @property +## def CachedDropEffect(self): ## '-no docstring-' ## #return retVal ## - -UIA_FillColorPropertyId = 30160 # Constant c_int -StyleId_Heading3 = 70003 # Constant c_int -UIA_FillTypePropertyId = 30162 # Constant c_int -UIA_VisualEffectsPropertyId = 30163 # Constant c_int -UIA_OutlineThicknessPropertyId = 30164 # Constant c_int -UIA_CenterPointPropertyId = 30165 # Constant c_int -UIA_RotationPropertyId = 30166 # Constant c_int -UIA_SizePropertyId = 30167 # Constant c_int -AnnotationType_FormatChange = 60014 # Constant c_int -IUIAutomationActiveTextPositionChangedEventHandler._methods_ = [ - COMMETHOD([], HRESULT, 'HandleActiveTextPositionChangedEvent', - ( ['in'], POINTER(IUIAutomationElement), 'sender' ), - ( ['in'], POINTER(IUIAutomationTextRange), 'range' )), -] -################################################################ -## code template for IUIAutomationActiveTextPositionChangedEventHandler implementation -##class IUIAutomationActiveTextPositionChangedEventHandler_Impl(object): -## def HandleActiveTextPositionChangedEvent(self, sender, range): +## @property +## def CurrentDropEffects(self): ## '-no docstring-' -## #return +## #return retVal ## - -UIA_Selection2LastSelectedItemPropertyId = 30170 # Constant c_int -UIA_Selection2CurrentSelectedItemPropertyId = 30171 # Constant c_int -UIA_Text_TextSelectionChangedEventId = 20014 # Constant c_int -UIA_HeadingLevelPropertyId = 30173 # Constant c_int -UIA_Transform2ZoomMaximumPropertyId = 30147 # Constant c_int -class IUIAutomationItemContainerPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{C690FDB2-27A8-423C-812D-429773C9084E}') - _idlflags_ = [] -IUIAutomationItemContainerPattern._methods_ = [ - COMMETHOD([], HRESULT, 'FindItemByProperty', - ( ['in'], POINTER(IUIAutomationElement), 'pStartAfter' ), - ( ['in'], c_int, 'propertyId' ), - ( ['in'], VARIANT, 'value' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'pFound' )), -] -################################################################ -## code template for IUIAutomationItemContainerPattern implementation -##class IUIAutomationItemContainerPattern_Impl(object): -## def FindItemByProperty(self, pStartAfter, propertyId, value): +## @property +## def CachedDropEffects(self): ## '-no docstring-' -## #return pFound +## #return retVal ## - -StyleId_BulletedList = 70015 # Constant c_int -UIA_CapStyleAttributeId = 40003 # Constant c_int -UIA_CultureAttributeId = 40004 # Constant c_int -UIA_FontNameAttributeId = 40005 # Constant c_int -UIA_FontSizeAttributeId = 40006 # Constant c_int -UIA_SearchLandmarkTypeId = 80004 # Constant c_int -IUIAutomationEventHandlerGroup._methods_ = [ - COMMETHOD([], HRESULT, 'AddActiveTextPositionChangedEventHandler', - ( ['in'], TreeScope, 'scope' ), - ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['in'], POINTER(IUIAutomationActiveTextPositionChangedEventHandler), 'handler' )), - COMMETHOD([], HRESULT, 'AddAutomationEventHandler', - ( ['in'], c_int, 'eventId' ), - ( ['in'], TreeScope, 'scope' ), - ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['in'], POINTER(IUIAutomationEventHandler), 'handler' )), - COMMETHOD([], HRESULT, 'AddChangesEventHandler', - ( ['in'], TreeScope, 'scope' ), - ( ['in'], POINTER(c_int), 'changeTypes' ), - ( ['in'], c_int, 'changesCount' ), - ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['in'], POINTER(IUIAutomationChangesEventHandler), 'handler' )), - COMMETHOD([], HRESULT, 'AddNotificationEventHandler', - ( ['in'], TreeScope, 'scope' ), - ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['in'], POINTER(IUIAutomationNotificationEventHandler), 'handler' )), - COMMETHOD([], HRESULT, 'AddPropertyChangedEventHandler', - ( ['in'], TreeScope, 'scope' ), - ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['in'], POINTER(IUIAutomationPropertyChangedEventHandler), 'handler' ), - ( ['in'], POINTER(c_int), 'propertyArray' ), - ( ['in'], c_int, 'propertyCount' )), - COMMETHOD([], HRESULT, 'AddStructureChangedEventHandler', - ( ['in'], TreeScope, 'scope' ), - ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['in'], POINTER(IUIAutomationStructureChangedEventHandler), 'handler' )), - COMMETHOD([], HRESULT, 'AddTextEditTextChangedEventHandler', - ( ['in'], TreeScope, 'scope' ), - ( ['in'], TextEditChangeType, 'TextEditChangeType' ), - ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), - ( ['in'], POINTER(IUIAutomationTextEditTextChangedEventHandler), 'handler' )), -] -################################################################ -## code template for IUIAutomationEventHandlerGroup implementation -##class IUIAutomationEventHandlerGroup_Impl(object): -## def AddStructureChangedEventHandler(self, scope, cacheRequest, handler): +## def GetCurrentGrabbedItems(self): ## '-no docstring-' -## #return +## #return retVal ## -## def AddActiveTextPositionChangedEventHandler(self, scope, cacheRequest, handler): +## def GetCachedGrabbedItems(self): ## '-no docstring-' -## #return +## #return retVal ## -## def AddNotificationEventHandler(self, scope, cacheRequest, handler): + +class IUIAutomationDropTargetPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{69A095F7-EEE4-430E-A46B-FB73B1AE39A5}') + _idlflags_ = [] +IUIAutomationDropTargetPattern._methods_ = [ + COMMETHOD(['propget'], HRESULT, 'CurrentDropTargetEffect', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedDropTargetEffect', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentDropTargetEffects', + ( ['out', 'retval'], POINTER(_midlSAFEARRAY(BSTR)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedDropTargetEffects', + ( ['out', 'retval'], POINTER(_midlSAFEARRAY(BSTR)), 'retVal' )), +] +################################################################ +## code template for IUIAutomationDropTargetPattern implementation +##class IUIAutomationDropTargetPattern_Impl(object): +## @property +## def CurrentDropTargetEffect(self): ## '-no docstring-' -## #return +## #return retVal ## -## def AddPropertyChangedEventHandler(self, scope, cacheRequest, handler, propertyArray, propertyCount): +## @property +## def CachedDropTargetEffect(self): ## '-no docstring-' -## #return +## #return retVal ## -## def AddAutomationEventHandler(self, eventId, scope, cacheRequest, handler): +## @property +## def CurrentDropTargetEffects(self): ## '-no docstring-' -## #return +## #return retVal ## -## def AddTextEditTextChangedEventHandler(self, scope, TextEditChangeType, cacheRequest, handler): +## @property +## def CachedDropTargetEffects(self): ## '-no docstring-' -## #return +## #return retVal ## -## def AddChangesEventHandler(self, scope, changeTypes, changesCount, cacheRequest, handler): + +class IUIAutomationNotCondition(IUIAutomationCondition): + _case_insensitive_ = True + _iid_ = GUID('{F528B657-847B-498C-8896-D52B565407A1}') + _idlflags_ = [] +IUIAutomationNotCondition._methods_ = [ + COMMETHOD([], HRESULT, 'GetChild', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationCondition)), 'condition' )), +] +################################################################ +## code template for IUIAutomationNotCondition implementation +##class IUIAutomationNotCondition_Impl(object): +## def GetChild(self): ## '-no docstring-' -## #return +## #return condition ## -UIA_HorizontalTextAlignmentAttributeId = 40009 # Constant c_int -HeadingLevel2 = 80052 # Constant c_int -UIA_IndentationLeadingAttributeId = 40011 # Constant c_int -HeadingLevel3 = 80053 # Constant c_int -UIA_IsHiddenAttributeId = 40013 # Constant c_int -UIA_IsItalicAttributeId = 40014 # Constant c_int -UIA_IsReadOnlyAttributeId = 40015 # Constant c_int -UIA_IsSubscriptAttributeId = 40016 # Constant c_int -UIA_IsSuperscriptAttributeId = 40017 # Constant c_int -HeadingLevel6 = 80056 # Constant c_int -UIA_MarginLeadingAttributeId = 40019 # Constant c_int -HeadingLevel7 = 80057 # Constant c_int -UIA_MarginTrailingAttributeId = 40021 # Constant c_int -UIA_OutlineStylesAttributeId = 40022 # Constant c_int -UIA_OverlineColorAttributeId = 40023 # Constant c_int -HeadingLevel9 = 80059 # Constant c_int -UIA_StrikethroughColorAttributeId = 40025 # Constant c_int +UIA_AnimationStyleAttributeId = 40000 # Constant c_int +UIA_CultureAttributeId = 40004 # Constant c_int +UIA_BackgroundColorAttributeId = 40001 # Constant c_int IUIAutomationEventHandler._methods_ = [ COMMETHOD([], HRESULT, 'HandleAutomationEvent', ( ['in'], POINTER(IUIAutomationElement), 'sender' ), @@ -4030,1545 +3793,1778 @@ class IUIAutomationItemContainerPattern(comtypes.gen._00020430_0000_0000_C000_00 ## #return ## -UIA_TabsAttributeId = 40027 # Constant c_int -UIA_TextFlowDirectionsAttributeId = 40028 # Constant c_int -UIA_UnderlineColorAttributeId = 40029 # Constant c_int -UIA_AnnotationTypesAttributeId = 40031 # Constant c_int -UIA_AnnotationObjectsAttributeId = 40032 # Constant c_int -UIA_StyleNameAttributeId = 40033 # Constant c_int -UIA_StyleIdAttributeId = 40034 # Constant c_int -UIA_LinkAttributeId = 40035 # Constant c_int -AnnotationType_DataValidationError = 60021 # Constant c_int -UIA_SelectionActiveEndAttributeId = 40037 # Constant c_int -UIA_CaretPositionAttributeId = 40038 # Constant c_int -UIA_CaretBidiModeAttributeId = 40039 # Constant c_int -UIA_LineSpacingAttributeId = 40040 # Constant c_int -UIA_BeforeParagraphSpacingAttributeId = 40041 # Constant c_int -UIA_LevelPropertyId = 30154 # Constant c_int -UIA_SayAsInterpretAsAttributeId = 40043 # Constant c_int -UIA_ButtonControlTypeId = 50000 # Constant c_int -AnnotationType_Mathematics = 60023 # Constant c_int -class IUIAutomationExpandCollapsePattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): +UIA_CapStyleAttributeId = 40003 # Constant c_int +UIA_BulletStyleAttributeId = 40002 # Constant c_int +UIA_FontNameAttributeId = 40005 # Constant c_int +UIA_ScrollHorizontalViewSizePropertyId = 30054 # Constant c_int +UIA_ScrollVerticalScrollPercentPropertyId = 30055 # Constant c_int +UIA_ScrollVerticalViewSizePropertyId = 30056 # Constant c_int +class IUIAutomationStylesPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): _case_insensitive_ = True - _iid_ = GUID('{619BE086-1F4E-4EE4-BAFA-210128738730}') + _iid_ = GUID('{85B5F0A2-BD79-484A-AD2B-388C9838D5FB}') _idlflags_ = [] - -# values for enumeration 'ExpandCollapseState' -ExpandCollapseState_Collapsed = 0 -ExpandCollapseState_Expanded = 1 -ExpandCollapseState_PartiallyExpanded = 2 -ExpandCollapseState_LeafNode = 3 -ExpandCollapseState = c_int # enum -IUIAutomationExpandCollapsePattern._methods_ = [ - COMMETHOD([], HRESULT, 'Expand'), - COMMETHOD([], HRESULT, 'Collapse'), - COMMETHOD(['propget'], HRESULT, 'CurrentExpandCollapseState', - ( ['retval', 'out'], POINTER(ExpandCollapseState), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedExpandCollapseState', - ( ['retval', 'out'], POINTER(ExpandCollapseState), 'retVal' )), +class ExtendedProperty(Structure): + pass +IUIAutomationStylesPattern._methods_ = [ + COMMETHOD(['propget'], HRESULT, 'CurrentStyleId', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentStyleName', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentFillColor', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentFillPatternStyle', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentShape', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentFillPatternColor', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentExtendedProperties', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD([], HRESULT, 'GetCurrentExtendedPropertiesAsArray', + ( ['out'], POINTER(POINTER(ExtendedProperty)), 'propertyArray' ), + ( ['out'], POINTER(c_int), 'propertyCount' )), + COMMETHOD(['propget'], HRESULT, 'CachedStyleId', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedStyleName', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedFillColor', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedFillPatternStyle', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedShape', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedFillPatternColor', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedExtendedProperties', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD([], HRESULT, 'GetCachedExtendedPropertiesAsArray', + ( ['out'], POINTER(POINTER(ExtendedProperty)), 'propertyArray' ), + ( ['out'], POINTER(c_int), 'propertyCount' )), ] ################################################################ -## code template for IUIAutomationExpandCollapsePattern implementation -##class IUIAutomationExpandCollapsePattern_Impl(object): +## code template for IUIAutomationStylesPattern implementation +##class IUIAutomationStylesPattern_Impl(object): ## @property -## def CachedExpandCollapseState(self): +## def CurrentStyleId(self): ## '-no docstring-' ## #return retVal ## -## def Collapse(self): +## @property +## def CurrentStyleName(self): ## '-no docstring-' -## #return +## #return retVal ## -## def Expand(self): +## @property +## def CurrentFillColor(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CurrentFillPatternStyle(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CurrentShape(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CurrentFillPatternColor(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CurrentExtendedProperties(self): +## '-no docstring-' +## #return retVal +## +## def GetCurrentExtendedPropertiesAsArray(self): +## '-no docstring-' +## #return propertyArray, propertyCount +## +## @property +## def CachedStyleId(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CachedStyleName(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CachedFillColor(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CachedFillPatternStyle(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CachedShape(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CachedFillPatternColor(self): +## '-no docstring-' +## #return retVal +## +## @property +## def CachedExtendedProperties(self): +## '-no docstring-' +## #return retVal +## +## def GetCachedExtendedPropertiesAsArray(self): +## '-no docstring-' +## #return propertyArray, propertyCount +## + +UIA_ScrollHorizontallyScrollablePropertyId = 30057 # Constant c_int +UIA_ScrollVerticallyScrollablePropertyId = 30058 # Constant c_int +IAccessible._methods_ = [ + COMMETHOD([dispid(-5000), 'hidden', 'propget'], HRESULT, 'accParent', + ( ['out', 'retval'], POINTER(POINTER(IDispatch)), 'ppdispParent' )), + COMMETHOD([dispid(-5001), 'hidden', 'propget'], HRESULT, 'accChildCount', + ( ['out', 'retval'], POINTER(c_int), 'pcountChildren' )), + COMMETHOD([dispid(-5002), 'hidden', 'propget'], HRESULT, 'accChild', + ( ['in'], VARIANT, 'varChild' ), + ( ['out', 'retval'], POINTER(POINTER(IDispatch)), 'ppdispChild' )), + COMMETHOD([dispid(-5003), 'hidden', 'propget'], HRESULT, 'accName', + ( ['in', 'optional'], VARIANT, 'varChild' ), + ( ['out', 'retval'], POINTER(BSTR), 'pszName' )), + COMMETHOD([dispid(-5004), 'hidden', 'propget'], HRESULT, 'accValue', + ( ['in', 'optional'], VARIANT, 'varChild' ), + ( ['out', 'retval'], POINTER(BSTR), 'pszValue' )), + COMMETHOD([dispid(-5005), 'hidden', 'propget'], HRESULT, 'accDescription', + ( ['in', 'optional'], VARIANT, 'varChild' ), + ( ['out', 'retval'], POINTER(BSTR), 'pszDescription' )), + COMMETHOD([dispid(-5006), 'hidden', 'propget'], HRESULT, 'accRole', + ( ['in', 'optional'], VARIANT, 'varChild' ), + ( ['out', 'retval'], POINTER(VARIANT), 'pvarRole' )), + COMMETHOD([dispid(-5007), 'hidden', 'propget'], HRESULT, 'accState', + ( ['in', 'optional'], VARIANT, 'varChild' ), + ( ['out', 'retval'], POINTER(VARIANT), 'pvarState' )), + COMMETHOD([dispid(-5008), 'hidden', 'propget'], HRESULT, 'accHelp', + ( ['in', 'optional'], VARIANT, 'varChild' ), + ( ['out', 'retval'], POINTER(BSTR), 'pszHelp' )), + COMMETHOD([dispid(-5009), 'hidden', 'propget'], HRESULT, 'accHelpTopic', + ( ['out'], POINTER(BSTR), 'pszHelpFile' ), + ( ['in', 'optional'], VARIANT, 'varChild' ), + ( ['out', 'retval'], POINTER(c_int), 'pidTopic' )), + COMMETHOD([dispid(-5010), 'hidden', 'propget'], HRESULT, 'accKeyboardShortcut', + ( ['in', 'optional'], VARIANT, 'varChild' ), + ( ['out', 'retval'], POINTER(BSTR), 'pszKeyboardShortcut' )), + COMMETHOD([dispid(-5011), 'hidden', 'propget'], HRESULT, 'accFocus', + ( ['out', 'retval'], POINTER(VARIANT), 'pvarChild' )), + COMMETHOD([dispid(-5012), 'hidden', 'propget'], HRESULT, 'accSelection', + ( ['out', 'retval'], POINTER(VARIANT), 'pvarChildren' )), + COMMETHOD([dispid(-5013), 'hidden', 'propget'], HRESULT, 'accDefaultAction', + ( ['in', 'optional'], VARIANT, 'varChild' ), + ( ['out', 'retval'], POINTER(BSTR), 'pszDefaultAction' )), + COMMETHOD([dispid(-5014), 'hidden'], HRESULT, 'accSelect', + ( ['in'], c_int, 'flagsSelect' ), + ( ['in', 'optional'], VARIANT, 'varChild' )), + COMMETHOD([dispid(-5015), 'hidden'], HRESULT, 'accLocation', + ( ['out'], POINTER(c_int), 'pxLeft' ), + ( ['out'], POINTER(c_int), 'pyTop' ), + ( ['out'], POINTER(c_int), 'pcxWidth' ), + ( ['out'], POINTER(c_int), 'pcyHeight' ), + ( ['in', 'optional'], VARIANT, 'varChild' )), + COMMETHOD([dispid(-5016), 'hidden'], HRESULT, 'accNavigate', + ( ['in'], c_int, 'navDir' ), + ( ['in', 'optional'], VARIANT, 'varStart' ), + ( ['out', 'retval'], POINTER(VARIANT), 'pvarEndUpAt' )), + COMMETHOD([dispid(-5017), 'hidden'], HRESULT, 'accHitTest', + ( ['in'], c_int, 'xLeft' ), + ( ['in'], c_int, 'yTop' ), + ( ['out', 'retval'], POINTER(VARIANT), 'pvarChild' )), + COMMETHOD([dispid(-5018), 'hidden'], HRESULT, 'accDoDefaultAction', + ( ['in', 'optional'], VARIANT, 'varChild' )), + COMMETHOD([dispid(-5003), 'hidden', 'propput'], HRESULT, 'accName', + ( ['in', 'optional'], VARIANT, 'varChild' ), + ( ['in'], BSTR, 'pszName' )), + COMMETHOD([dispid(-5004), 'hidden', 'propput'], HRESULT, 'accValue', + ( ['in', 'optional'], VARIANT, 'varChild' ), + ( ['in'], BSTR, 'pszValue' )), +] +################################################################ +## code template for IAccessible implementation +##class IAccessible_Impl(object): +## @property +## def accParent(self): ## '-no docstring-' -## #return +## #return ppdispParent ## ## @property -## def CurrentExpandCollapseState(self): +## def accChildCount(self): ## '-no docstring-' -## #return retVal +## #return pcountChildren ## - -class IUIAutomationAnnotationPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{9A175B21-339E-41B1-8E8B-623F6B681098}') - _idlflags_ = [] -IUIAutomationAnnotationPattern._methods_ = [ - COMMETHOD(['propget'], HRESULT, 'CurrentAnnotationTypeId', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentAnnotationTypeName', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentAuthor', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentDateTime', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentTarget', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedAnnotationTypeId', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedAnnotationTypeName', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedAuthor', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedDateTime', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedTarget', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), -] -################################################################ -## code template for IUIAutomationAnnotationPattern implementation -##class IUIAutomationAnnotationPattern_Impl(object): ## @property -## def CachedTarget(self): +## def accChild(self, varChild): ## '-no docstring-' -## #return retVal +## #return ppdispChild ## -## @property -## def CachedAuthor(self): +## def _get(self, varChild): ## '-no docstring-' -## #return retVal +## #return pszName +## def _set(self, varChild, pszName): +## '-no docstring-' +## accName = property(_get, _set, doc = _set.__doc__) +## +## def _get(self, varChild): +## '-no docstring-' +## #return pszValue +## def _set(self, varChild, pszValue): +## '-no docstring-' +## accValue = property(_get, _set, doc = _set.__doc__) ## ## @property -## def CachedAnnotationTypeId(self): +## def accDescription(self, varChild): ## '-no docstring-' -## #return retVal +## #return pszDescription ## ## @property -## def CurrentAnnotationTypeName(self): +## def accRole(self, varChild): ## '-no docstring-' -## #return retVal +## #return pvarRole ## ## @property -## def CurrentAuthor(self): +## def accState(self, varChild): ## '-no docstring-' -## #return retVal +## #return pvarState ## ## @property -## def CachedAnnotationTypeName(self): +## def accHelp(self, varChild): ## '-no docstring-' -## #return retVal +## #return pszHelp ## ## @property -## def CachedDateTime(self): +## def accHelpTopic(self, varChild): ## '-no docstring-' -## #return retVal +## #return pszHelpFile, pidTopic ## ## @property -## def CurrentTarget(self): +## def accKeyboardShortcut(self, varChild): ## '-no docstring-' -## #return retVal +## #return pszKeyboardShortcut ## ## @property -## def CurrentAnnotationTypeId(self): +## def accFocus(self): ## '-no docstring-' -## #return retVal +## #return pvarChild ## ## @property -## def CurrentDateTime(self): +## def accSelection(self): ## '-no docstring-' -## #return retVal +## #return pvarChildren ## - -UIA_ForegroundColorAttributeId = 40008 # Constant c_int -UIA_FlowsFromPropertyId = 30148 # Constant c_int -UIA_FullDescriptionPropertyId = 30159 # Constant c_int -class ExtendedProperty(Structure): - pass -ExtendedProperty._fields_ = [ - ('PropertyName', BSTR), - ('PropertyValue', BSTR), -] -assert sizeof(ExtendedProperty) == 8, sizeof(ExtendedProperty) -assert alignment(ExtendedProperty) == 4, alignment(ExtendedProperty) -IUIAutomationElementArray._methods_ = [ - COMMETHOD(['propget'], HRESULT, 'Length', - ( ['retval', 'out'], POINTER(c_int), 'Length' )), - COMMETHOD([], HRESULT, 'GetElement', - ( ['in'], c_int, 'index' ), - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'element' )), -] -################################################################ -## code template for IUIAutomationElementArray implementation -##class IUIAutomationElementArray_Impl(object): ## @property -## def Length(self): +## def accDefaultAction(self, varChild): ## '-no docstring-' -## #return Length +## #return pszDefaultAction ## -## def GetElement(self, index): +## def accSelect(self, flagsSelect, varChild): ## '-no docstring-' -## #return element +## #return ## - -UIA_Drag_DragCancelEventId = 20027 # Constant c_int -UIA_ToolBarControlTypeId = 50021 # Constant c_int -StyleId_Heading2 = 70002 # Constant c_int -class IUIAutomationStylesPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{85B5F0A2-BD79-484A-AD2B-388C9838D5FB}') - _idlflags_ = [] -IUIAutomationStylesPattern._methods_ = [ - COMMETHOD(['propget'], HRESULT, 'CurrentStyleId', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentStyleName', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentFillColor', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentFillPatternStyle', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentShape', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentFillPatternColor', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentExtendedProperties', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD([], HRESULT, 'GetCurrentExtendedPropertiesAsArray', - ( ['out'], POINTER(POINTER(ExtendedProperty)), 'propertyArray' ), - ( ['out'], POINTER(c_int), 'propertyCount' )), - COMMETHOD(['propget'], HRESULT, 'CachedStyleId', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedStyleName', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedFillColor', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedFillPatternStyle', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedShape', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedFillPatternColor', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedExtendedProperties', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD([], HRESULT, 'GetCachedExtendedPropertiesAsArray', - ( ['out'], POINTER(POINTER(ExtendedProperty)), 'propertyArray' ), - ( ['out'], POINTER(c_int), 'propertyCount' )), -] -################################################################ -## code template for IUIAutomationStylesPattern implementation -##class IUIAutomationStylesPattern_Impl(object): -## @property -## def CurrentFillPatternColor(self): +## def accLocation(self, varChild): ## '-no docstring-' -## #return retVal +## #return pxLeft, pyTop, pcxWidth, pcyHeight ## -## @property -## def CachedStyleName(self): +## def accNavigate(self, navDir, varStart): ## '-no docstring-' -## #return retVal +## #return pvarEndUpAt ## -## @property -## def CachedFillPatternColor(self): +## def accHitTest(self, xLeft, yTop): ## '-no docstring-' -## #return retVal +## #return pvarChild ## -## @property -## def CurrentFillColor(self): +## def accDoDefaultAction(self, varChild): ## '-no docstring-' -## #return retVal +## #return ## -## @property -## def CurrentFillPatternStyle(self): + +UIA_SelectionSelectionPropertyId = 30059 # Constant c_int +UIA_SelectionCanSelectMultiplePropertyId = 30060 # Constant c_int +UIA_SelectionIsSelectionRequiredPropertyId = 30061 # Constant c_int +UIA_GridRowCountPropertyId = 30062 # Constant c_int +UIA_GridColumnCountPropertyId = 30063 # Constant c_int +UIA_GridItemRowPropertyId = 30064 # Constant c_int +UIA_GridItemColumnPropertyId = 30065 # Constant c_int +UIA_GridItemRowSpanPropertyId = 30066 # Constant c_int +UIA_GridItemColumnSpanPropertyId = 30067 # Constant c_int +UIA_GridItemContainingGridPropertyId = 30068 # Constant c_int +UIA_DockDockPositionPropertyId = 30069 # Constant c_int +UIA_ExpandCollapseExpandCollapseStatePropertyId = 30070 # Constant c_int +IUIAutomationPropertyChangedEventHandler._methods_ = [ + COMMETHOD([], HRESULT, 'HandlePropertyChangedEvent', + ( ['in'], POINTER(IUIAutomationElement), 'sender' ), + ( ['in'], c_int, 'propertyId' ), + ( ['in'], VARIANT, 'newValue' )), +] +################################################################ +## code template for IUIAutomationPropertyChangedEventHandler implementation +##class IUIAutomationPropertyChangedEventHandler_Impl(object): +## def HandlePropertyChangedEvent(self, sender, propertyId, newValue): ## '-no docstring-' -## #return retVal +## #return ## -## @property -## def CurrentStyleId(self): + +UIA_MultipleViewCurrentViewPropertyId = 30071 # Constant c_int +UIA_MultipleViewSupportedViewsPropertyId = 30072 # Constant c_int +UIA_WindowCanMaximizePropertyId = 30073 # Constant c_int +UIA_WindowCanMinimizePropertyId = 30074 # Constant c_int +UIA_WindowWindowVisualStatePropertyId = 30075 # Constant c_int +UIA_WindowWindowInteractionStatePropertyId = 30076 # Constant c_int +UIA_WindowIsModalPropertyId = 30077 # Constant c_int +UIA_WindowIsTopmostPropertyId = 30078 # Constant c_int +UIA_SelectionItemIsSelectedPropertyId = 30079 # Constant c_int + +# values for enumeration 'StructureChangeType' +StructureChangeType_ChildAdded = 0 +StructureChangeType_ChildRemoved = 1 +StructureChangeType_ChildrenInvalidated = 2 +StructureChangeType_ChildrenBulkAdded = 3 +StructureChangeType_ChildrenBulkRemoved = 4 +StructureChangeType_ChildrenReordered = 5 +StructureChangeType = c_int # enum +IUIAutomationStructureChangedEventHandler._methods_ = [ + COMMETHOD([], HRESULT, 'HandleStructureChangedEvent', + ( ['in'], POINTER(IUIAutomationElement), 'sender' ), + ( ['in'], StructureChangeType, 'changeType' ), + ( ['in'], _midlSAFEARRAY(c_int), 'runtimeId' )), +] +################################################################ +## code template for IUIAutomationStructureChangedEventHandler implementation +##class IUIAutomationStructureChangedEventHandler_Impl(object): +## def HandleStructureChangedEvent(self, sender, changeType, runtimeId): ## '-no docstring-' -## #return retVal +## #return ## -## @property -## def CurrentShape(self): + +UIA_SelectionItemSelectionContainerPropertyId = 30080 # Constant c_int +UIA_TableRowHeadersPropertyId = 30081 # Constant c_int +UIA_TableColumnHeadersPropertyId = 30082 # Constant c_int +UIA_TableRowOrColumnMajorPropertyId = 30083 # Constant c_int +UIA_TableItemRowHeaderItemsPropertyId = 30084 # Constant c_int +UIA_TableItemColumnHeaderItemsPropertyId = 30085 # Constant c_int +UIA_ToggleToggleStatePropertyId = 30086 # Constant c_int +UIA_TransformCanMovePropertyId = 30087 # Constant c_int +UIA_TransformCanResizePropertyId = 30088 # Constant c_int +UIA_TransformCanRotatePropertyId = 30089 # Constant c_int +UIA_IsLegacyIAccessiblePatternAvailablePropertyId = 30090 # Constant c_int +UIA_LegacyIAccessibleChildIdPropertyId = 30091 # Constant c_int +UIA_LegacyIAccessibleNamePropertyId = 30092 # Constant c_int +UIA_LegacyIAccessibleValuePropertyId = 30093 # Constant c_int +UIA_LegacyIAccessibleDescriptionPropertyId = 30094 # Constant c_int +UIA_LegacyIAccessibleRolePropertyId = 30095 # Constant c_int +UIA_LegacyIAccessibleStatePropertyId = 30096 # Constant c_int +IUIAutomationFocusChangedEventHandler._methods_ = [ + COMMETHOD([], HRESULT, 'HandleFocusChangedEvent', + ( ['in'], POINTER(IUIAutomationElement), 'sender' )), +] +################################################################ +## code template for IUIAutomationFocusChangedEventHandler implementation +##class IUIAutomationFocusChangedEventHandler_Impl(object): +## def HandleFocusChangedEvent(self, sender): ## '-no docstring-' -## #return retVal +## #return ## -## def GetCachedExtendedPropertiesAsArray(self): + +UIA_LegacyIAccessibleHelpPropertyId = 30097 # Constant c_int +UIA_LegacyIAccessibleKeyboardShortcutPropertyId = 30098 # Constant c_int +UIA_LegacyIAccessibleSelectionPropertyId = 30099 # Constant c_int +ExtendedProperty._fields_ = [ + ('PropertyName', BSTR), + ('PropertyValue', BSTR), +] +assert sizeof(ExtendedProperty) == 8, sizeof(ExtendedProperty) +assert alignment(ExtendedProperty) == 4, alignment(ExtendedProperty) +UIA_LegacyIAccessibleDefaultActionPropertyId = 30100 # Constant c_int +UIA_AriaRolePropertyId = 30101 # Constant c_int +UIA_AriaPropertiesPropertyId = 30102 # Constant c_int +UIA_IsDataValidForFormPropertyId = 30103 # Constant c_int +UIA_ControllerForPropertyId = 30104 # Constant c_int +UIA_DescribedByPropertyId = 30105 # Constant c_int +UIA_FlowsToPropertyId = 30106 # Constant c_int +IUIAutomationTextEditTextChangedEventHandler._methods_ = [ + COMMETHOD([], HRESULT, 'HandleTextEditTextChangedEvent', + ( ['in'], POINTER(IUIAutomationElement), 'sender' ), + ( ['in'], TextEditChangeType, 'TextEditChangeType' ), + ( ['in'], _midlSAFEARRAY(BSTR), 'eventStrings' )), +] +################################################################ +## code template for IUIAutomationTextEditTextChangedEventHandler implementation +##class IUIAutomationTextEditTextChangedEventHandler_Impl(object): +## def HandleTextEditTextChangedEvent(self, sender, TextEditChangeType, eventStrings): ## '-no docstring-' -## #return propertyArray, propertyCount +## #return ## -## @property -## def CachedExtendedProperties(self): + +UIA_ProviderDescriptionPropertyId = 30107 # Constant c_int +UIA_IsItemContainerPatternAvailablePropertyId = 30108 # Constant c_int +UIA_IsVirtualizedItemPatternAvailablePropertyId = 30109 # Constant c_int +UIA_IsSynchronizedInputPatternAvailablePropertyId = 30110 # Constant c_int +UIA_OptimizeForVisualContentPropertyId = 30111 # Constant c_int +UIA_IsObjectModelPatternAvailablePropertyId = 30112 # Constant c_int +UIA_AnnotationAnnotationTypeIdPropertyId = 30113 # Constant c_int +UIA_AnnotationAnnotationTypeNamePropertyId = 30114 # Constant c_int +UIA_AnnotationAuthorPropertyId = 30115 # Constant c_int +UIA_AnnotationDateTimePropertyId = 30116 # Constant c_int +class IUIAutomationSpreadsheetPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{7517A7C8-FAAE-4DE9-9F08-29B91E8595C1}') + _idlflags_ = [] +IUIAutomationSpreadsheetPattern._methods_ = [ + COMMETHOD([], HRESULT, 'GetItemByName', + ( ['in'], BSTR, 'name' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'element' )), +] +################################################################ +## code template for IUIAutomationSpreadsheetPattern implementation +##class IUIAutomationSpreadsheetPattern_Impl(object): +## def GetItemByName(self, name): ## '-no docstring-' -## #return retVal +## #return element ## + +UIA_AnnotationTargetPropertyId = 30117 # Constant c_int +UIA_IsAnnotationPatternAvailablePropertyId = 30118 # Constant c_int +UIA_IsTextPattern2AvailablePropertyId = 30119 # Constant c_int +UIA_StylesStyleIdPropertyId = 30120 # Constant c_int +UIA_StylesStyleNamePropertyId = 30121 # Constant c_int +UIA_StylesFillColorPropertyId = 30122 # Constant c_int +UIA_StylesFillPatternStylePropertyId = 30123 # Constant c_int +UIA_StylesShapePropertyId = 30124 # Constant c_int +class IUIAutomationSpreadsheetItemPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{7D4FB86C-8D34-40E1-8E83-62C15204E335}') + _idlflags_ = [] +IUIAutomationSpreadsheetItemPattern._methods_ = [ + COMMETHOD(['propget'], HRESULT, 'CurrentFormula', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD([], HRESULT, 'GetCurrentAnnotationObjects', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), + COMMETHOD([], HRESULT, 'GetCurrentAnnotationTypes', + ( ['out', 'retval'], POINTER(_midlSAFEARRAY(c_int)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedFormula', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD([], HRESULT, 'GetCachedAnnotationObjects', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), + COMMETHOD([], HRESULT, 'GetCachedAnnotationTypes', + ( ['out', 'retval'], POINTER(_midlSAFEARRAY(c_int)), 'retVal' )), +] +################################################################ +## code template for IUIAutomationSpreadsheetItemPattern implementation +##class IUIAutomationSpreadsheetItemPattern_Impl(object): ## @property -## def CachedFillPatternStyle(self): +## def CurrentFormula(self): ## '-no docstring-' ## #return retVal ## -## @property -## def CachedShape(self): +## def GetCurrentAnnotationObjects(self): ## '-no docstring-' ## #return retVal ## -## @property -## def CurrentStyleName(self): +## def GetCurrentAnnotationTypes(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedStyleId(self): +## def CachedFormula(self): ## '-no docstring-' ## #return retVal ## -## @property -## def CachedFillColor(self): +## def GetCachedAnnotationObjects(self): ## '-no docstring-' ## #return retVal ## -## @property -## def CurrentExtendedProperties(self): +## def GetCachedAnnotationTypes(self): ## '-no docstring-' ## #return retVal ## -## def GetCurrentExtendedPropertiesAsArray(self): -## '-no docstring-' -## #return propertyArray, propertyCount -## -UIA_OutlineColorPropertyId = 30161 # Constant c_int -StyleId_Heading4 = 70004 # Constant c_int -class IUIAutomationLegacyIAccessiblePattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): +UIA_StylesFillPatternColorPropertyId = 30125 # Constant c_int +UIA_StylesExtendedPropertiesPropertyId = 30126 # Constant c_int +UIA_IsStylesPatternAvailablePropertyId = 30127 # Constant c_int +UIA_IsSpreadsheetPatternAvailablePropertyId = 30128 # Constant c_int +UIA_SpreadsheetItemFormulaPropertyId = 30129 # Constant c_int +UIA_SpreadsheetItemAnnotationObjectsPropertyId = 30130 # Constant c_int +class IUIAutomationItemContainerPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): _case_insensitive_ = True - _iid_ = GUID('{828055AD-355B-4435-86D5-3B51C14A9B1B}') + _iid_ = GUID('{C690FDB2-27A8-423C-812D-429773C9084E}') _idlflags_ = [] -IUIAutomationLegacyIAccessiblePattern._methods_ = [ - COMMETHOD([], HRESULT, 'Select', - ( [], c_int, 'flagsSelect' )), - COMMETHOD([], HRESULT, 'DoDefaultAction'), - COMMETHOD([], HRESULT, 'SetValue', - ( [], WSTRING, 'szValue' )), - COMMETHOD(['propget'], HRESULT, 'CurrentChildId', - ( ['retval', 'out'], POINTER(c_int), 'pRetVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentName', - ( ['retval', 'out'], POINTER(BSTR), 'pszName' )), - COMMETHOD(['propget'], HRESULT, 'CurrentValue', - ( ['retval', 'out'], POINTER(BSTR), 'pszValue' )), - COMMETHOD(['propget'], HRESULT, 'CurrentDescription', - ( ['retval', 'out'], POINTER(BSTR), 'pszDescription' )), - COMMETHOD(['propget'], HRESULT, 'CurrentRole', - ( ['retval', 'out'], POINTER(c_ulong), 'pdwRole' )), - COMMETHOD(['propget'], HRESULT, 'CurrentState', - ( ['retval', 'out'], POINTER(c_ulong), 'pdwState' )), - COMMETHOD(['propget'], HRESULT, 'CurrentHelp', - ( ['retval', 'out'], POINTER(BSTR), 'pszHelp' )), - COMMETHOD(['propget'], HRESULT, 'CurrentKeyboardShortcut', - ( ['retval', 'out'], POINTER(BSTR), 'pszKeyboardShortcut' )), - COMMETHOD([], HRESULT, 'GetCurrentSelection', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'pvarSelectedChildren' )), - COMMETHOD(['propget'], HRESULT, 'CurrentDefaultAction', - ( ['retval', 'out'], POINTER(BSTR), 'pszDefaultAction' )), - COMMETHOD(['propget'], HRESULT, 'CachedChildId', - ( ['retval', 'out'], POINTER(c_int), 'pRetVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedName', - ( ['retval', 'out'], POINTER(BSTR), 'pszName' )), - COMMETHOD(['propget'], HRESULT, 'CachedValue', - ( ['retval', 'out'], POINTER(BSTR), 'pszValue' )), - COMMETHOD(['propget'], HRESULT, 'CachedDescription', - ( ['retval', 'out'], POINTER(BSTR), 'pszDescription' )), - COMMETHOD(['propget'], HRESULT, 'CachedRole', - ( ['retval', 'out'], POINTER(c_ulong), 'pdwRole' )), - COMMETHOD(['propget'], HRESULT, 'CachedState', - ( ['retval', 'out'], POINTER(c_ulong), 'pdwState' )), - COMMETHOD(['propget'], HRESULT, 'CachedHelp', - ( ['retval', 'out'], POINTER(BSTR), 'pszHelp' )), - COMMETHOD(['propget'], HRESULT, 'CachedKeyboardShortcut', - ( ['retval', 'out'], POINTER(BSTR), 'pszKeyboardShortcut' )), - COMMETHOD([], HRESULT, 'GetCachedSelection', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'pvarSelectedChildren' )), - COMMETHOD(['propget'], HRESULT, 'CachedDefaultAction', - ( ['retval', 'out'], POINTER(BSTR), 'pszDefaultAction' )), - COMMETHOD([], HRESULT, 'GetIAccessible', - ( ['retval', 'out'], POINTER(POINTER(IAccessible)), 'ppAccessible' )), +IUIAutomationItemContainerPattern._methods_ = [ + COMMETHOD([], HRESULT, 'FindItemByProperty', + ( ['in'], POINTER(IUIAutomationElement), 'pStartAfter' ), + ( ['in'], c_int, 'propertyId' ), + ( ['in'], VARIANT, 'value' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'pFound' )), ] ################################################################ -## code template for IUIAutomationLegacyIAccessiblePattern implementation -##class IUIAutomationLegacyIAccessiblePattern_Impl(object): -## @property -## def CurrentDescription(self): -## '-no docstring-' -## #return pszDescription -## -## @property -## def CurrentHelp(self): -## '-no docstring-' -## #return pszHelp -## -## @property -## def CachedValue(self): -## '-no docstring-' -## #return pszValue -## -## def GetCachedSelection(self): -## '-no docstring-' -## #return pvarSelectedChildren -## -## @property -## def CurrentState(self): -## '-no docstring-' -## #return pdwState -## -## @property -## def CurrentValue(self): -## '-no docstring-' -## #return pszValue -## -## @property -## def CachedName(self): -## '-no docstring-' -## #return pszName -## -## @property -## def CurrentName(self): -## '-no docstring-' -## #return pszName -## -## @property -## def CachedDescription(self): -## '-no docstring-' -## #return pszDescription -## -## def GetIAccessible(self): -## '-no docstring-' -## #return ppAccessible -## -## @property -## def CachedRole(self): -## '-no docstring-' -## #return pdwRole -## -## @property -## def CurrentChildId(self): -## '-no docstring-' -## #return pRetVal -## -## def DoDefaultAction(self): -## '-no docstring-' -## #return -## -## @property -## def CachedChildId(self): -## '-no docstring-' -## #return pRetVal -## -## @property -## def CachedHelp(self): -## '-no docstring-' -## #return pszHelp -## -## @property -## def CurrentRole(self): -## '-no docstring-' -## #return pdwRole -## -## def SetValue(self, szValue): +## code template for IUIAutomationItemContainerPattern implementation +##class IUIAutomationItemContainerPattern_Impl(object): +## def FindItemByProperty(self, pStartAfter, propertyId, value): ## '-no docstring-' -## #return +## #return pFound ## -## def GetCurrentSelection(self): + +UIA_SpreadsheetItemAnnotationTypesPropertyId = 30131 # Constant c_int +UIA_IsSpreadsheetItemPatternAvailablePropertyId = 30132 # Constant c_int +UIA_Transform2CanZoomPropertyId = 30133 # Constant c_int +UIA_IsTransformPattern2AvailablePropertyId = 30134 # Constant c_int + +# values for enumeration 'NotificationKind' +NotificationKind_ItemAdded = 0 +NotificationKind_ItemRemoved = 1 +NotificationKind_ActionCompleted = 2 +NotificationKind_ActionAborted = 3 +NotificationKind_Other = 4 +NotificationKind = c_int # enum + +# values for enumeration 'NotificationProcessing' +NotificationProcessing_ImportantAll = 0 +NotificationProcessing_ImportantMostRecent = 1 +NotificationProcessing_All = 2 +NotificationProcessing_MostRecent = 3 +NotificationProcessing_CurrentThenMostRecent = 4 +NotificationProcessing = c_int # enum +IUIAutomationNotificationEventHandler._methods_ = [ + COMMETHOD([], HRESULT, 'HandleNotificationEvent', + ( ['in'], POINTER(IUIAutomationElement), 'sender' ), + ( [], NotificationKind, 'NotificationKind' ), + ( [], NotificationProcessing, 'NotificationProcessing' ), + ( ['in'], BSTR, 'displayString' ), + ( ['in'], BSTR, 'activityId' )), +] +################################################################ +## code template for IUIAutomationNotificationEventHandler implementation +##class IUIAutomationNotificationEventHandler_Impl(object): +## def HandleNotificationEvent(self, sender, NotificationKind, NotificationProcessing, displayString, activityId): ## '-no docstring-' -## #return pvarSelectedChildren +## #return ## -## @property -## def CachedDefaultAction(self): + +UIA_LiveSettingPropertyId = 30135 # Constant c_int +UIA_IsTextChildPatternAvailablePropertyId = 30136 # Constant c_int +UiaChangeInfo._fields_ = [ + ('uiaId', c_int), + ('payload', VARIANT), + ('extraInfo', VARIANT), +] +assert sizeof(UiaChangeInfo) == 40, sizeof(UiaChangeInfo) +assert alignment(UiaChangeInfo) == 8, alignment(UiaChangeInfo) +UIA_IsDragPatternAvailablePropertyId = 30137 # Constant c_int +class IUIAutomationVirtualizedItemPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{6BA3D7A6-04CF-4F11-8793-A8D1CDE9969F}') + _idlflags_ = [] +IUIAutomationVirtualizedItemPattern._methods_ = [ + COMMETHOD([], HRESULT, 'Realize'), +] +################################################################ +## code template for IUIAutomationVirtualizedItemPattern implementation +##class IUIAutomationVirtualizedItemPattern_Impl(object): +## def Realize(self): ## '-no docstring-' -## #return pszDefaultAction +## #return ## -## @property -## def CachedState(self): + +UIA_DragIsGrabbedPropertyId = 30138 # Constant c_int +UIA_DragDropEffectPropertyId = 30139 # Constant c_int +UIA_DragDropEffectsPropertyId = 30140 # Constant c_int +UIA_IsDropTargetPatternAvailablePropertyId = 30141 # Constant c_int +UIA_DropTargetDropTargetEffectPropertyId = 30142 # Constant c_int +UIA_DropTargetDropTargetEffectsPropertyId = 30143 # Constant c_int +UIA_DragGrabbedItemsPropertyId = 30144 # Constant c_int +UIA_Transform2ZoomLevelPropertyId = 30145 # Constant c_int +UIA_Transform2ZoomMinimumPropertyId = 30146 # Constant c_int +class IUIAutomationInvokePattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{FB377FBE-8EA6-46D5-9C73-6499642D3059}') + _idlflags_ = [] +IUIAutomationInvokePattern._methods_ = [ + COMMETHOD([], HRESULT, 'Invoke'), +] +################################################################ +## code template for IUIAutomationInvokePattern implementation +##class IUIAutomationInvokePattern_Impl(object): +## def Invoke(self): ## '-no docstring-' -## #return pdwState +## #return ## -## @property -## def CurrentDefaultAction(self): + +UIA_Transform2ZoomMaximumPropertyId = 30147 # Constant c_int +UIA_FlowsFromPropertyId = 30148 # Constant c_int +UIA_IsTextEditPatternAvailablePropertyId = 30149 # Constant c_int +UIA_IsPeripheralPropertyId = 30150 # Constant c_int +class IUIAutomationDockPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): + _case_insensitive_ = True + _iid_ = GUID('{FDE5EF97-1464-48F6-90BF-43D0948E86EC}') + _idlflags_ = [] +IUIAutomationDockPattern._methods_ = [ + COMMETHOD([], HRESULT, 'SetDockPosition', + ( ['in'], DockPosition, 'dockPos' )), + COMMETHOD(['propget'], HRESULT, 'CurrentDockPosition', + ( ['out', 'retval'], POINTER(DockPosition), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedDockPosition', + ( ['out', 'retval'], POINTER(DockPosition), 'retVal' )), +] +################################################################ +## code template for IUIAutomationDockPattern implementation +##class IUIAutomationDockPattern_Impl(object): +## def SetDockPosition(self, dockPos): ## '-no docstring-' -## #return pszDefaultAction +## #return ## ## @property -## def CachedKeyboardShortcut(self): -## '-no docstring-' -## #return pszKeyboardShortcut -## -## def Select(self, flagsSelect): +## def CurrentDockPosition(self): ## '-no docstring-' -## #return +## #return retVal ## ## @property -## def CurrentKeyboardShortcut(self): +## def CachedDockPosition(self): ## '-no docstring-' -## #return pszKeyboardShortcut +## #return retVal ## +UIA_IsCustomNavigationPatternAvailablePropertyId = 30151 # Constant c_int +UIA_PositionInSetPropertyId = 30152 # Constant c_int +UIA_SizeOfSetPropertyId = 30153 # Constant c_int +UIA_LevelPropertyId = 30154 # Constant c_int +UIA_AnnotationTypesPropertyId = 30155 # Constant c_int +class IUIAutomationTransformPattern2(IUIAutomationTransformPattern): + _case_insensitive_ = True + _iid_ = GUID('{6D74D017-6ECB-4381-B38B-3C17A48FF1C2}') + _idlflags_ = [] -# values for enumeration 'AutomationElementMode' -AutomationElementMode_None = 0 -AutomationElementMode_Full = 1 -AutomationElementMode = c_int # enum -IUIAutomationCacheRequest._methods_ = [ - COMMETHOD([], HRESULT, 'AddProperty', - ( ['in'], c_int, 'propertyId' )), - COMMETHOD([], HRESULT, 'AddPattern', - ( ['in'], c_int, 'patternId' )), - COMMETHOD([], HRESULT, 'Clone', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationCacheRequest)), 'clonedRequest' )), - COMMETHOD(['propget'], HRESULT, 'TreeScope', - ( ['retval', 'out'], POINTER(TreeScope), 'scope' )), - COMMETHOD(['propput'], HRESULT, 'TreeScope', - ( ['in'], TreeScope, 'scope' )), - COMMETHOD(['propget'], HRESULT, 'TreeFilter', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationCondition)), 'filter' )), - COMMETHOD(['propput'], HRESULT, 'TreeFilter', - ( ['in'], POINTER(IUIAutomationCondition), 'filter' )), - COMMETHOD(['propget'], HRESULT, 'AutomationElementMode', - ( ['retval', 'out'], POINTER(AutomationElementMode), 'mode' )), - COMMETHOD(['propput'], HRESULT, 'AutomationElementMode', - ( ['in'], AutomationElementMode, 'mode' )), +# values for enumeration 'ZoomUnit' +ZoomUnit_NoAmount = 0 +ZoomUnit_LargeDecrement = 1 +ZoomUnit_SmallDecrement = 2 +ZoomUnit_LargeIncrement = 3 +ZoomUnit_SmallIncrement = 4 +ZoomUnit = c_int # enum +IUIAutomationTransformPattern2._methods_ = [ + COMMETHOD([], HRESULT, 'Zoom', + ( ['in'], c_double, 'zoomValue' )), + COMMETHOD([], HRESULT, 'ZoomByUnit', + ( ['in'], ZoomUnit, 'ZoomUnit' )), + COMMETHOD(['propget'], HRESULT, 'CurrentCanZoom', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedCanZoom', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentZoomLevel', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedZoomLevel', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentZoomMinimum', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedZoomMinimum', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentZoomMaximum', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedZoomMaximum', + ( ['out', 'retval'], POINTER(c_double), 'retVal' )), ] ################################################################ -## code template for IUIAutomationCacheRequest implementation -##class IUIAutomationCacheRequest_Impl(object): -## def AddPattern(self, patternId): +## code template for IUIAutomationTransformPattern2 implementation +##class IUIAutomationTransformPattern2_Impl(object): +## def Zoom(self, zoomValue): ## '-no docstring-' ## #return ## -## def AddProperty(self, propertyId): +## def ZoomByUnit(self, ZoomUnit): ## '-no docstring-' ## #return ## -## def Clone(self): -## '-no docstring-' -## #return clonedRequest -## -## def _get(self): -## '-no docstring-' -## #return scope -## def _set(self, scope): -## '-no docstring-' -## TreeScope = property(_get, _set, doc = _set.__doc__) -## -## def _get(self): -## '-no docstring-' -## #return mode -## def _set(self, mode): +## @property +## def CurrentCanZoom(self): ## '-no docstring-' -## AutomationElementMode = property(_get, _set, doc = _set.__doc__) +## #return retVal ## -## def _get(self): -## '-no docstring-' -## #return filter -## def _set(self, filter): +## @property +## def CachedCanZoom(self): ## '-no docstring-' -## TreeFilter = property(_get, _set, doc = _set.__doc__) +## #return retVal ## - -class IUIAutomationSpreadsheetItemPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{7D4FB86C-8D34-40E1-8E83-62C15204E335}') - _idlflags_ = [] -IUIAutomationSpreadsheetItemPattern._methods_ = [ - COMMETHOD(['propget'], HRESULT, 'CurrentFormula', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD([], HRESULT, 'GetCurrentAnnotationObjects', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), - COMMETHOD([], HRESULT, 'GetCurrentAnnotationTypes', - ( ['retval', 'out'], POINTER(_midlSAFEARRAY(c_int)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedFormula', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD([], HRESULT, 'GetCachedAnnotationObjects', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), - COMMETHOD([], HRESULT, 'GetCachedAnnotationTypes', - ( ['retval', 'out'], POINTER(_midlSAFEARRAY(c_int)), 'retVal' )), -] -################################################################ -## code template for IUIAutomationSpreadsheetItemPattern implementation -##class IUIAutomationSpreadsheetItemPattern_Impl(object): ## @property -## def CurrentFormula(self): +## def CurrentZoomLevel(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedFormula(self): +## def CachedZoomLevel(self): ## '-no docstring-' ## #return retVal ## -## def GetCachedAnnotationTypes(self): +## @property +## def CurrentZoomMinimum(self): ## '-no docstring-' ## #return retVal ## -## def GetCurrentAnnotationTypes(self): +## @property +## def CachedZoomMinimum(self): ## '-no docstring-' ## #return retVal ## -## def GetCurrentAnnotationObjects(self): +## @property +## def CurrentZoomMaximum(self): ## '-no docstring-' ## #return retVal ## -## def GetCachedAnnotationObjects(self): +## @property +## def CachedZoomMaximum(self): ## '-no docstring-' ## #return retVal ## -UIA_BackgroundColorAttributeId = 40001 # Constant c_int -class CUIAutomation(CoClass): - u'The Central Class for UIAutomation' - _reg_clsid_ = GUID('{FF48DBA4-60EF-4201-AA87-54103EEF594E}') - _idlflags_ = [] - _typelib_path_ = typelib_path - _reg_typelib_ = ('{944DE083-8FB8-45CF-BCB7-C477ACB2F897}', 1, 0) -CUIAutomation._com_interfaces_ = [IUIAutomation] - -class IUIAutomationGridItemPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): +UIA_AnnotationObjectsPropertyId = 30156 # Constant c_int +UIA_LandmarkTypePropertyId = 30157 # Constant c_int +UIA_LocalizedLandmarkTypePropertyId = 30158 # Constant c_int +class IUIAutomationAnnotationPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): _case_insensitive_ = True - _iid_ = GUID('{78F8EF57-66C3-4E09-BD7C-E79B2004894D}') + _iid_ = GUID('{9A175B21-339E-41B1-8E8B-623F6B681098}') _idlflags_ = [] -IUIAutomationGridItemPattern._methods_ = [ - COMMETHOD(['propget'], HRESULT, 'CurrentContainingGrid', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentRow', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentColumn', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentRowSpan', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentColumnSpan', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedContainingGrid', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedRow', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedColumn', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedRowSpan', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedColumnSpan', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), +IUIAutomationAnnotationPattern._methods_ = [ + COMMETHOD(['propget'], HRESULT, 'CurrentAnnotationTypeId', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentAnnotationTypeName', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentAuthor', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentDateTime', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CurrentTarget', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedAnnotationTypeId', + ( ['out', 'retval'], POINTER(c_int), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedAnnotationTypeName', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedAuthor', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedDateTime', + ( ['out', 'retval'], POINTER(BSTR), 'retVal' )), + COMMETHOD(['propget'], HRESULT, 'CachedTarget', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'retVal' )), ] ################################################################ -## code template for IUIAutomationGridItemPattern implementation -##class IUIAutomationGridItemPattern_Impl(object): +## code template for IUIAutomationAnnotationPattern implementation +##class IUIAutomationAnnotationPattern_Impl(object): ## @property -## def CurrentColumn(self): +## def CurrentAnnotationTypeId(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentRow(self): +## def CurrentAnnotationTypeName(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedColumn(self): +## def CurrentAuthor(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentContainingGrid(self): +## def CurrentDateTime(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedRowSpan(self): +## def CurrentTarget(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedColumnSpan(self): +## def CachedAnnotationTypeId(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedContainingGrid(self): +## def CachedAnnotationTypeName(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentRowSpan(self): +## def CachedAuthor(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CurrentColumnSpan(self): +## def CachedDateTime(self): ## '-no docstring-' ## #return retVal ## ## @property -## def CachedRow(self): +## def CachedTarget(self): ## '-no docstring-' ## #return retVal ## -class IUIAutomationTextEditPattern(IUIAutomationTextPattern): +UIA_FullDescriptionPropertyId = 30159 # Constant c_int +UIA_FillColorPropertyId = 30160 # Constant c_int +UIA_OutlineColorPropertyId = 30161 # Constant c_int +UIA_FillTypePropertyId = 30162 # Constant c_int +UIA_VisualEffectsPropertyId = 30163 # Constant c_int +UIA_OutlineThicknessPropertyId = 30164 # Constant c_int +UIA_CenterPointPropertyId = 30165 # Constant c_int +UIA_RotationPropertyId = 30166 # Constant c_int +UIA_SizePropertyId = 30167 # Constant c_int +UIA_IsSelectionPattern2AvailablePropertyId = 30168 # Constant c_int +UIA_Selection2FirstSelectedItemPropertyId = 30169 # Constant c_int +UIA_Selection2LastSelectedItemPropertyId = 30170 # Constant c_int +UIA_Selection2CurrentSelectedItemPropertyId = 30171 # Constant c_int +UIA_Selection2ItemCountPropertyId = 30172 # Constant c_int +UIA_HeadingLevelPropertyId = 30173 # Constant c_int +UIA_IsDialogPropertyId = 30174 # Constant c_int +class IRawElementProviderSimple(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): _case_insensitive_ = True - _iid_ = GUID('{17E21576-996C-4870-99D9-BFF323380C06}') - _idlflags_ = [] -IUIAutomationTextEditPattern._methods_ = [ - COMMETHOD([], HRESULT, 'GetActiveComposition', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationTextRange)), 'range' )), - COMMETHOD([], HRESULT, 'GetConversionTarget', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationTextRange)), 'range' )), + _iid_ = GUID('{D6DD68D1-86FD-4332-8666-9ABEDEA2D24C}') + _idlflags_ = ['oleautomation'] +IUIAutomationProxyFactory._methods_ = [ + COMMETHOD([], HRESULT, 'CreateProvider', + ( ['in'], c_void_p, 'hwnd' ), + ( ['in'], c_int, 'idObject' ), + ( ['in'], c_int, 'idChild' ), + ( ['out', 'retval'], POINTER(POINTER(IRawElementProviderSimple)), 'provider' )), + COMMETHOD(['propget'], HRESULT, 'ProxyFactoryId', + ( ['out', 'retval'], POINTER(BSTR), 'factoryId' )), ] ################################################################ -## code template for IUIAutomationTextEditPattern implementation -##class IUIAutomationTextEditPattern_Impl(object): -## def GetActiveComposition(self): +## code template for IUIAutomationProxyFactory implementation +##class IUIAutomationProxyFactory_Impl(object): +## def CreateProvider(self, hwnd, idObject, idChild): ## '-no docstring-' -## #return range +## #return provider ## -## def GetConversionTarget(self): +## @property +## def ProxyFactoryId(self): ## '-no docstring-' -## #return range +## #return factoryId ## -StyleId_Heading7 = 70007 # Constant c_int -UIA_TextEdit_ConversionTargetChangedEventId = 20033 # Constant c_int -StyleId_Heading8 = 70008 # Constant c_int -StyleId_Heading9 = 70009 # Constant c_int -class IUIAutomationMultipleViewPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{8D253C91-1DC5-4BB5-B18F-ADE16FA495E8}') - _idlflags_ = [] -IUIAutomationMultipleViewPattern._methods_ = [ - COMMETHOD([], HRESULT, 'GetViewName', - ( ['in'], c_int, 'view' ), - ( ['retval', 'out'], POINTER(BSTR), 'name' )), - COMMETHOD([], HRESULT, 'SetCurrentView', - ( ['in'], c_int, 'view' )), - COMMETHOD(['propget'], HRESULT, 'CurrentCurrentView', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD([], HRESULT, 'GetCurrentSupportedViews', - ( ['retval', 'out'], POINTER(_midlSAFEARRAY(c_int)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedCurrentView', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD([], HRESULT, 'GetCachedSupportedViews', - ( ['retval', 'out'], POINTER(_midlSAFEARRAY(c_int)), 'retVal' )), + +# values for enumeration 'ProviderOptions' +ProviderOptions_ClientSideProvider = 1 +ProviderOptions_ServerSideProvider = 2 +ProviderOptions_NonClientAreaProvider = 4 +ProviderOptions_OverrideProvider = 8 +ProviderOptions_ProviderOwnsSetFocus = 16 +ProviderOptions_UseComThreading = 32 +ProviderOptions_RefuseNonClientSupport = 64 +ProviderOptions_HasNativeIAccessible = 128 +ProviderOptions_UseClientCoordinates = 256 +ProviderOptions = c_int # enum +IRawElementProviderSimple._methods_ = [ + COMMETHOD(['propget'], HRESULT, 'ProviderOptions', + ( ['out', 'retval'], POINTER(ProviderOptions), 'pRetVal' )), + COMMETHOD([], HRESULT, 'GetPatternProvider', + ( ['in'], c_int, 'patternId' ), + ( ['out', 'retval'], POINTER(POINTER(IUnknown)), 'pRetVal' )), + COMMETHOD([], HRESULT, 'GetPropertyValue', + ( ['in'], c_int, 'propertyId' ), + ( ['out', 'retval'], POINTER(VARIANT), 'pRetVal' )), + COMMETHOD(['propget'], HRESULT, 'HostRawElementProvider', + ( ['out', 'retval'], POINTER(POINTER(IRawElementProviderSimple)), 'pRetVal' )), ] ################################################################ -## code template for IUIAutomationMultipleViewPattern implementation -##class IUIAutomationMultipleViewPattern_Impl(object): -## def SetCurrentView(self, view): -## '-no docstring-' -## #return -## -## def GetCurrentSupportedViews(self): -## '-no docstring-' -## #return retVal -## -## def GetCachedSupportedViews(self): +## code template for IRawElementProviderSimple implementation +##class IRawElementProviderSimple_Impl(object): +## @property +## def ProviderOptions(self): ## '-no docstring-' -## #return retVal +## #return pRetVal ## -## @property -## def CurrentCurrentView(self): +## def GetPatternProvider(self, patternId): ## '-no docstring-' -## #return retVal +## #return pRetVal ## -## def GetViewName(self, view): +## def GetPropertyValue(self, propertyId): ## '-no docstring-' -## #return name +## #return pRetVal ## ## @property -## def CachedCurrentView(self): +## def HostRawElementProvider(self): ## '-no docstring-' -## #return retVal +## #return pRetVal ## -class IUIAutomationTransformPattern2(IUIAutomationTransformPattern): - _case_insensitive_ = True - _iid_ = GUID('{6D74D017-6ECB-4381-B38B-3C17A48FF1C2}') - _idlflags_ = [] - -# values for enumeration 'ZoomUnit' -ZoomUnit_NoAmount = 0 -ZoomUnit_LargeDecrement = 1 -ZoomUnit_SmallDecrement = 2 -ZoomUnit_LargeIncrement = 3 -ZoomUnit_SmallIncrement = 4 -ZoomUnit = c_int # enum -IUIAutomationTransformPattern2._methods_ = [ - COMMETHOD([], HRESULT, 'Zoom', - ( ['in'], c_double, 'zoomValue' )), - COMMETHOD([], HRESULT, 'ZoomByUnit', - ( ['in'], ZoomUnit, 'ZoomUnit' )), - COMMETHOD(['propget'], HRESULT, 'CurrentCanZoom', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedCanZoom', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentZoomLevel', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedZoomLevel', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentZoomMinimum', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedZoomMinimum', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentZoomMaximum', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedZoomMaximum', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), +IUIAutomationProxyFactoryEntry._methods_ = [ + COMMETHOD(['propget'], HRESULT, 'ProxyFactory', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationProxyFactory)), 'factory' )), + COMMETHOD(['propget'], HRESULT, 'ClassName', + ( ['out', 'retval'], POINTER(BSTR), 'ClassName' )), + COMMETHOD(['propget'], HRESULT, 'ImageName', + ( ['out', 'retval'], POINTER(BSTR), 'ImageName' )), + COMMETHOD(['propget'], HRESULT, 'AllowSubstringMatch', + ( ['out', 'retval'], POINTER(c_int), 'AllowSubstringMatch' )), + COMMETHOD(['propget'], HRESULT, 'CanCheckBaseClass', + ( ['out', 'retval'], POINTER(c_int), 'CanCheckBaseClass' )), + COMMETHOD(['propget'], HRESULT, 'NeedsAdviseEvents', + ( ['out', 'retval'], POINTER(c_int), 'adviseEvents' )), + COMMETHOD(['propput'], HRESULT, 'ClassName', + ( ['in'], WSTRING, 'ClassName' )), + COMMETHOD(['propput'], HRESULT, 'ImageName', + ( ['in'], WSTRING, 'ImageName' )), + COMMETHOD(['propput'], HRESULT, 'AllowSubstringMatch', + ( ['in'], c_int, 'AllowSubstringMatch' )), + COMMETHOD(['propput'], HRESULT, 'CanCheckBaseClass', + ( ['in'], c_int, 'CanCheckBaseClass' )), + COMMETHOD(['propput'], HRESULT, 'NeedsAdviseEvents', + ( ['in'], c_int, 'adviseEvents' )), + COMMETHOD([], HRESULT, 'SetWinEventsForAutomationEvent', + ( ['in'], c_int, 'eventId' ), + ( ['in'], c_int, 'propertyId' ), + ( ['in'], _midlSAFEARRAY(c_uint), 'winEvents' )), + COMMETHOD([], HRESULT, 'GetWinEventsForAutomationEvent', + ( ['in'], c_int, 'eventId' ), + ( ['in'], c_int, 'propertyId' ), + ( ['out', 'retval'], POINTER(_midlSAFEARRAY(c_uint)), 'winEvents' )), ] ################################################################ -## code template for IUIAutomationTransformPattern2 implementation -##class IUIAutomationTransformPattern2_Impl(object): +## code template for IUIAutomationProxyFactoryEntry implementation +##class IUIAutomationProxyFactoryEntry_Impl(object): ## @property -## def CachedZoomMinimum(self): +## def ProxyFactory(self): ## '-no docstring-' -## #return retVal +## #return factory ## -## @property -## def CurrentZoomMinimum(self): +## def _get(self): ## '-no docstring-' -## #return retVal +## #return ClassName +## def _set(self, ClassName): +## '-no docstring-' +## ClassName = property(_get, _set, doc = _set.__doc__) ## -## @property -## def CachedCanZoom(self): +## def _get(self): +## '-no docstring-' +## #return ImageName +## def _set(self, ImageName): +## '-no docstring-' +## ImageName = property(_get, _set, doc = _set.__doc__) +## +## def _get(self): +## '-no docstring-' +## #return AllowSubstringMatch +## def _set(self, AllowSubstringMatch): +## '-no docstring-' +## AllowSubstringMatch = property(_get, _set, doc = _set.__doc__) +## +## def _get(self): +## '-no docstring-' +## #return CanCheckBaseClass +## def _set(self, CanCheckBaseClass): +## '-no docstring-' +## CanCheckBaseClass = property(_get, _set, doc = _set.__doc__) +## +## def _get(self): +## '-no docstring-' +## #return adviseEvents +## def _set(self, adviseEvents): +## '-no docstring-' +## NeedsAdviseEvents = property(_get, _set, doc = _set.__doc__) +## +## def SetWinEventsForAutomationEvent(self, eventId, propertyId, winEvents): +## '-no docstring-' +## #return +## +## def GetWinEventsForAutomationEvent(self, eventId, propertyId): +## '-no docstring-' +## #return winEvents +## + +IUIAutomationTreeWalker._methods_ = [ + COMMETHOD([], HRESULT, 'GetParentElement', + ( ['in'], POINTER(IUIAutomationElement), 'element' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'parent' )), + COMMETHOD([], HRESULT, 'GetFirstChildElement', + ( ['in'], POINTER(IUIAutomationElement), 'element' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'first' )), + COMMETHOD([], HRESULT, 'GetLastChildElement', + ( ['in'], POINTER(IUIAutomationElement), 'element' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'last' )), + COMMETHOD([], HRESULT, 'GetNextSiblingElement', + ( ['in'], POINTER(IUIAutomationElement), 'element' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'next' )), + COMMETHOD([], HRESULT, 'GetPreviousSiblingElement', + ( ['in'], POINTER(IUIAutomationElement), 'element' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'previous' )), + COMMETHOD([], HRESULT, 'NormalizeElement', + ( ['in'], POINTER(IUIAutomationElement), 'element' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'normalized' )), + COMMETHOD([], HRESULT, 'GetParentElementBuildCache', + ( ['in'], POINTER(IUIAutomationElement), 'element' ), + ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'parent' )), + COMMETHOD([], HRESULT, 'GetFirstChildElementBuildCache', + ( ['in'], POINTER(IUIAutomationElement), 'element' ), + ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'first' )), + COMMETHOD([], HRESULT, 'GetLastChildElementBuildCache', + ( ['in'], POINTER(IUIAutomationElement), 'element' ), + ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'last' )), + COMMETHOD([], HRESULT, 'GetNextSiblingElementBuildCache', + ( ['in'], POINTER(IUIAutomationElement), 'element' ), + ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'next' )), + COMMETHOD([], HRESULT, 'GetPreviousSiblingElementBuildCache', + ( ['in'], POINTER(IUIAutomationElement), 'element' ), + ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'previous' )), + COMMETHOD([], HRESULT, 'NormalizeElementBuildCache', + ( ['in'], POINTER(IUIAutomationElement), 'element' ), + ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationElement)), 'normalized' )), + COMMETHOD(['propget'], HRESULT, 'condition', + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationCondition)), 'condition' )), +] +################################################################ +## code template for IUIAutomationTreeWalker implementation +##class IUIAutomationTreeWalker_Impl(object): +## def GetParentElement(self, element): ## '-no docstring-' -## #return retVal +## #return parent ## -## @property -## def CachedZoomMaximum(self): +## def GetFirstChildElement(self, element): ## '-no docstring-' -## #return retVal +## #return first ## -## @property -## def CurrentCanZoom(self): +## def GetLastChildElement(self, element): ## '-no docstring-' -## #return retVal +## #return last ## -## def ZoomByUnit(self, ZoomUnit): +## def GetNextSiblingElement(self, element): ## '-no docstring-' -## #return +## #return next ## -## @property -## def CachedZoomLevel(self): +## def GetPreviousSiblingElement(self, element): ## '-no docstring-' -## #return retVal +## #return previous ## -## def Zoom(self, zoomValue): +## def NormalizeElement(self, element): ## '-no docstring-' -## #return +## #return normalized ## -## @property -## def CurrentZoomLevel(self): +## def GetParentElementBuildCache(self, element, cacheRequest): ## '-no docstring-' -## #return retVal +## #return parent ## -## @property -## def CurrentZoomMaximum(self): +## def GetFirstChildElementBuildCache(self, element, cacheRequest): ## '-no docstring-' -## #return retVal +## #return first ## - -UIA_TextEditPatternId = 10032 # Constant c_int -UIA_IsPeripheralPropertyId = 30150 # Constant c_int -UIA_Selection2FirstSelectedItemPropertyId = 30169 # Constant c_int -class IUIAutomationObjectModelPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{71C284B3-C14D-4D14-981E-19751B0D756D}') - _idlflags_ = [] -IUIAutomationObjectModelPattern._methods_ = [ - COMMETHOD([], HRESULT, 'GetUnderlyingObjectModel', - ( ['retval', 'out'], POINTER(POINTER(IUnknown)), 'retVal' )), -] -################################################################ -## code template for IUIAutomationObjectModelPattern implementation -##class IUIAutomationObjectModelPattern_Impl(object): -## def GetUnderlyingObjectModel(self): +## def GetLastChildElementBuildCache(self, element, cacheRequest): ## '-no docstring-' -## #return retVal +## #return last ## - -UIA_TreeControlTypeId = 50023 # Constant c_int -StyleId_Subtitle = 70011 # Constant c_int -UIA_InputReachedTargetEventId = 20020 # Constant c_int -UIA_BoundingRectanglePropertyId = 30001 # Constant c_int -StyleId_Emphasis = 70013 # Constant c_int -UIA_Selection2ItemCountPropertyId = 30172 # Constant c_int -class IUIAutomationRangeValuePattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{59213F4F-7346-49E5-B120-80555987A148}') - _idlflags_ = [] -IUIAutomationRangeValuePattern._methods_ = [ - COMMETHOD([], HRESULT, 'SetValue', - ( ['in'], c_double, 'val' )), - COMMETHOD(['propget'], HRESULT, 'CurrentValue', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentIsReadOnly', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentMaximum', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentMinimum', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentLargeChange', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentSmallChange', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedValue', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedIsReadOnly', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedMaximum', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedMinimum', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedLargeChange', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedSmallChange', - ( ['retval', 'out'], POINTER(c_double), 'retVal' )), -] -################################################################ -## code template for IUIAutomationRangeValuePattern implementation -##class IUIAutomationRangeValuePattern_Impl(object): -## @property -## def CachedIsReadOnly(self): +## def GetNextSiblingElementBuildCache(self, element, cacheRequest): ## '-no docstring-' -## #return retVal +## #return next ## -## @property -## def CurrentValue(self): +## def GetPreviousSiblingElementBuildCache(self, element, cacheRequest): ## '-no docstring-' -## #return retVal +## #return previous ## -## def SetValue(self, val): +## def NormalizeElementBuildCache(self, element, cacheRequest): ## '-no docstring-' -## #return +## #return normalized ## ## @property -## def CurrentMaximum(self): +## def condition(self): ## '-no docstring-' -## #return retVal +## #return condition ## + +IUIAutomationProxyFactoryMapping._methods_ = [ + COMMETHOD(['propget'], HRESULT, 'count', + ( ['out', 'retval'], POINTER(c_uint), 'count' )), + COMMETHOD([], HRESULT, 'GetTable', + ( ['out', 'retval'], POINTER(_midlSAFEARRAY(POINTER(IUIAutomationProxyFactoryEntry))), 'table' )), + COMMETHOD([], HRESULT, 'GetEntry', + ( ['in'], c_uint, 'index' ), + ( ['out', 'retval'], POINTER(POINTER(IUIAutomationProxyFactoryEntry)), 'entry' )), + COMMETHOD([], HRESULT, 'SetTable', + ( ['in'], _midlSAFEARRAY(POINTER(IUIAutomationProxyFactoryEntry)), 'factoryList' )), + COMMETHOD([], HRESULT, 'InsertEntries', + ( ['in'], c_uint, 'before' ), + ( ['in'], _midlSAFEARRAY(POINTER(IUIAutomationProxyFactoryEntry)), 'factoryList' )), + COMMETHOD([], HRESULT, 'InsertEntry', + ( ['in'], c_uint, 'before' ), + ( ['in'], POINTER(IUIAutomationProxyFactoryEntry), 'factory' )), + COMMETHOD([], HRESULT, 'RemoveEntry', + ( ['in'], c_uint, 'index' )), + COMMETHOD([], HRESULT, 'ClearTable'), + COMMETHOD([], HRESULT, 'RestoreDefaultTable'), +] +################################################################ +## code template for IUIAutomationProxyFactoryMapping implementation +##class IUIAutomationProxyFactoryMapping_Impl(object): ## @property -## def CurrentSmallChange(self): +## def count(self): ## '-no docstring-' -## #return retVal +## #return count ## -## @property -## def CachedValue(self): +## def GetTable(self): ## '-no docstring-' -## #return retVal +## #return table ## -## @property -## def CurrentIsReadOnly(self): +## def GetEntry(self, index): ## '-no docstring-' -## #return retVal +## #return entry ## -## @property -## def CurrentLargeChange(self): +## def SetTable(self, factoryList): ## '-no docstring-' -## #return retVal +## #return ## -## @property -## def CachedSmallChange(self): +## def InsertEntries(self, before, factoryList): ## '-no docstring-' -## #return retVal +## #return ## -## @property -## def CurrentMinimum(self): +## def InsertEntry(self, before, factory): ## '-no docstring-' -## #return retVal +## #return ## -## @property -## def CachedMinimum(self): +## def RemoveEntry(self, index): ## '-no docstring-' -## #return retVal +## #return ## -## @property -## def CachedMaximum(self): +## def ClearTable(self): ## '-no docstring-' -## #return retVal +## #return ## -## @property -## def CachedLargeChange(self): +## def RestoreDefaultTable(self): ## '-no docstring-' -## #return retVal +## #return ## -class IUIAutomationTextChildPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): +class IUIAutomationPropertyCondition(IUIAutomationCondition): _case_insensitive_ = True - _iid_ = GUID('{6552B038-AE05-40C8-ABFD-AA08352AAB86}') + _iid_ = GUID('{99EBF2CB-5578-4267-9AD4-AFD6EA77E94B}') _idlflags_ = [] -IUIAutomationTextChildPattern._methods_ = [ - COMMETHOD(['propget'], HRESULT, 'TextContainer', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElement)), 'container' )), - COMMETHOD(['propget'], HRESULT, 'TextRange', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationTextRange)), 'range' )), +IUIAutomationPropertyCondition._methods_ = [ + COMMETHOD(['propget'], HRESULT, 'propertyId', + ( ['out', 'retval'], POINTER(c_int), 'propertyId' )), + COMMETHOD(['propget'], HRESULT, 'PropertyValue', + ( ['out', 'retval'], POINTER(VARIANT), 'PropertyValue' )), + COMMETHOD(['propget'], HRESULT, 'PropertyConditionFlags', + ( ['out', 'retval'], POINTER(PropertyConditionFlags), 'flags' )), ] ################################################################ -## code template for IUIAutomationTextChildPattern implementation -##class IUIAutomationTextChildPattern_Impl(object): +## code template for IUIAutomationPropertyCondition implementation +##class IUIAutomationPropertyCondition_Impl(object): ## @property -## def TextContainer(self): +## def propertyId(self): ## '-no docstring-' -## #return container +## #return propertyId ## ## @property -## def TextRange(self): +## def PropertyValue(self): ## '-no docstring-' -## #return range +## #return PropertyValue +## +## @property +## def PropertyConditionFlags(self): +## '-no docstring-' +## #return flags ## -UIA_AnnotationTargetPropertyId = 30117 # Constant c_int -class IUIAutomationDropTargetPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): +class IUIAutomationEventHandlerGroup(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): _case_insensitive_ = True - _iid_ = GUID('{69A095F7-EEE4-430E-A46B-FB73B1AE39A5}') + _iid_ = GUID('{C9EE12F2-C13B-4408-997C-639914377F4E}') _idlflags_ = [] -IUIAutomationDropTargetPattern._methods_ = [ - COMMETHOD(['propget'], HRESULT, 'CurrentDropTargetEffect', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedDropTargetEffect', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentDropTargetEffects', - ( ['retval', 'out'], POINTER(_midlSAFEARRAY(BSTR)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedDropTargetEffects', - ( ['retval', 'out'], POINTER(_midlSAFEARRAY(BSTR)), 'retVal' )), +IUIAutomation6._methods_ = [ + COMMETHOD([], HRESULT, 'CreateEventHandlerGroup', + ( ['out'], POINTER(POINTER(IUIAutomationEventHandlerGroup)), 'handlerGroup' )), + COMMETHOD([], HRESULT, 'AddEventHandlerGroup', + ( ['in'], POINTER(IUIAutomationElement), 'element' ), + ( ['in'], POINTER(IUIAutomationEventHandlerGroup), 'handlerGroup' )), + COMMETHOD([], HRESULT, 'RemoveEventHandlerGroup', + ( ['in'], POINTER(IUIAutomationElement), 'element' ), + ( ['in'], POINTER(IUIAutomationEventHandlerGroup), 'handlerGroup' )), + COMMETHOD(['propget'], HRESULT, 'ConnectionRecoveryBehavior', + ( ['out', 'retval'], POINTER(ConnectionRecoveryBehaviorOptions), 'ConnectionRecoveryBehaviorOptions' )), + COMMETHOD(['propput'], HRESULT, 'ConnectionRecoveryBehavior', + ( ['in'], ConnectionRecoveryBehaviorOptions, 'ConnectionRecoveryBehaviorOptions' )), + COMMETHOD(['propget'], HRESULT, 'CoalesceEvents', + ( ['out', 'retval'], POINTER(CoalesceEventsOptions), 'CoalesceEventsOptions' )), + COMMETHOD(['propput'], HRESULT, 'CoalesceEvents', + ( ['in'], CoalesceEventsOptions, 'CoalesceEventsOptions' )), + COMMETHOD([], HRESULT, 'AddActiveTextPositionChangedEventHandler', + ( ['in'], POINTER(IUIAutomationElement), 'element' ), + ( ['in'], TreeScope, 'scope' ), + ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), + ( ['in'], POINTER(IUIAutomationActiveTextPositionChangedEventHandler), 'handler' )), + COMMETHOD([], HRESULT, 'RemoveActiveTextPositionChangedEventHandler', + ( ['in'], POINTER(IUIAutomationElement), 'element' ), + ( ['in'], POINTER(IUIAutomationActiveTextPositionChangedEventHandler), 'handler' )), ] ################################################################ -## code template for IUIAutomationDropTargetPattern implementation -##class IUIAutomationDropTargetPattern_Impl(object): -## @property -## def CachedDropTargetEffects(self): +## code template for IUIAutomation6 implementation +##class IUIAutomation6_Impl(object): +## def CreateEventHandlerGroup(self): ## '-no docstring-' -## #return retVal +## #return handlerGroup ## -## @property -## def CurrentDropTargetEffect(self): +## def AddEventHandlerGroup(self, element, handlerGroup): +## '-no docstring-' +## #return +## +## def RemoveEventHandlerGroup(self, element, handlerGroup): +## '-no docstring-' +## #return +## +## def _get(self): +## '-no docstring-' +## #return ConnectionRecoveryBehaviorOptions +## def _set(self, ConnectionRecoveryBehaviorOptions): +## '-no docstring-' +## ConnectionRecoveryBehavior = property(_get, _set, doc = _set.__doc__) +## +## def _get(self): ## '-no docstring-' -## #return retVal +## #return CoalesceEventsOptions +## def _set(self, CoalesceEventsOptions): +## '-no docstring-' +## CoalesceEvents = property(_get, _set, doc = _set.__doc__) ## -## @property -## def CachedDropTargetEffect(self): +## def AddActiveTextPositionChangedEventHandler(self, element, scope, cacheRequest, handler): ## '-no docstring-' -## #return retVal +## #return ## -## @property -## def CurrentDropTargetEffects(self): +## def RemoveActiveTextPositionChangedEventHandler(self, element, handler): ## '-no docstring-' -## #return retVal +## #return ## -class IUIAutomationDragPattern(comtypes.gen._00020430_0000_0000_C000_000000000046_0_2_0.IUnknown): - _case_insensitive_ = True - _iid_ = GUID('{1DC7B570-1F54-4BAD-BCDA-D36A722FB7BD}') - _idlflags_ = [] -IUIAutomationDragPattern._methods_ = [ - COMMETHOD(['propget'], HRESULT, 'CurrentIsGrabbed', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedIsGrabbed', - ( ['retval', 'out'], POINTER(c_int), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentDropEffect', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedDropEffect', - ( ['retval', 'out'], POINTER(BSTR), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CurrentDropEffects', - ( ['retval', 'out'], POINTER(_midlSAFEARRAY(BSTR)), 'retVal' )), - COMMETHOD(['propget'], HRESULT, 'CachedDropEffects', - ( ['retval', 'out'], POINTER(_midlSAFEARRAY(BSTR)), 'retVal' )), - COMMETHOD([], HRESULT, 'GetCurrentGrabbedItems', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), - COMMETHOD([], HRESULT, 'GetCachedGrabbedItems', - ( ['retval', 'out'], POINTER(POINTER(IUIAutomationElementArray)), 'retVal' )), +IUIAutomationEventHandlerGroup._methods_ = [ + COMMETHOD([], HRESULT, 'AddActiveTextPositionChangedEventHandler', + ( ['in'], TreeScope, 'scope' ), + ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), + ( ['in'], POINTER(IUIAutomationActiveTextPositionChangedEventHandler), 'handler' )), + COMMETHOD([], HRESULT, 'AddAutomationEventHandler', + ( ['in'], c_int, 'eventId' ), + ( ['in'], TreeScope, 'scope' ), + ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), + ( ['in'], POINTER(IUIAutomationEventHandler), 'handler' )), + COMMETHOD([], HRESULT, 'AddChangesEventHandler', + ( ['in'], TreeScope, 'scope' ), + ( ['in'], POINTER(c_int), 'changeTypes' ), + ( ['in'], c_int, 'changesCount' ), + ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), + ( ['in'], POINTER(IUIAutomationChangesEventHandler), 'handler' )), + COMMETHOD([], HRESULT, 'AddNotificationEventHandler', + ( ['in'], TreeScope, 'scope' ), + ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), + ( ['in'], POINTER(IUIAutomationNotificationEventHandler), 'handler' )), + COMMETHOD([], HRESULT, 'AddPropertyChangedEventHandler', + ( ['in'], TreeScope, 'scope' ), + ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), + ( ['in'], POINTER(IUIAutomationPropertyChangedEventHandler), 'handler' ), + ( ['in'], POINTER(c_int), 'propertyArray' ), + ( ['in'], c_int, 'propertyCount' )), + COMMETHOD([], HRESULT, 'AddStructureChangedEventHandler', + ( ['in'], TreeScope, 'scope' ), + ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), + ( ['in'], POINTER(IUIAutomationStructureChangedEventHandler), 'handler' )), + COMMETHOD([], HRESULT, 'AddTextEditTextChangedEventHandler', + ( ['in'], TreeScope, 'scope' ), + ( ['in'], TextEditChangeType, 'TextEditChangeType' ), + ( ['in'], POINTER(IUIAutomationCacheRequest), 'cacheRequest' ), + ( ['in'], POINTER(IUIAutomationTextEditTextChangedEventHandler), 'handler' )), ] ################################################################ -## code template for IUIAutomationDragPattern implementation -##class IUIAutomationDragPattern_Impl(object): -## @property -## def CurrentIsGrabbed(self): -## '-no docstring-' -## #return retVal -## -## @property -## def CurrentDropEffects(self): +## code template for IUIAutomationEventHandlerGroup implementation +##class IUIAutomationEventHandlerGroup_Impl(object): +## def AddActiveTextPositionChangedEventHandler(self, scope, cacheRequest, handler): ## '-no docstring-' -## #return retVal +## #return ## -## @property -## def CurrentDropEffect(self): +## def AddAutomationEventHandler(self, eventId, scope, cacheRequest, handler): ## '-no docstring-' -## #return retVal +## #return ## -## def GetCachedGrabbedItems(self): +## def AddChangesEventHandler(self, scope, changeTypes, changesCount, cacheRequest, handler): ## '-no docstring-' -## #return retVal +## #return ## -## @property -## def CachedDropEffect(self): +## def AddNotificationEventHandler(self, scope, cacheRequest, handler): ## '-no docstring-' -## #return retVal +## #return ## -## @property -## def CachedIsGrabbed(self): +## def AddPropertyChangedEventHandler(self, scope, cacheRequest, handler, propertyArray, propertyCount): ## '-no docstring-' -## #return retVal +## #return ## -## @property -## def CachedDropEffects(self): +## def AddStructureChangedEventHandler(self, scope, cacheRequest, handler): ## '-no docstring-' -## #return retVal +## #return ## -## def GetCurrentGrabbedItems(self): +## def AddTextEditTextChangedEventHandler(self, scope, TextEditChangeType, cacheRequest, handler): ## '-no docstring-' -## #return retVal +## #return ## -UIA_CalendarControlTypeId = 50001 # Constant c_int -__all__ = [ 'UIA_IsGridItemPatternAvailablePropertyId', - 'IUIAutomationAndCondition', - 'UIA_StrikethroughColorAttributeId', - 'UIA_IndentationLeadingAttributeId', - 'UIA_LegacyIAccessiblePatternId', - 'UIA_Drag_DragCancelEventId', - 'UIA_IsSpreadsheetItemPatternAvailablePropertyId', - 'IUIAutomationElement', 'UIA_ClickablePointPropertyId', - 'UiaChangeInfo', 'UIA_LandmarkTypePropertyId', - 'WindowInteractionState_Running', 'UIA_StyleIdAttributeId', - 'UIA_SliderControlTypeId', - 'UIA_ForegroundColorAttributeId', - 'UIA_HeaderControlTypeId', 'UIA_ScrollItemPatternId', - 'UIA_StylesExtendedPropertiesPropertyId', - 'UIA_Invoke_InvokedEventId', 'UIA_HyperlinkControlTypeId', - 'UIA_Window_WindowOpenedEventId', - 'IUIAutomationActiveTextPositionChangedEventHandler', - 'OrientationType_None', 'UIA_DropTarget_DragLeaveEventId', - 'UIA_ValueIsReadOnlyPropertyId', - 'PropertyConditionFlags_None', 'UIA_ToolTipControlTypeId', - 'UIA_MultipleViewCurrentViewPropertyId', - 'TextEditChangeType_Composition', - 'UIA_MarginLeadingAttributeId', - 'UIA_IsScrollItemPatternAvailablePropertyId', - 'UIA_GridColumnCountPropertyId', 'UIA_WindowControlTypeId', - 'UIA_CaretBidiModeAttributeId', - 'UIA_AnnotationObjectsAttributeId', - 'UIA_LocalizedControlTypePropertyId', - 'UIA_AnnotationObjectsPropertyId', - 'UIA_SelectionItem_ElementAddedToSelectionEventId', - 'AnnotationType_Highlighted', 'UIA_ButtonControlTypeId', - 'AnnotationType_Header', - 'UIA_LegacyIAccessibleRolePropertyId', - 'UIA_InputReachedOtherElementEventId', - 'UIA_SelectionItem_ElementRemovedFromSelectionEventId', - 'UIA_CaretPositionAttributeId', - 'IUIAutomationExpandCollapsePattern', 'DockPosition_None', - 'UIA_MainLandmarkTypeId', +__all__ = [ 'UIA_TableItemPatternId', 'ToggleState', + 'UIA_TableColumnHeadersPropertyId', + 'UIA_FillColorPropertyId', 'UIA_ToolTipClosedEventId', + 'HeadingLevel3', + 'UIA_MultipleViewSupportedViewsPropertyId', + 'SynchronizedInputType_KeyDown', + 'SynchronizedInputType_RightMouseUp', + 'UIA_StylesFillPatternStylePropertyId', + 'UIA_IsDialogPropertyId', 'SynchronizedInputType_LeftMouseUp', - 'UIA_RotationPropertyId', - 'UIA_LegacyIAccessibleDefaultActionPropertyId', - 'TreeTraversalOptions', - 'UIA_IsMultipleViewPatternAvailablePropertyId', - 'UIA_RangeValueMinimumPropertyId', - 'IUIAutomationTransformPattern2', 'HeadingLevel2', - 'UIA_MenuBarControlTypeId', 'UIA_FontWeightAttributeId', - 'UIA_DocumentControlTypeId', 'UIA_CustomControlTypeId', - 'UIA_ExpandCollapsePatternId', 'ExtendedProperty', - 'AnnotationType_Comment', 'HeadingLevel8', - 'AnnotationType_DataValidationError', - 'UIA_ScrollHorizontalViewSizePropertyId', - 'WindowInteractionState_BlockedByModalWindow', - 'UIA_IsPeripheralPropertyId', - 'IUIAutomationTextRangeArray', - 'UIA_IsTextPattern2AvailablePropertyId', - 'StructureChangeType_ChildrenReordered', - 'TextEditChangeType_None', - 'UIA_SynchronizedInputPatternId', - 'UIA_FullDescriptionPropertyId', - 'UIA_TreeItemControlTypeId', - 'IUIAutomationSpreadsheetPattern', 'UIA_InvokePatternId', + 'UIA_MenuModeEndEventId', 'DockPosition_Fill', + 'NotificationKind_ItemAdded', + 'UIA_DragDropEffectPropertyId', + 'UIA_LiveSettingPropertyId', + 'IUIAutomationRangeValuePattern', + 'UIA_StylesStyleIdPropertyId', + 'UIA_LegacyIAccessibleSelectionPropertyId', + 'UIA_SelectionItemPatternId', + 'UIA_LegacyIAccessibleStatePropertyId', + 'UIA_IsDataValidForFormPropertyId', + 'AnnotationType_Header', + 'UIA_DropTargetDropTargetEffectsPropertyId', + 'PropertyConditionFlags_None', + 'SynchronizedInputType_RightMouseDown', + 'UIA_ScrollVerticalViewSizePropertyId', + 'IUIAutomationTablePattern', 'HeadingLevel7', + 'NotificationProcessing_ImportantMostRecent', + 'StyleId_Heading4', 'ZoomUnit_SmallDecrement', + 'UIA_IsKeyboardFocusablePropertyId', + 'IUIAutomationNotificationEventHandler', + 'UIA_IsValuePatternAvailablePropertyId', + 'UIA_TreeItemControlTypeId', 'UIA_AriaRolePropertyId', + 'CoalesceEventsOptions_Enabled', + 'OrientationType_Vertical', 'StyleId_Heading2', + 'UIA_ProgressBarControlTypeId', 'UiaChangeInfo', + 'UIA_WindowIsTopmostPropertyId', + 'UIA_InputDiscardedEventId', 'UIA_MainLandmarkTypeId', + 'WindowInteractionState', 'UIA_Drag_DragCompleteEventId', + 'UIA_BeforeParagraphSpacingAttributeId', + 'TextPatternRangeEndpoint_End', 'UIA_SizeOfSetPropertyId', + 'UIA_TransformPattern2Id', + 'UIA_StylesFillPatternColorPropertyId', + 'UIA_SpreadsheetItemPatternId', 'ZoomUnit_LargeDecrement', + 'UIA_RangeValueIsReadOnlyPropertyId', 'UIA_SelectionItem_ElementSelectedEventId', - 'IUIAutomationWindowPattern', - 'UIA_IsDropTargetPatternAvailablePropertyId', - 'AutomationElementMode_None', - 'UIA_IsSelectionItemPatternAvailablePropertyId', - 'UIA_LiveRegionChangedEventId', - 'AnnotationType_FormatChange', - 'UIA_BackgroundColorAttributeId', - 'UIA_SizeOfSetPropertyId', 'UIA_AnimationStyleAttributeId', - 'HeadingLevel_None', 'IUIAutomationNotCondition', - 'UIA_OutlineColorPropertyId', - 'IUIAutomationTransformPattern', - 'UIA_InputDiscardedEventId', - 'ExpandCollapseState_Expanded', 'UIA_IsItalicAttributeId', - 'UIA_AnnotationDateTimePropertyId', 'StyleId_BulletedList', - 'RowOrColumnMajor_Indeterminate', - 'UIA_DataGridControlTypeId', 'UIA_DockDockPositionPropertyId', - 'IUIAutomationTextPattern', - 'UIA_IsExpandCollapsePatternAvailablePropertyId', - 'IUIAutomationTreeWalker', 'UIA_LayoutInvalidatedEventId', - 'UIA_LegacyIAccessibleStatePropertyId', - 'UIA_TextPatternId', 'UIA_RangeValueSmallChangePropertyId', - 'UIA_ValueValuePropertyId', - 'IUIAutomationSelectionPattern2', - 'UIA_IsSpreadsheetPatternAvailablePropertyId', - 'UIA_SpinnerControlTypeId', 'AnnotationType_MoveChange', - 'AnnotationType_CircularReferenceError', - 'UIA_NativeWindowHandlePropertyId', - 'UIA_RuntimeIdPropertyId', 'TextUnit_Document', - 'HeadingLevel3', 'TextUnit_Word', 'HeadingLevel5', - 'HeadingLevel4', 'HeadingLevel7', - 'IUIAutomationSynchronizedInputPattern', 'HeadingLevel9', - 'UIA_GridItemColumnPropertyId', 'UIA_SelectionPatternId', - 'IUIAutomationOrCondition', - 'WindowInteractionState_Closing', - 'UIA_Selection2CurrentSelectedItemPropertyId', + 'UIA_AnnotationTargetPropertyId', + 'UIA_IsSpreadsheetItemPatternAvailablePropertyId', + 'UIA_InvokePatternId', 'UIA_IsPeripheralPropertyId', + 'UIA_SpreadsheetPatternId', + 'UIA_RangeValueValuePropertyId', 'ToggleState_On', + 'UIA_Window_WindowClosedEventId', 'UIA_LevelPropertyId', + 'TextEditChangeType', + 'UIA_AnnotationAnnotationTypeIdPropertyId', + 'TreeScope_Descendants', 'UIA_TextEdit_TextChangedEventId', + 'IUIAutomationTextChildPattern', 'StyleId_Quote', + 'UIA_TransformCanMovePropertyId', + 'UIA_LandmarkTypePropertyId', + 'UIA_LegacyIAccessibleNamePropertyId', + 'UIA_WindowCanMaximizePropertyId', + 'UIA_OutlineStylesAttributeId', + 'IUIAutomationNotCondition', + 'UIA_StrikethroughColorAttributeId', + 'IUIAutomationElementArray', 'UIA_SliderControlTypeId', + 'UIA_SpinnerControlTypeId', 'HeadingLevel2', 'UIA_IsScrollPatternAvailablePropertyId', - 'UIA_LevelPropertyId', 'UIA_TogglePatternId', - 'UIA_SelectionActiveEndAttributeId', - 'UIA_IsActiveAttributeId', 'IUIAutomationElement4', - 'SynchronizedInputType_RightMouseDown', - 'UIA_RangeValueMaximumPropertyId', - 'IUIAutomationValuePattern', - 'UIA_BoundingRectanglePropertyId', - 'IUIAutomationEventHandler', - 'UIA_TextFlowDirectionsAttributeId', - 'UIA_MultipleViewPatternId', 'StyleId_NumberedList', + 'UIA_SplitButtonControlTypeId', + 'UIA_IsCustomNavigationPatternAvailablePropertyId', + 'IUIAutomationElement5', 'UIA_IsReadOnlyAttributeId', + 'UIA_ControllerForPropertyId', + 'UIA_GridRowCountPropertyId', 'UIA_ToolTipControlTypeId', + 'TreeScope_Element', 'UIA_ToolBarControlTypeId', + 'UIA_StylesStyleNamePropertyId', 'ExtendedProperty', + 'UIA_AnnotationPatternId', 'AnnotationType_Highlighted', 'UIA_Selection2ItemCountPropertyId', - 'NavigateDirection_FirstChild', - 'UIA_IsTextEditPatternAvailablePropertyId', - 'UIA_SearchLandmarkTypeId', 'TreeScope_None', - 'UIA_ScrollVerticallyScrollablePropertyId', - 'UIA_TableControlTypeId', - 'IUIAutomationChangesEventHandler', - 'UIA_TableColumnHeadersPropertyId', - 'UIA_Selection2LastSelectedItemPropertyId', - 'UIA_SizePropertyId', 'UIA_AnnotationTypesPropertyId', - 'TextPatternRangeEndpoint_Start', - 'UIA_TableItemColumnHeaderItemsPropertyId', - 'SupportedTextSelection_Single', - 'IUIAutomationTextPattern2', 'SynchronizedInputType', - 'UIA_ClassNamePropertyId', 'UIA_UnderlineStyleAttributeId', - 'NotificationKind_ItemRemoved', - 'UIA_RangeValueValuePropertyId', - 'UIA_HorizontalTextAlignmentAttributeId', - 'UIA_SelectionItemSelectionContainerPropertyId', - 'UIA_LegacyIAccessibleKeyboardShortcutPropertyId', - 'TextUnit_Page', 'UIA_SelectionPattern2Id', - 'UIA_Transform2ZoomMaximumPropertyId', - 'UIA_PaneControlTypeId', 'UIA_CheckBoxControlTypeId', - 'UIA_CenterPointPropertyId', 'UIA_GridItemPatternId', - 'UIA_AnnotationAnnotationTypeIdPropertyId', - 'IUIAutomationProxyFactoryMapping', - 'WindowVisualState_Normal', - 'UIA_WindowWindowVisualStatePropertyId', - 'ConnectionRecoveryBehaviorOptions', - 'IUIAutomationItemContainerPattern', - 'UIA_DragDropEffectsPropertyId', - 'ExpandCollapseState_Collapsed', - 'UIA_MenuModeStartEventId', 'UIA_MenuClosedEventId', - 'UIA_CustomLandmarkTypeId', 'UIA_WindowPatternId', - 'UIA_ChangesEventId', 'IUIAutomationDockPattern', - 'LiveSetting', 'IUIAutomationFocusChangedEventHandler', - 'UIA_CalendarControlTypeId', - 'UIA_OverlineColorAttributeId', - 'IUIAutomationDropTargetPattern', - 'UIA_StyleNameAttributeId', 'AnnotationType_Footer', - 'TextUnit_Format', - 'UIA_WindowWindowInteractionStatePropertyId', + 'UIA_StatusBarControlTypeId', 'StyleId_Heading6', + 'UIA_AccessKeyPropertyId', 'AutomationElementMode_None', + 'ProviderOptions_UseComThreading', + 'UIA_AnnotationObjectsAttributeId', + 'UIA_IsRequiredForFormPropertyId', 'DockPosition', + 'UIA_LegacyIAccessibleChildIdPropertyId', + 'IUIAutomationStylesPattern', + 'UIA_DropTarget_DragEnterEventId', 'TextUnit_Character', + 'RowOrColumnMajor_ColumnMajor', + 'TreeTraversalOptions_Default', 'UIA_ScrollVerticalScrollPercentPropertyId', - 'StyleId_Quote', 'UIA_FormLandmarkTypeId', - 'UIA_SpreadsheetItemPatternId', 'AutomationElementMode', - 'UIA_AnnotationTypesAttributeId', 'StyleId_Heading9', - 'UIA_ItemContainerPatternId', 'StyleId_Heading5', - 'StyleId_Heading4', 'StyleId_Heading7', 'StyleId_Heading6', - 'StyleId_Heading1', 'StyleId_Heading3', - 'UIA_SelectionIsSelectionRequiredPropertyId', - 'UIA_ListItemControlTypeId', 'UIA_ObjectModelPatternId', - 'UIA_LegacyIAccessibleSelectionPropertyId', - 'UIA_TransformPatternId', 'TextPatternRangeEndpoint', - 'UIA_AnnotationTargetPropertyId', - 'UIA_Transform2ZoomLevelPropertyId', - 'UIA_IsAnnotationPatternAvailablePropertyId', - 'IUIAutomationTogglePattern', - 'UIA_IsValuePatternAvailablePropertyId', - 'IUIAutomationRangeValuePattern', - 'ZoomUnit_LargeDecrement', 'UIA_ComboBoxControlTypeId', - 'UIA_MarginBottomAttributeId', - 'IUIAutomationObjectModelPattern', 'IUIAutomationElement9', - 'IUIAutomationElement8', 'IUIAutomationTextChildPattern', - 'IUIAutomationElement3', 'IUIAutomationElement2', - 'IUIAutomationElement7', 'IUIAutomationElement6', - 'IUIAutomationElement5', 'ToggleState_On', - 'UIA_DockPatternId', 'UIA_IsRequiredForFormPropertyId', - 'TextUnit_Line', 'AnnotationType_AdvancedProofingIssue', - 'UIA_IsGridPatternAvailablePropertyId', 'CUIAutomation8', - 'UIA_IsHiddenAttributeId', - 'UIA_TableRowOrColumnMajorPropertyId', - 'NotificationKind_ActionCompleted', 'TreeScope_Children', - 'UIA_SpreadsheetItemAnnotationTypesPropertyId', - 'WindowInteractionState_ReadyForUserInteraction', - 'UIA_TableItemRowHeaderItemsPropertyId', - 'UIA_SelectionCanSelectMultiplePropertyId', - 'WindowInteractionState_NotResponding', - 'UIA_Text_TextSelectionChangedEventId', - 'ExpandCollapseState_LeafNode', 'UIA_ToolBarControlTypeId', - 'IUIAutomation', 'TreeScope_Parent', - 'IUIAutomationProxyFactory', 'IUIAutomationTextRange3', - 'IUIAutomationTextRange2', - 'ProviderOptions_ClientSideProvider', - 'NavigateDirection_NextSibling', - 'ScrollAmount_SmallIncrement', - 'ProviderOptions_ProviderOwnsSetFocus', 'NotificationKind', - 'UIA_FontNameAttributeId', 'IUIAutomationSelectionPattern', - 'TreeScope_Element', 'WindowInteractionState', - 'UIA_SummaryChangeId', - 'UIA_IsInvokePatternAvailablePropertyId', - 'ExpandCollapseState', + 'UIA_SynchronizedInputPatternId', + 'UIA_ProviderDescriptionPropertyId', 'StyleId_Heading7', + 'UIA_GridItemColumnSpanPropertyId', + 'ScrollAmount_NoAmount', + 'UIA_IsTransformPatternAvailablePropertyId', + 'UIA_AnimationStyleAttributeId', + 'AnnotationType_FormatChange', + 'UIA_IsTransformPattern2AvailablePropertyId', + 'NavigateDirection', 'Assertive', 'UIA_MenuClosedEventId', + 'UIA_ToggleToggleStatePropertyId', + 'UIA_ImageControlTypeId', 'DockPosition_Bottom', + 'AnnotationType_ExternalChange', + 'UIA_IsControlElementPropertyId', + 'IUIAutomationPropertyCondition', + 'UIA_LocalizedControlTypePropertyId', + 'UIA_AutomationIdPropertyId', 'DockPosition_Left', + 'UIA_Selection2LastSelectedItemPropertyId', + 'UIA_NotificationEventId', 'UIA_CulturePropertyId', + 'StyleId_Heading9', 'UIA_WindowPatternId', + 'UIA_AsyncContentLoadedEventId', 'UIA_SelectionPatternId', + 'IUIAutomation5', 'UIA_IsActiveAttributeId', + 'UIA_AutomationFocusChangedEventId', + 'ScrollAmount_SmallIncrement', 'StyleId_Title', + 'UIA_TextEdit_ConversionTargetChangedEventId', + 'OrientationType_None', 'TextUnit', + 'UIA_ScrollHorizontallyScrollablePropertyId', + 'StyleId_Emphasis', + 'TreeTraversalOptions_LastToFirstOrder', + 'StructureChangeType_ChildrenReordered', + 'ExpandCollapseState_LeafNode', 'IUIAutomationSpreadsheetItemPattern', - 'UIA_OptimizeForVisualContentPropertyId', - 'SynchronizedInputType_RightMouseUp', - 'UIA_StrikethroughStyleAttributeId', + 'UIA_DescribedByPropertyId', + 'UIA_ForegroundColorAttributeId', + 'UIA_IsSelectionPattern2AvailablePropertyId', 'UIA_IsWindowPatternAvailablePropertyId', - 'UIA_IsDragPatternAvailablePropertyId', - 'UIA_DragDropEffectPropertyId', - 'UIA_AutomationPropertyChangedEventId', + 'UIA_MultipleViewPatternId', + 'UIA_ValueIsReadOnlyPropertyId', + 'IUIAutomationScrollItemPattern', + 'ProviderOptions_ProviderOwnsSetFocus', + 'NotificationProcessing', 'UIA_CalendarControlTypeId', + 'ProviderOptions_RefuseNonClientSupport', + 'IUIAutomationAndCondition', 'TreeScope_None', 'UIA_SpreadsheetItemAnnotationObjectsPropertyId', - 'UIA_ExpandCollapseExpandCollapseStatePropertyId', - 'UIA_StylesFillPatternStylePropertyId', - 'DockPosition_Right', 'UIA_ProgressBarControlTypeId', - 'Assertive', 'ProviderOptions_UseClientCoordinates', - 'UIA_MenuOpenedEventId', 'UIA_MenuModeEndEventId', - 'IUIAutomationPropertyCondition', 'UIA_AriaRolePropertyId', - 'UIA_TransformCanResizePropertyId', - 'PropertyConditionFlags_MatchSubstring', - 'AutomationElementMode_Full', - 'StructureChangeType_ChildrenBulkRemoved', - 'IUIAutomationTextEditPattern', 'Off', - 'AnnotationType_SpellingError', - 'NotificationProcessing_ImportantMostRecent', - 'UIA_MenuControlTypeId', 'UIA_OutlineThicknessPropertyId', - 'CoalesceEventsOptions_Enabled', - 'UIA_ScrollBarControlTypeId', - 'UIA_SelectionItemIsSelectedPropertyId', - 'UIA_LineSpacingAttributeId', 'UIA_CapStyleAttributeId', - 'HeadingLevel1', 'UIA_AppBarControlTypeId', - 'UIA_Drag_DragStartEventId', 'StyleId_Custom', - 'UIA_ScrollHorizontalScrollPercentPropertyId', - 'UIA_DragPatternId', 'AnnotationType_EditingLockedChange', - 'WindowVisualState_Maximized', 'WindowVisualState', - 'UIA_LiveSettingPropertyId', 'UIA_FlowsToPropertyId', - 'AnnotationType_Author', 'UIA_HeaderItemControlTypeId', - 'UIA_ListControlTypeId', - 'UIA_ProviderDescriptionPropertyId', - 'UIA_ScrollVerticalViewSizePropertyId', 'StyleId_Normal', - 'StructureChangeType', 'UIA_NotificationEventId', - 'UIA_SeparatorControlTypeId', - 'UIA_IsContentElementPropertyId', - 'ScrollAmount_LargeDecrement', - 'UIA_MarginTrailingAttributeId', + 'UIA_Transform2ZoomMinimumPropertyId', + 'AnnotationType_SpellingError', 'UIA_ItemTypePropertyId', + 'UIA_IsTextEditPatternAvailablePropertyId', + 'UIA_LegacyIAccessibleValuePropertyId', + 'ConnectionRecoveryBehaviorOptions', + 'IUIAutomationGridPattern', + 'IUIAutomationSynchronizedInputPattern', + 'IUIAutomationTextEditTextChangedEventHandler', + 'IUIAutomationEventHandlerGroup', 'UIA_InputReachedTargetEventId', - 'UIA_DragIsGrabbedPropertyId', 'AnnotationType_Endnote', - 'DockPosition_Top', 'UIA_OrientationPropertyId', - 'UIA_Selection2FirstSelectedItemPropertyId', - 'UIA_SayAsInterpretAsMetadataId', 'IUIAutomationCondition', - 'UIA_StructureChangedEventId', - 'NotificationProcessing_All', - 'UIA_IsSuperscriptAttributeId', - 'UIA_MenuItemControlTypeId', - 'UIA_Window_WindowClosedEventId', 'UIA_ImageControlTypeId', - 'DockPosition_Left', 'PropertyConditionFlags_IgnoreCase', - 'UIA_FlowsFromPropertyId', - 'UIA_Transform2CanZoomPropertyId', - 'UIA_SelectionSelectionPropertyId', + 'UIA_SemanticZoomControlTypeId', 'TreeTraversalOptions', + 'UIA_SelectionItem_ElementRemovedFromSelectionEventId', + 'WindowVisualState', 'ZoomUnit_NoAmount', + 'UIA_CheckBoxControlTypeId', 'ZoomUnit_SmallIncrement', + 'NotificationProcessing_All', 'UIA_DragPatternId', + 'UIA_IsRangeValuePatternAvailablePropertyId', 'SynchronizedInputType_KeyUp', - 'UIA_LocalizedLandmarkTypePropertyId', - 'UIA_StatusBarControlTypeId', - 'UIA_TransformCanRotatePropertyId', - 'UIA_NavigationLandmarkTypeId', - 'UIA_AutomationIdPropertyId', - 'SynchronizedInputType_LeftMouseDown', - 'UIA_StylesStyleIdPropertyId', - 'UIA_LegacyIAccessibleChildIdPropertyId', - 'IUIAutomationTableItemPattern', - 'TextPatternRangeEndpoint_End', + 'IUIAutomationItemContainerPattern', + 'UIA_DragGrabbedItemsPropertyId', + 'NavigateDirection_NextSibling', 'SupportedTextSelection', + 'UIA_LegacyIAccessibleRolePropertyId', + 'IUIAutomationProxyFactory', 'UIA_TitleBarControlTypeId', + 'UIA_TableRowOrColumnMajorPropertyId', + 'IUIAutomationBoolCondition', 'UIA_EditControlTypeId', + 'UIA_IsItemContainerPatternAvailablePropertyId', + 'UIA_FlowsFromPropertyId', + 'UIA_IndentationTrailingAttributeId', + 'UIA_GridItemRowSpanPropertyId', 'OrientationType', + 'HeadingLevel8', 'UIA_WindowIsModalPropertyId', 'Off', + 'HeadingLevel4', + 'IUIAutomationPropertyChangedEventHandler', + 'UIA_TransformCanResizePropertyId', + 'ProviderOptions_NonClientAreaProvider', + 'UIA_HorizontalTextAlignmentAttributeId', 'UIA_IsObjectModelPatternAvailablePropertyId', - 'ProviderOptions_ServerSideProvider', - 'IUIAutomationTextRange', 'ToggleState_Off', - 'ScrollAmount', 'TextEditChangeType_AutoCorrect', - 'UIA_RangeValueIsReadOnlyPropertyId', - 'IUIAutomationTextEditTextChangedEventHandler', - 'IAccessible', 'NavigateDirection_Parent', - 'ZoomUnit_LargeIncrement', - 'UIA_ActiveTextPositionChangedEventId', 'ToggleState', - 'ProviderOptions_UseComThreading', - 'OrientationType_Vertical', 'AnnotationType_GrammarError', - 'UIA_TreeControlTypeId', 'ZoomUnit_SmallIncrement', - 'UIA_WindowCanMinimizePropertyId', 'HeadingLevel6', - 'DockPosition_Bottom', 'UIA_ControllerForPropertyId', - 'TreeScope_Subtree', 'UIA_GridRowCountPropertyId', - 'ConnectionRecoveryBehaviorOptions_Enabled', - 'NavigateDirection', 'UIA_IsOffscreenPropertyId', - 'UIA_IsDialogPropertyId', - 'UIA_LegacyIAccessibleDescriptionPropertyId', - 'NotificationKind_ItemAdded', - 'SupportedTextSelection_None', 'UIA_ValuePatternId', - 'UIA_CulturePropertyId', 'IUIAutomationBoolCondition', + 'TextPatternRangeEndpoint_Start', + 'UIA_TableItemColumnHeaderItemsPropertyId', + 'UIA_IsSelectionItemPatternAvailablePropertyId', + 'TreeScope_Ancestors', + 'UIA_SelectionItem_ElementAddedToSelectionEventId', + 'NotificationProcessing_MostRecent', 'TextUnit_Line', + 'UIA_ListItemControlTypeId', 'UIA_Drag_DragStartEventId', + 'UIA_ListControlTypeId', 'UIA_NamePropertyId', + 'UIA_TabControlTypeId', + 'WindowInteractionState_ReadyForUserInteraction', + 'UIA_BoundingRectanglePropertyId', + 'UIA_IsHiddenAttributeId', + 'TextEditChangeType_AutoCorrect', 'TextUnit_Format', 'AnnotationType_Unknown', + 'TextEditChangeType_AutoComplete', + 'UIA_OverlineColorAttributeId', + 'IUIAutomationTransformPattern', 'ToggleState_Off', + 'IUIAutomation3', 'UIA_MarginTrailingAttributeId', + 'IUIAutomationStructureChangedEventHandler', + 'UIA_Transform2CanZoomPropertyId', + 'UIA_FillTypePropertyId', 'UIA_HasKeyboardFocusPropertyId', + 'HeadingLevel6', 'UIA_AutomationPropertyChangedEventId', 'UIA_IsLegacyIAccessiblePatternAvailablePropertyId', - 'UIA_IsEnabledPropertyId', 'UIA_NamePropertyId', - 'ZoomUnit_SmallDecrement', 'UIA_FontSizeAttributeId', - 'IUIAutomationScrollPattern', 'ToggleState_Indeterminate', - 'UIA_IsControlElementPropertyId', - 'UIA_AcceleratorKeyPropertyId', - 'UIA_HostedFragmentRootsInvalidatedEventId', - 'UIA_IsStylesPatternAvailablePropertyId', 'UIA_DropTarget_DroppedEventId', - 'AnnotationType_Mathematics', + 'UIA_IsGridPatternAvailablePropertyId', 'HeadingLevel5', + 'UIA_GridItemColumnPropertyId', 'ZoomUnit', + 'UIA_GroupControlTypeId', 'UIA_DataGridControlTypeId', + 'UIA_ScrollItemPatternId', + 'UIA_IsAnnotationPatternAvailablePropertyId', + 'UIA_DropTargetPatternId', + 'UIA_SelectionSelectionPropertyId', + 'UIA_AnnotationAnnotationTypeNamePropertyId', + 'UIA_SayAsInterpretAsMetadataId', + 'StructureChangeType_ChildrenBulkAdded', + 'NotificationKind_ActionCompleted', + 'IUIAutomationActiveTextPositionChangedEventHandler', + 'AnnotationType_DeletionChange', 'UIA_ButtonControlTypeId', + 'UIA_Text_TextChangedEventId', + 'UIA_HyperlinkControlTypeId', 'UIA_CultureAttributeId', + 'IAccessible', 'UIA_StylesShapePropertyId', + 'UIA_TextPatternId', 'UIA_Transform2ZoomMaximumPropertyId', + 'IUIAutomationCustomNavigationPattern', 'StyleId_Custom', + 'UIA_Invoke_InvokedEventId', + 'UIA_Window_WindowOpenedEventId', + 'UIA_TableRowHeadersPropertyId', + 'IUIAutomationVirtualizedItemPattern', + 'ToggleState_Indeterminate', + 'ExpandCollapseState_PartiallyExpanded', + 'UIA_SelectionItemSelectionContainerPropertyId', + 'UIA_IsTextPatternAvailablePropertyId', + 'UIA_IsSubscriptAttributeId', 'AnnotationType_Mathematics', + 'IUIAutomationObjectModelPattern', + 'UIA_Text_TextSelectionChangedEventId', + 'AnnotationType_ConflictingChange', 'HeadingLevel9', + 'IUIAutomationOrCondition', 'UIA_GridItemRowPropertyId', + 'SupportedTextSelection_Multiple', + 'ConnectionRecoveryBehaviorOptions_Enabled', + 'UIA_AnnotationDateTimePropertyId', 'LiveSetting', + 'UIA_UnderlineStyleAttributeId', 'UIA_TextPattern2Id', + 'UIA_ExpandCollapseExpandCollapseStatePropertyId', + 'UIA_HeaderControlTypeId', + 'UIA_IsExpandCollapsePatternAvailablePropertyId', + 'UIA_CenterPointPropertyId', + 'IUIAutomationFocusChangedEventHandler', + 'UIA_TableControlTypeId', 'TextPatternRangeEndpoint', + 'IUIAutomationElement8', + 'UIA_SelectionItemIsSelectedPropertyId', + 'UIA_StylesExtendedPropertiesPropertyId', + 'IUIAutomationCacheRequest', 'TextUnit_Document', + 'TextUnit_Word', 'IUIAutomationElement6', + 'UIA_ItemContainerPatternId', + 'UIA_RangeValueSmallChangePropertyId', + 'UIA_RangeValuePatternId', 'CUIAutomation8', + 'UIA_ActiveTextPositionChangedEventId', + 'UIA_AcceleratorKeyPropertyId', + 'IUIAutomationSpreadsheetPattern', + 'IUIAutomationDropTargetPattern', + 'UIA_IsInvokePatternAvailablePropertyId', + 'UIA_MenuBarControlTypeId', 'UIA_RadioButtonControlTypeId', + 'NotificationKind_ItemRemoved', 'UIA_TabsAttributeId', + 'AnnotationType_Author', 'StyleId_BulletedList', + 'AnnotationType_CircularReferenceError', + 'UIA_DocumentControlTypeId', + 'UIA_TextFlowDirectionsAttributeId', + 'AnnotationType_AdvancedProofingIssue', + 'UIA_RangeValueMaximumPropertyId', + 'UIA_DropTargetDropTargetEffectPropertyId', + 'UIA_StrikethroughStyleAttributeId', + 'UIA_StyleIdAttributeId', 'IUIAutomationMultipleViewPattern', - 'TreeTraversalOptions_PostOrder', - 'UIA_TextEdit_TextChangedEventId', 'UIA_TextControlTypeId', - 'UIA_TextPattern2Id', 'UIA_LinkAttributeId', - 'UIA_StylesPatternId', - 'UIA_IsTransformPatternAvailablePropertyId', - 'TextEditChangeType_AutoComplete', - 'UIA_TextEdit_ConversionTargetChangedEventId', - 'WindowVisualState_Minimized', - 'AnnotationType_ExternalChange', - 'IUIAutomationCacheRequest', - 'UIA_Drag_DragCompleteEventId', + 'WindowVisualState_Maximized', + 'UIA_SpreadsheetItemAnnotationTypesPropertyId', + 'ProviderOptions_ClientSideProvider', + 'UIA_ControlTypePropertyId', + 'IUIAutomationTextEditPattern', + 'IUIAutomationTableItemPattern', + 'ConnectionRecoveryBehaviorOptions_Disabled', + 'RowOrColumnMajor', 'UIA_OrientationPropertyId', + 'UIA_ScrollPatternId', + 'TextEditChangeType_CompositionFinalized', + 'UIA_ObjectModelPatternId', 'IUIAutomation6', + 'StructureChangeType_ChildRemoved', + 'IUIAutomationTextRangeArray', + 'UIA_Drag_DragCancelEventId', 'PropertyConditionFlags', + 'UIA_Selection_InvalidatedEventId', + 'UIA_DragDropEffectsPropertyId', + 'UIA_AnnotationTypesAttributeId', 'IUIAutomationElement7', + 'UIA_NativeWindowHandlePropertyId', + 'IUIAutomationExpandCollapsePattern', + 'UIA_TransformCanRotatePropertyId', + 'IUIAutomationTextPattern', 'UIA_TreeControlTypeId', + 'IUIAutomationInvokePattern', 'StyleId_Heading3', + 'RowOrColumnMajor_Indeterminate', + 'UIA_UnderlineColorAttributeId', 'IUIAutomationTextRange', + 'UIA_MenuOpenedEventId', 'IUIAutomationDragPattern', 'UIA_AfterParagraphSpacingAttributeId', - 'UIA_VirtualizedItemPatternId', - 'AnnotationType_DeletionChange', - 'TreeTraversalOptions_LastToFirstOrder', - 'UIA_OutlineStylesAttributeId', 'UIA_IsPasswordPropertyId', - 'SynchronizedInputType_KeyDown', - 'UIA_SelectionItemPatternId', 'PropertyConditionFlags', - 'UIA_UnderlineColorAttributeId', - 'UIA_DataItemControlTypeId', - 'RowOrColumnMajor_ColumnMajor', - 'UIA_MultipleViewSupportedViewsPropertyId', - 'IUIAutomationStructureChangedEventHandler', - 'UIA_IndentationTrailingAttributeId', - 'CoalesceEventsOptions', - 'NotificationProcessing_MostRecent', - 'UIA_ToolTipOpenedEventId', - 'UIA_StylesFillPatternColorPropertyId', 'TreeScope', - 'UIA_DropTargetPatternId', - 'UIA_IsSelectionPattern2AvailablePropertyId', - 'ScrollAmount_LargeIncrement', 'UIA_ThumbControlTypeId', - 'UIA_GridItemContainingGridPropertyId', - 'UIA_AnnotationPatternId', + 'UIA_IsScrollItemPatternAvailablePropertyId', + 'StyleId_Subtitle', 'UIA_ToolTipOpenedEventId', + 'UIA_BulletStyleAttributeId', + 'UIA_IsTogglePatternAvailablePropertyId', + 'UIA_LegacyIAccessibleDefaultActionPropertyId', 'UIA_SpreadsheetItemFormulaPropertyId', - 'UIA_ScrollPatternId', - 'UIA_IsTablePatternAvailablePropertyId', - 'UIA_GridItemColumnSpanPropertyId', - 'UIA_BeforeParagraphSpacingAttributeId', - 'SupportedTextSelection_Multiple', - 'RowOrColumnMajor_RowMajor', - 'UIA_WindowIsTopmostPropertyId', - 'UIA_IsKeyboardFocusablePropertyId', - 'UIA_EditControlTypeId', 'UIA_SemanticZoomControlTypeId', - 'IUIAutomation2', 'IUIAutomation3', 'IUIAutomation4', - 'IUIAutomation5', 'IUIAutomation6', - 'AnnotationType_InsertionChange', - 'UIA_WindowCanMaximizePropertyId', 'TextUnit_Paragraph', - 'ProviderOptions_OverrideProvider', 'DockPosition', - 'ExpandCollapseState_PartiallyExpanded', - 'IRawElementProviderSimple', 'UIA_TablePatternId', - 'UIA_AutomationFocusChangedEventId', + 'UIA_SystemAlertEventId', + 'UIA_IsDragPatternAvailablePropertyId', + 'ProviderOptions_UseClientCoordinates', + 'DockPosition_Right', 'IUIAutomationProxyFactoryEntry', + 'UIA_GridItemContainingGridPropertyId', 'UIA_TextChildPatternId', - 'UIA_DropTargetDropTargetEffectsPropertyId', - 'UIA_Selection_InvalidatedEventId', 'ProviderOptions', - 'StructureChangeType_ChildRemoved', - 'UIA_IsTransformPattern2AvailablePropertyId', - 'UIA_DragGrabbedItemsPropertyId', - 'UIA_GridItemRowSpanPropertyId', - 'AnnotationType_ConflictingChange', - 'UIA_AnnotationAuthorPropertyId', - 'UIA_IsSelectionPatternAvailablePropertyId', - 'OrientationType', 'UIA_StylesShapePropertyId', - 'UIA_LabeledByPropertyId', 'IUIAutomationElementArray', - 'IUIAutomationDragPattern', - 'UIA_StylesStyleNamePropertyId', - 'OrientationType_Horizontal', - 'UIA_AnnotationAnnotationTypeNamePropertyId', - 'AnnotationType_UnsyncedChange', - 'UIA_PositionInSetPropertyId', - 'IUIAutomationPropertyChangedEventHandler', - 'ProviderOptions_RefuseNonClientSupport', - 'IUIAutomationSelectionItemPattern', - 'UIA_DescribedByPropertyId', 'IUIAutomationStylesPattern', - 'UIA_IsReadOnlyAttributeId', 'UIA_Text_TextChangedEventId', - 'TextUnit', 'IUIAutomationProxyFactoryEntry', - 'SupportedTextSelection', - 'UIA_RangeValueLargeChangePropertyId', - 'UIA_TransformPattern2Id', 'UIA_VisualEffectsPropertyId', - 'TreeScope_Ancestors', - 'IUIAutomationCustomNavigationPattern', - 'ScrollAmount_SmallDecrement', - 'UIA_IsDataValidForFormPropertyId', - 'NotificationProcessing', - 'UIA_SayAsInterpretAsAttributeId', - 'UIA_TitleBarControlTypeId', 'IUIAutomationInvokePattern', - 'NavigateDirection_PreviousSibling', - 'ConnectionRecoveryBehaviorOptions_Disabled', - 'UIA_RangeValuePatternId', 'ZoomUnit', + 'UIA_LocalizedLandmarkTypePropertyId', + 'AnnotationType_Footnote', 'UIA_IsVirtualizedItemPatternAvailablePropertyId', - 'UIA_BulletStyleAttributeId', 'UIA_MarginTopAttributeId', - 'IUIAutomationGridPattern', 'DockPosition_Fill', - 'CUIAutomation', 'NotificationProcessing_ImportantAll', - 'UIA_HasKeyboardFocusPropertyId', 'StyleId_Subtitle', - 'UIA_IsTextPatternAvailablePropertyId', - 'UIA_ToggleToggleStatePropertyId', - 'ProviderOptions_HasNativeIAccessible', - 'UIA_TransformCanMovePropertyId', - 'UIA_ItemStatusPropertyId', - 'IUIAutomationScrollItemPattern', - 'IUIAutomationAnnotationPattern', - 'UIA_IsSubscriptAttributeId', 'UIA_SystemAlertEventId', - 'TextEditChangeType_CompositionFinalized', - 'UIA_FillColorPropertyId', 'UIA_TextEditPatternId', - 'UIA_LegacyIAccessibleNamePropertyId', - 'UIA_RadioButtonControlTypeId', - 'AnnotationType_FormulaError', - 'UIA_SplitButtonControlTypeId', - 'UIA_LegacyIAccessibleValuePropertyId', - 'UIA_IsCustomNavigationPatternAvailablePropertyId', - 'UIA_SpreadsheetPatternId', 'UIA_HeadingLevelPropertyId', - 'TextEditChangeType', 'AnnotationType_Footnote', - 'NotificationProcessing_CurrentThenMostRecent', - 'StructureChangeType_ChildrenBulkAdded', + 'IUIAutomationSelectionPattern2', + 'IUIAutomationTogglePattern', + 'UIA_OverlineStyleAttributeId', + 'UIA_IsTextChildPatternAvailablePropertyId', + 'StyleId_Heading8', 'UIA_StylesPatternId', + 'UIA_WindowCanMinimizePropertyId', + 'ZoomUnit_LargeIncrement', 'UIA_FormLandmarkTypeId', + 'UIA_HelpTextPropertyId', 'NotificationKind_Other', + 'IUIAutomationValuePattern', + 'UIA_DropTarget_DragLeaveEventId', + 'UIA_InputReachedOtherElementEventId', + 'UIA_IsMultipleViewPatternAvailablePropertyId', + 'AutomationElementMode', + 'UIA_OptimizeForVisualContentPropertyId', + 'NotificationProcessing_ImportantAll', + 'UIA_LineSpacingAttributeId', + 'UIA_CaretPositionAttributeId', + 'UIA_StructureChangedEventId', + 'UIA_ScrollBarControlTypeId', + 'UIA_IsSuperscriptAttributeId', + 'AnnotationType_FormulaError', 'UIA_MenuControlTypeId', + 'IUIAutomationLegacyIAccessiblePattern', + 'WindowVisualState_Minimized', + 'NavigateDirection_FirstChild', + 'AnnotationType_TrackChanges', 'UIA_IsDockPatternAvailablePropertyId', - 'CoalesceEventsOptions_Disabled', - 'IUIAutomationVirtualizedItemPattern', - 'UIA_AsyncContentLoadedEventId', 'StyleId_Title', - 'UIA_DropTargetDropTargetEffectPropertyId', 'Polite', - 'TextUnit_Character', 'UIA_FrameworkIdPropertyId', - 'UIA_DropTarget_DragEnterEventId', - 'TreeTraversalOptions_Default', - 'NotificationKind_ActionAborted', 'UIA_TableItemPatternId', - 'TreeScope_Descendants', 'UIA_TabItemControlTypeId', - 'IUIAutomationGridItemPattern', - 'NavigateDirection_LastChild', - 'UIA_IsSynchronizedInputPatternAvailablePropertyId', - 'UIA_TabsAttributeId', + 'UIA_MarginTopAttributeId', 'UIA_SizePropertyId', + 'UIA_RotationPropertyId', + 'AnnotationType_DataValidationError', + 'UIA_IsOffscreenPropertyId', 'UIA_ProcessIdPropertyId', + 'UIA_PositionInSetPropertyId', 'UIA_FrameworkIdPropertyId', + 'UIA_SelectionIsSelectionRequiredPropertyId', + 'UIA_BackgroundColorAttributeId', + 'ScrollAmount_LargeDecrement', 'UIA_DockPatternId', + 'UIA_SummaryChangeId', 'HeadingLevel1', + 'UIA_IsStylesPatternAvailablePropertyId', + 'AnnotationType_Footer', 'ExpandCollapseState_Expanded', + 'AnnotationType_GrammarError', 'DockPosition_None', + 'ExpandCollapseState', 'UIA_CustomLandmarkTypeId', + 'UIA_CaretBidiModeAttributeId', + 'IUIAutomationProxyFactoryMapping', + 'UIA_MarginLeadingAttributeId', 'UIA_PaneControlTypeId', + 'TextUnit_Page', 'UIA_RangeValueMinimumPropertyId', + 'IUIAutomationElement9', 'WindowVisualState_Normal', + 'WindowInteractionState_BlockedByModalWindow', + 'CoalesceEventsOptions_Disabled', 'TreeScope', + 'UIA_ComboBoxControlTypeId', + 'UIA_SelectionCanSelectMultiplePropertyId', + 'UIA_HostedFragmentRootsInvalidatedEventId', + 'StructureChangeType_ChildAdded', + 'UIA_AppBarControlTypeId', + 'UIA_IsSelectionPatternAvailablePropertyId', + 'CUIAutomation', 'UIA_ExpandCollapsePatternId', + 'ProviderOptions_OverrideProvider', + 'CoalesceEventsOptions', 'IUIAutomationTransformPattern2', + 'UIA_ClassNamePropertyId', 'UIA_MenuItemControlTypeId', + 'UIA_DragIsGrabbedPropertyId', + 'WindowInteractionState_NotResponding', + 'UIA_IsDropTargetPatternAvailablePropertyId', + 'UIA_MultipleViewCurrentViewPropertyId', + 'UIA_IndentationFirstLineAttributeId', + 'UIA_IsContentElementPropertyId', + 'IUIAutomationDockPattern', + 'UIA_Transform2ZoomLevelPropertyId', 'IUIAutomation4', + 'UIA_AnnotationAuthorPropertyId', + 'UIA_TabItemControlTypeId', 'IUIAutomationElement4', + 'NotificationKind', 'UIA_FontSizeAttributeId', 'Polite', + 'TreeScope_Subtree', 'UIA_CapStyleAttributeId', + 'ScrollAmount', 'IUIAutomationAnnotationPattern', + 'IUIAutomationElement2', 'TextEditChangeType_None', 'StructureChangeType_ChildrenInvalidated', - 'IUIAutomationTablePattern', 'AnnotationType_TrackChanges', - 'ZoomUnit_NoAmount', - 'UIA_IsTogglePatternAvailablePropertyId', - 'UIA_ToolTipClosedEventId', - 'UIA_IsRangeValuePatternAvailablePropertyId', - 'UIA_GridItemRowPropertyId', + 'UIA_IndentationLeadingAttributeId', + 'UIA_DataItemControlTypeId', + 'UIA_Selection2CurrentSelectedItemPropertyId', + 'UIA_SeparatorControlTypeId', 'IUIAutomation2', + 'UIA_ScrollHorizontalScrollPercentPropertyId', 'UIA_IsTableItemPatternAvailablePropertyId', - 'StyleId_Heading8', 'UIA_AriaPropertiesPropertyId', - 'UIA_CustomNavigationPatternId', - 'UIA_WindowIsModalPropertyId', 'UIA_ControlTypePropertyId', - 'ScrollAmount_NoAmount', 'RowOrColumnMajor', - 'ProviderOptions_NonClientAreaProvider', - 'UIA_ItemTypePropertyId', - 'UIA_IsTextChildPatternAvailablePropertyId', - 'UIA_HelpTextPropertyId', 'UIA_CultureAttributeId', - 'IUIAutomationEventHandlerGroup', 'NotificationKind_Other', + 'TreeScope_Children', 'AutomationElementMode_Full', + 'StyleId_NumberedList', 'UIA_OutlineColorPropertyId', + 'UIA_Selection2FirstSelectedItemPropertyId', + 'SynchronizedInputType_LeftMouseDown', 'IUIAutomation', + 'UIA_IsTextPattern2AvailablePropertyId', + 'UIA_HeaderItemControlTypeId', + 'UIA_LegacyIAccessibleDescriptionPropertyId', + 'StyleId_Heading1', 'UIA_CustomNavigationPatternId', + 'UIA_TextControlTypeId', 'IRawElementProviderSimple', + 'UIA_TogglePatternId', 'UIA_FontWeightAttributeId', + 'UIA_ValueValuePropertyId', 'UIA_IsEnabledPropertyId', + 'IUIAutomationCondition', 'NavigateDirection_LastChild', + 'SynchronizedInputType', 'UIA_ItemStatusPropertyId', + 'UIA_IsTablePatternAvailablePropertyId', + 'UIA_RuntimeIdPropertyId', + 'UIA_TableItemRowHeaderItemsPropertyId', + 'AnnotationType_EditingLockedChange', + 'IUIAutomationEventHandler', + 'IUIAutomationSelectionPattern', 'UIA_CustomControlTypeId', + 'RowOrColumnMajor_RowMajor', + 'UIA_LiveRegionChangedEventId', + 'UIA_WindowWindowVisualStatePropertyId', + 'ProviderOptions_ServerSideProvider', + 'IUIAutomationTextRange3', 'UIA_FullDescriptionPropertyId', + 'UIA_TextEditPatternId', 'UIA_FlowsToPropertyId', + 'UIA_LegacyIAccessibleKeyboardShortcutPropertyId', + 'IUIAutomationGridItemPattern', 'UIA_LegacyIAccessibleHelpPropertyId', - 'UIA_AccessKeyPropertyId', 'StyleId_Heading2', - 'StructureChangeType_ChildAdded', - 'UIA_TableRowHeadersPropertyId', - 'IUIAutomationLegacyIAccessiblePattern', - 'UIA_FillTypePropertyId', - 'UIA_IsItemContainerPatternAvailablePropertyId', - 'UIA_IndentationFirstLineAttributeId', 'StyleId_Emphasis', - 'UIA_GroupControlTypeId', 'UIA_ProcessIdPropertyId', - 'UIA_OverlineStyleAttributeId', - 'UIA_ScrollHorizontallyScrollablePropertyId', + 'AnnotationType_Comment', 'UIA_OutlineThicknessPropertyId', + 'UIA_TablePatternId', 'UIA_GridPatternId', + 'ProviderOptions_HasNativeIAccessible', + 'UIA_SelectionActiveEndAttributeId', + 'UIA_GridColumnCountPropertyId', + 'NavigateDirection_PreviousSibling', 'UIA_StylesFillColorPropertyId', - 'UIA_Transform2ZoomMinimumPropertyId', - 'IUIAutomationNotificationEventHandler', - 'UIA_TabControlTypeId', 'UIA_GridPatternId'] + 'UIA_IsSpreadsheetPatternAvailablePropertyId', + 'ProviderOptions', 'IUIAutomationTextPattern2', + 'UIA_FontNameAttributeId', + 'UIA_IsGridItemPatternAvailablePropertyId', + 'TreeScope_Parent', 'IUIAutomationScrollPattern', + 'AnnotationType_Endnote', 'NotificationKind_ActionAborted', + 'SupportedTextSelection_None', 'UIA_ValuePatternId', + 'UIA_IsItalicAttributeId', 'UIA_WindowControlTypeId', + 'UIA_RangeValueLargeChangePropertyId', + 'TreeTraversalOptions_PostOrder', + 'IUIAutomationSelectionItemPattern', + 'TextEditChangeType_Composition', + 'NotificationProcessing_CurrentThenMostRecent', + 'UIA_ScrollVerticallyScrollablePropertyId', + 'HeadingLevel_None', 'UIA_HeadingLevelPropertyId', + 'AnnotationType_MoveChange', + 'WindowInteractionState_Closing', + 'IUIAutomationTextRange2', 'UIA_MarginBottomAttributeId', + 'PropertyConditionFlags_MatchSubstring', + 'UIA_IsSynchronizedInputPatternAvailablePropertyId', + 'UIA_MenuModeStartEventId', 'UIA_NavigationLandmarkTypeId', + 'StyleId_Heading5', 'AnnotationType_UnsyncedChange', + 'UIA_SearchLandmarkTypeId', 'UIA_GridItemPatternId', + 'IUIAutomationTreeWalker', 'ScrollAmount_LargeIncrement', + 'IUIAutomationElement', 'ExpandCollapseState_Collapsed', + 'AnnotationType_InsertionChange', 'StructureChangeType', + 'UIA_LabeledByPropertyId', 'UIA_TransformPatternId', + 'PropertyConditionFlags_IgnoreCase', + 'ScrollAmount_SmallDecrement', + 'UIA_VirtualizedItemPatternId', 'IUIAutomationElement3', + 'SupportedTextSelection_Single', + 'IUIAutomationWindowPattern', + 'UIA_VisualEffectsPropertyId', + 'UIA_AnnotationObjectsPropertyId', + 'UIA_ClickablePointPropertyId', + 'IUIAutomationChangesEventHandler', 'DockPosition_Top', + 'UIA_SelectionPattern2Id', + 'UIA_SayAsInterpretAsAttributeId', 'UIA_LinkAttributeId', + 'UIA_StyleNameAttributeId', 'UIA_LayoutInvalidatedEventId', + 'UIA_ThumbControlTypeId', 'UIA_ChangesEventId', + 'StructureChangeType_ChildrenBulkRemoved', + 'NavigateDirection_Parent', + 'UIA_WindowWindowInteractionStatePropertyId', + 'UIA_AriaPropertiesPropertyId', 'UIA_IsPasswordPropertyId', + 'UIA_ScrollHorizontalViewSizePropertyId', + 'UIA_LegacyIAccessiblePatternId', + 'OrientationType_Horizontal', + 'UIA_AnnotationTypesPropertyId', 'TextUnit_Paragraph', + 'WindowInteractionState_Running', 'StyleId_Normal'] from comtypes import _check_version; _check_version('') diff --git a/source/comInterfaces_sconscript b/source/comInterfaces_sconscript index abae66c79bc..fe29e33ac76 100755 --- a/source/comInterfaces_sconscript +++ b/source/comInterfaces_sconscript @@ -16,6 +16,8 @@ Import( 'env', ) +import importlib.util + def interfaceAction(target,source,env): clsid=env.get('clsid') if clsid: @@ -46,12 +48,12 @@ COM_INTERFACES = { "FlashAccessibility.py": "typelibs/FlashAccessibility.tlb", } -for k,v in COM_INTERFACES.iteritems(): +for k,v in COM_INTERFACES.items(): targets=[Dir('comInterfaces').File(k), # This buillds a .pyc file as well. - Dir('comInterfaces').File(k + "c")] + Dir('comInterfaces').File(importlib.util.cache_from_source(k))] source=clsid=majorVersion=None - if isinstance(v,basestring): + if isinstance(v, str): env.comtypesInterface(targets,v) else: env.comtypesInterface(targets,Dir('comInterfaces').File('__init__.py'),clsid=v[0],majorVersion=v[1],minorVersion=v[2]) diff --git a/source/compoundDocuments.py b/source/compoundDocuments.py index 17190f23956..4f0d9bbcdc8 100644 --- a/source/compoundDocuments.py +++ b/source/compoundDocuments.py @@ -173,6 +173,11 @@ def __eq__(self, other): return False return self._start == other._start and self._startObj == other._startObj and self._end == other._end and self._endObj == other._endObj + # As __eq__ was defined on this class, we must provide __hash__ to remain hashable. + # The default hash implementation is fine for our purposes. + def __hash__(self): + return super().__hash__() + def __ne__(self, other): return not self == other @@ -268,7 +273,7 @@ def getTextWithFields(self, formatConfig=None): embedIndex = None for ti in self._getTextInfos(): for field in ti._iterTextWithEmbeddedObjects(True, formatConfig=formatConfig): - if isinstance(field, basestring): + if isinstance(field, str): fields.append(field) elif isinstance(field, int): # Embedded object if embedIndex is None: @@ -319,7 +324,13 @@ def compareEndPoints(self, other, which): return selfTi.compareEndPoints(otherTi, which) # Different objects, so we have to compare the hierarchical positions of the objects. - return cmp(self._getObjectPosition(selfObj), other._getObjectPosition(otherObj)) + # cmp no longer exists in Python3. + # Per the Python3 What's New docs: + # cmp can be replaced with (a>b)-(aotherPosition)-(selfPosition= levelNames.get(logLevelName)): + if log.isEnabledFor(log.DEBUG) or (logLevelName and DEBUG >= logging.getLevelName(logLevelName)): # Log at level info to ensure that the profile is logged. log.info(u"Config loaded (after upgrade, and in the state it will be used by NVDA):\n{0}".format(profile)) return profile @@ -507,7 +506,7 @@ def getProfile(self, name): """Get a profile given its name. This is useful for checking whether a profile has been manually activated or triggered. @param name: The name of the profile. - @type name: basestring + @type name: str @return: The profile object. @raise KeyError: If the profile is not loaded. """ @@ -519,7 +518,7 @@ def manualActivateProfile(self, name): If another profile was manually activated, deactivate it first. If C{name} is C{None}, a profile will not be activated. @param name: The name of the profile or C{None} for no profile. - @type name: basestring + @type name: str """ if len(self.profiles) > 1: profile = self.profiles[-1] @@ -579,7 +578,7 @@ def reset(self, factoryDefaults=False): def createProfile(self, name): """Create a profile. @param name: The name of the profile to create. - @type name: basestring + @type name: str @raise ValueError: If a profile with this name already exists. """ if globalVars.appArgs.secure: @@ -588,7 +587,7 @@ def createProfile(self, name): if os.path.isfile(fn): raise ValueError("A profile with the same name already exists: %s" % name) # Just create an empty file to make sure we can. - file(fn, "w") + open(fn, "w").close() # Register a script for the new profile. # Import late to avoid circular import. from globalCommands import ConfigProfileActivationCommands @@ -597,7 +596,7 @@ def createProfile(self, name): def deleteProfile(self, name): """Delete a profile. @param name: The name of the profile to delete. - @type name: basestring + @type name: str @raise LookupError: If the profile doesn't exist. """ if globalVars.appArgs.secure: @@ -617,7 +616,7 @@ def deleteProfile(self, name): # Remove any triggers associated with this profile. allTriggers = self.triggersToProfiles # You can't delete from a dict while iterating through it. - delTrigs = [trigSpec for trigSpec, trigProfile in allTriggers.iteritems() + delTrigs = [trigSpec for trigSpec, trigProfile in allTriggers.items() if trigProfile == name] if delTrigs: for trigSpec in delTrigs: @@ -625,7 +624,7 @@ def deleteProfile(self, name): self.saveProfileTriggers() # Check if this profile was active. delProfile = None - for index in xrange(len(self.profiles) - 1, -1, -1): + for index in range(len(self.profiles) - 1, -1, -1): profile = self.profiles[index] if profile.name == name: # Deactivate it. @@ -636,16 +635,17 @@ def deleteProfile(self, name): self._handleProfileSwitch() if self._suspendedTriggers: # Remove any suspended triggers referring to this profile. - for trigger in self._suspendedTriggers.keys(): + # As the dictionary changes during iteration, wrap this inside a list call. + for trigger in list(self._suspendedTriggers): if trigger._profile == delProfile: del self._suspendedTriggers[trigger] def renameProfile(self, oldName, newName): """Rename a profile. @param oldName: The current name of the profile. - @type oldName: basestring + @type oldName: str @param newName: The new name for the profile. - @type newName: basestring + @type newName: str @raise LookupError: If the profile doesn't exist. @raise ValueError: If a profile with the new name already exists. """ @@ -666,7 +666,7 @@ def renameProfile(self, oldName, newName): # Update any associated triggers. allTriggers = self.triggersToProfiles saveTrigs = False - for trigSpec, trigProfile in allTriggers.iteritems(): + for trigSpec, trigProfile in allTriggers.items(): if trigProfile == oldName: allTriggers[trigSpec] = newName saveTrigs = True @@ -780,7 +780,7 @@ def resumeProfileTriggers(self): triggers = self._suspendedTriggers self._suspendedTriggers = None with self.atomicProfileSwitch(): - for trigger, action in triggers.iteritems(): + for trigger, action in triggers.items(): trigger.enter() if action == "enter" else trigger.exit() def disableProfileTriggers(self): @@ -989,7 +989,7 @@ def _cacheLeaf(self, key, spec, val): def __iter__(self): keys = set() # Start with the cached items. - for key, val in self._cache.iteritems(): + for key, val in self._cache.items(): keys.add(key) if val is not KeyError: yield key @@ -1003,7 +1003,7 @@ def __iter__(self): keys.add(key) yield key - def iteritems(self): + def items(self): for key in self: try: yield (key, self[key]) @@ -1012,14 +1012,14 @@ def iteritems(self): pass def copy(self): - return dict(self.iteritems()) + return dict(self.items()) def dict(self): """Return a deepcopy of self as a dictionary. Adapted from L{configobj.Section.dict}. """ newdict = {} - for key, value in self.iteritems(): + for key, value in self.items(): if isinstance(value, AggregatedSection): value = value.dict() elif isinstance(value, list): @@ -1130,7 +1130,7 @@ class ProfileTrigger(object): def spec(self): """The trigger specification. This is a string used to search for this trigger in the user's configuration. - @rtype: basestring + @rtype: str """ raise NotImplementedError diff --git a/source/config/configSpec.py b/source/config/configSpec.py index fdc4e0114b5..ab9c894269b 100644 --- a/source/config/configSpec.py +++ b/source/config/configSpec.py @@ -4,7 +4,7 @@ #This file is covered by the GNU General Public License. #See the file COPYING for more details. -from cStringIO import StringIO +from io import StringIO from configobj import ConfigObj #: The version of the schema outlined in this file. Increment this when modifying the schema and diff --git a/source/config/profileUpgrader.py b/source/config/profileUpgrader.py index e138fdabfec..1ce5dbb1097 100644 --- a/source/config/profileUpgrader.py +++ b/source/config/profileUpgrader.py @@ -20,7 +20,7 @@ def upgrade(profile, validator, writeProfileToFileFunc): _ensureVersionProperty(profile) startSchemaVersion = int(profile[SCHEMA_VERSION_KEY]) log.debug("Current config schema version: {0}, latest: {1}".format(startSchemaVersion, latestSchemaVersion)) - for fromVersion in xrange(startSchemaVersion, latestSchemaVersion): + for fromVersion in range(startSchemaVersion, latestSchemaVersion): _doConfigUpgrade(profile, fromVersion) _doValidation(deepcopy(profile), validator) # copy the profile, since validating mutates the object try: @@ -66,7 +66,7 @@ def _doValidation(profile, validator): raise ValueError(errorString) def _ensureVersionProperty(profile): - isEmptyProfile = 1 > len(profile.keys()) + isEmptyProfile = 1 > len(profile) if isEmptyProfile: log.debug("Empty profile, triggering default schema version") profile[SCHEMA_VERSION_KEY] = latestSchemaVersion diff --git a/source/contentRecog/__init__.py b/source/contentRecog/__init__.py index 2c26da70325..6536772e9bb 100644 --- a/source/contentRecog/__init__.py +++ b/source/contentRecog/__init__.py @@ -16,10 +16,9 @@ from collections import namedtuple import textInfos.offsets from abc import ABCMeta, abstractmethod -from six import with_metaclass from locationHelper import RectLTWH -class ContentRecognizer(with_metaclass(ABCMeta, object)): +class ContentRecognizer(object, metaclass=ABCMeta): """Implementation of a content recognizer. """ @@ -129,7 +128,7 @@ def convertHeightToScreen(self, height): """ return int(height / self.resizeFactor) -class RecognitionResult(with_metaclass(ABCMeta, object)): +class RecognitionResult(object, metaclass=ABCMeta): """Provides access to the result of recognition by a recognizer. The result is textual, but to facilitate navigation by word, line, etc. and to allow for retrieval of screen coordinates within the text, @@ -221,6 +220,8 @@ class LwrTextInfo(textInfos.offsets.OffsetsTextInfo): This should only be instantiated by L{LinesWordsResult}. """ + encoding = None + def __init__(self, obj, position, result): self.result = result super(LwrTextInfo, self).__init__(obj, position) @@ -283,6 +284,8 @@ class SimpleResultTextInfo(textInfos.offsets.OffsetsTextInfo): This should only be instantiated by L{SimpleTextResult}. """ + encoding = None + def __init__(self, obj, position, result): self.result = result super(SimpleResultTextInfo, self).__init__(obj, position) diff --git a/source/contentRecog/uwpOcr.py b/source/contentRecog/uwpOcr.py index 119470fb774..2db83e5cae4 100644 --- a/source/contentRecog/uwpOcr.py +++ b/source/contentRecog/uwpOcr.py @@ -21,7 +21,7 @@ def getLanguages(): @return: A list of language codes suitable to be passed to L{UwpOcr}'s constructor. These need to be normalized with L{languageHandler.normalizeLanguage} for use as NVDA language codes. - @rtype: list of unicode + @rtype: list of str """ dll = NVDAHelper.getHelperLocalWin10Dll() dll.uwpOcr_getLanguages.restype = NVDAHelper.bstrReturn diff --git a/source/core.py b/source/core.py index b03b94587b6..52e420bb2fe 100644 --- a/source/core.py +++ b/source/core.py @@ -7,19 +7,27 @@ """NVDA core""" -# Do this first to initialise comtypes.client.gen_dir and the comtypes.gen search path. +RPC_E_CALL_CANCELED = -2147418110 + +class CallCancelled(Exception): + """Raised when a call is cancelled. + """ + +# Apply several monkey patches to comtypes +# noinspection PyUnresolvedReferences +import comtypesMonkeyPatches + +# Initialise comtypes.client.gen_dir and the comtypes.gen search path +# and Append our comInterfaces directory to the comtypes.gen search path. +import comtypes import comtypes.client -# Append our comInterfaces directory to the comtypes.gen search path. import comtypes.gen import comInterfaces comtypes.gen.__path__.append(comInterfaces.__path__[0]) -#Apply several monky patches to comtypes -import comtypesMonkeyPatches - import sys import winVersion -import thread +import threading import nvwave import os import time @@ -37,7 +45,7 @@ PUMP_MAX_DELAY = 10 #: The thread identifier of the main thread. -mainThreadId = thread.get_ident() +mainThreadId = threading.get_ident() #: Notifies when a window message has been received by NVDA. #: This allows components to perform an action when several system events occur, @@ -125,8 +133,8 @@ def restart(disableAddons=False, debugLogging=False): except ValueError: pass shellapi.ShellExecute(None, None, - sys.executable.decode("mbcs"), - subprocess.list2cmdline(sys.argv + options).decode("mbcs"), + sys.executable, + subprocess.list2cmdline(sys.argv + options), None, # #4475: ensure that the first window of the new process is not hidden by providing SW_SHOWNORMAL winUser.SW_SHOWNORMAL) @@ -255,7 +263,8 @@ def main(): # wxPython 4 no longer has either of these constants (despite the documentation saying so), some add-ons may rely on # them so we add it back into wx. https://wxpython.org/Phoenix/docs/html/wx.Window.html#wx.Window.Centre wx.CENTER_ON_SCREEN = wx.CENTRE_ON_SCREEN = 0x2 - log.info("Using wx version %s"%wx.version()) + import six + log.info("Using wx version %s with six version %s"%(wx.version(), six.__version__)) class App(wx.App): def OnAssert(self,file,line,cond,msg): message="{file}, line {line}:\nassert {cond}: {msg}".format(file=file,line=line,cond=cond,msg=msg) @@ -375,7 +384,7 @@ def handlePowerStatusChange(self): #Translators: Reported when the battery is no longer plugged in, and now is not charging. ui.message(_("Not charging battery. %d percent") %sps.BatteryLifePercent) - messageWindow = MessageWindow(unicode(versionInfo.name)) + messageWindow = MessageWindow(versionInfo.name) # initialize wxpython localization support locale = wx.Locale() @@ -384,7 +393,7 @@ def handlePowerStatusChange(self): if not wxLang and '_' in lang: wxLang=locale.FindLanguageInfo(lang.split('_')[0]) if hasattr(sys,'frozen'): - locale.AddCatalogLookupPathPrefix(os.path.join(os.getcwdu(),"locale")) + locale.AddCatalogLookupPathPrefix(os.path.join(os.getcwd(),"locale")) # #8064: Wx might know the language, but may not actually contain a translation database for that language. # If we try to initialize this language, wx will show a warning dialog. # #9089: some languages (such as Aragonese) do not have language info, causing language getter to fail. @@ -584,7 +593,7 @@ def requestPump(): if not _pump or _isPumpPending: return _isPumpPending = True - if thread.get_ident() == mainThreadId: + if threading.get_ident() == mainThreadId: _pump.Start(PUMP_MAX_DELAY, True) return # This isn't the main thread. wx timers cannot be run outside the main thread. @@ -599,7 +608,7 @@ def callLater(delay, callable, *args, **kwargs): This function can be safely called from any thread. """ import wx - if thread.get_ident() == mainThreadId: + if threading.get_ident() == mainThreadId: return wx.CallLater(delay, _callLaterExec, callable, args, kwargs) else: return wx.CallAfter(wx.CallLater,delay, _callLaterExec, callable, args, kwargs) diff --git a/source/displayModel.py b/source/displayModel.py index b740b49d84e..7a32b0b3c6c 100644 --- a/source/displayModel.py +++ b/source/displayModel.py @@ -21,6 +21,7 @@ from logHandler import log import windowUtils from locationHelper import RectLTRB, RectLTWH +import textUtils def wcharToInt(c): i=ord(c) @@ -42,22 +43,22 @@ def normalizeRtlString(s): d=unicodedata.decomposition(c) d=d.split(' ') if d else None if d and len(d)==2 and d[0] in ('','','',''): - c=unichr(int(d[1],16)) + c=chr(int(d[1],16)) l.append(c) return u"".join(l) def yieldListRange(l,start,stop): - for x in xrange(start,stop): + for x in range(start,stop): yield l[x] def processWindowChunksInLine(commandList,rects,startIndex,startOffset,endIndex,endOffset): windowStartIndex=startIndex lastEndOffset=windowStartOffset=startOffset lastHwnd=None - for index in xrange(startIndex,endIndex+1): + for index in range(startIndex,endIndex+1): item=commandList[index] if index0 else None:-1] rectsStart=runStartOffset - for i in xrange(runStartIndex,index,2): + for i in range(runStartIndex,index,2): command=commandList[i] text=commandList[i+1] - rectsEnd=rectsStart+len(text) + rectsEnd = rectsStart + textUtils.WideStringOffsetConverter(text).wideStringLength commandList[i+1]=command shouldReverseText=command.field.get('shouldReverseText',True) commandList[i]=normalizeRtlString(text[::-1] if shouldReverseText else text) @@ -243,8 +244,8 @@ def _getSelectionOffsets(self): inHighlightChunk=True if startOffset is None: startOffset=curOffset - elif isinstance(item,basestring): - curOffset+=len(item) + elif isinstance(item,str): + curOffset += textUtils.WideStringOffsetConverter(item).wideStringLength if inHighlightChunk: endOffset=curOffset else: @@ -293,10 +294,10 @@ def _get__storyFieldsAndRects(self): lineStartIndex=0 lineBaseline=None lineEndOffsets=[] - for index in xrange(len(commandList)): + for index in range(len(commandList)): item=commandList[index] - if isinstance(item,basestring): - lastEndOffset+=len(item) + if isinstance(item,str): + lastEndOffset += textUtils.WideStringOffsetConverter(item).wideStringLength elif isinstance(item,textInfos.FieldCommand): if isinstance(item.field,textInfos.FormatField): curFormatField=item.field @@ -309,7 +310,13 @@ def _get__storyFieldsAndRects(self): processWindowChunksInLine(commandList,rects,lineStartIndex,lineStartOffset,index,lastEndOffset) #Convert the whitespace at the end of the line into a line feed item=commandList[index-1] - if isinstance(item,basestring) and len(item)==1 and item.isspace(): + if ( + isinstance(item,str) + # Since we're searching for white space, it is safe to + # do this opperation on the length of the pythonic string + and len(item)==1 + and item.isspace() + ): commandList[index-1]=u'\n' lineEndOffsets.append(lastEndOffset) if baseline is not None: @@ -327,8 +334,8 @@ def _getStoryOffsetLocations(self): if isinstance(item,textInfos.FieldCommand) and isinstance(item.field,textInfos.FormatField): baseline=item.field['baseline'] direction=item.field['direction'] - elif isinstance(item,basestring): - endOffset=lastEndOffset+len(item) + elif isinstance(item,str): + endOffset = lastEndOffset + textUtils.WideStringOffsetConverter(item).wideStringLength for rect in rects[lastEndOffset:endOffset]: yield rect,baseline,direction lastEndOffset=endOffset @@ -340,10 +347,10 @@ def _getFieldsInRange(self,start,end): #Strip unwanted commands and text from the start and the end to honour the requested offsets lastEndOffset=0 startIndex=endIndex=relStart=relEnd=None - for index in xrange(len(storyFields)): + for index in range(len(storyFields)): item=storyFields[index] - if isinstance(item,basestring): - endOffset=lastEndOffset+len(item) + if isinstance(item,str): + endOffset = lastEndOffset + textUtils.WideStringOffsetConverter(item).wideStringLength if lastEndOffset<=start=len(rects): raise RuntimeError("offset %d out of range") - left,top,right,bottom=rects[offset] - x=left #+(right-left)/2 - y=top+(bottom-top)/2 + rect = rects[offset] + x = rect.left + y= rect.center.y x,y=windowUtils.logicalToPhysicalPoint(self.obj.windowHandle,x,y) oldX,oldY=winUser.getCursorPos() winUser.setCursorPos(x,y) diff --git a/source/easeOfAccess.py b/source/easeOfAccess.py index 5efcc212415..ba4729c5271 100644 --- a/source/easeOfAccess.py +++ b/source/easeOfAccess.py @@ -7,10 +7,7 @@ """Utilities for working with the Windows Ease of Access Center. """ -try: - import _winreg as winreg # Python 2.7 import -except ImportError: - import winreg # Python 3 import +import winreg import ctypes import winUser from winVersion import winVersion diff --git a/source/editableText.py b/source/editableText.py index e00f6512a72..ce146185ac2 100755 --- a/source/editableText.py +++ b/source/editableText.py @@ -127,6 +127,8 @@ def _caretScriptPostMovedHelper(self, speakUnit, gesture, info=None): info = self.makeTextInfo(textInfos.POSITION_CARET) except: return + # Forget the word currently being typed as the user has moved the caret somewhere else. + speech.clearTypedWordBuffer() review.handleCaretMove(info) if speakUnit and not willSayAllResume(gesture): info.expand(speakUnit) @@ -134,8 +136,6 @@ def _caretScriptPostMovedHelper(self, speakUnit, gesture, info=None): braille.handler.handleCaretMove(self) def _caretMovementScriptHelper(self, gesture, unit): - # Forget the word currently being typed as the user is moving the caret somewhere else. - speech.clearTypedWordBuffer() try: info=self.makeTextInfo(textInfos.POSITION_CARET) except: diff --git a/source/extensionPoints/util.py b/source/extensionPoints/util.py index 684036192d0..eeed950a452 100644 --- a/source/extensionPoints/util.py +++ b/source/extensionPoints/util.py @@ -82,9 +82,11 @@ def register(self, handler): However, the callable must be kept alive by your code otherwise it will be de-registered. This is due to the use of weak references. This is especially relevant when using lambdas. """ - if hasattr(handler, "__self__"): - if not handler.__self__: + if inspect.isfunction(handler): + sig = inspect.signature(handler) + if sig.parameters and list(sig.parameters)[0] == "self": raise TypeError("Registering unbound instance methods not supported.") + if inspect.ismethod(handler): weak = BoundMethodWeakref(handler, self.unregister) else: weak = AnnotatableWeakref(handler, self.unregister) @@ -125,7 +127,10 @@ def callWithSupportedKwargs(func, *args, **kwargs): Instead of raising a TypeError, myFunc will simply be called like this: C{myFunc(a=1, b=2)} - While C{callWithSupportedKwargs} does support positional arguments (C{*args}), usage is strongly discouraged due to the + C{callWithSupportedKwargs} does support positional arguments (C{*args}). + Unfortunately, positional args can not be matched on name (keyword) + to the names of the params in the handler. + Therefore, usage is strongly discouraged due to the risk of parameter order differences causing bugs. @param func: can be any callable that is not an unbound method. EG: @@ -134,6 +139,7 @@ def callWithSupportedKwargs(func, *args, **kwargs): - static methods - functions - lambdas + - partials The arguments for the supplied callable, C{func}, do not need to have default values, and can take C{**kwargs} to capture all arguments. @@ -143,43 +149,22 @@ def callWithSupportedKwargs(func, *args, **kwargs): - the number of positional arguments given can not be received by C{func}. - parameters required (parameters declared with no default value) by C{func} are not supplied. """ - spec = inspect.getargspec(func) - - # some handlers are instance/class methods, discard "self"/"cls" because it is typically passed implicitly. - if inspect.ismethod(func): - spec.args.pop(0) # remove "self"/"cls" for instance methods - if not hasattr(func, "__self__"): - raise TypeError("Unbound instance methods are not handled.") - - # Ensure that the positional args provided by the caller of `callWithSupportedKwargs` actually have a place to go. - # Unfortunately, positional args can not be matched on name (keyword) to the names of the params in the handler, - # and so calling `callWithSupportedKwargs` is at risk of causing bugs if parameter order differs. - numExpectedArgs = len(spec.args) - numGivenPositionalArgs = len(args) - if numGivenPositionalArgs > numExpectedArgs: - raise TypeError("Expected to be able to pass {} positional arguments.".format(numGivenPositionalArgs)) - - # Ensure that all arguments without defaults which are expected by the handler were provided. - # `defaults` is a tuple of default argument values or None if there are no default arguments; - # if this tuple has N elements, they correspond to the last N elements listed in args. - numExpectedArgsWithDefaults = len(spec.defaults) if spec.defaults else 0 - if not spec.defaults or numExpectedArgsWithDefaults != numExpectedArgs: - # get the names of the args without defaults, skipping the N positional args given to `callWithSupportedKwargs` - # positionals are required for the Filter extension point. - givenKwargsKeys = set(kwargs.keys()) - firstArgWithDefault = numExpectedArgs - numExpectedArgsWithDefaults - specArgs = set(spec.args[numGivenPositionalArgs:firstArgWithDefault]) - for arg in specArgs: - # and ensure they are in the kwargs list - if arg not in givenKwargsKeys: - raise TypeError("Parameter required for handler not provided: {}".format(arg)) - - if spec.keywords: - # func has a catch-all for kwargs (**kwargs) so we do not need to filter to just the supported args. - return func(*args, **kwargs) - - supportedKwargs = set(spec.args) - for kwarg in kwargs.keys(): - if kwarg not in supportedKwargs: - del kwargs[kwarg] - return func(*args, **kwargs) \ No newline at end of file + sig = inspect.signature(func) + + if inspect.isfunction(func) and sig.parameters and list(sig.parameters)[0] == "self": + raise TypeError("Unbound instance methods are not handled.") + + # Check whether func has a catch-all for kwargs (**kwargs) + # In this case, we do not need to filter to just the supported args. + if not any( + param for param in sig.parameters.values() + if param.kind == param.VAR_KEYWORD + ): + # Delete all the kwargs that are not supported by this callable. + # Wrap the items call in a list, as the dictionary changes during iteration. + for kwarg in list(kwargs.keys()): + if kwarg not in sig.parameters: + del kwargs[kwarg] + + boundArguments = sig.bind(*args, **kwargs) + return func(*boundArguments.args, **boundArguments.kwargs) diff --git a/source/fileUtils.py b/source/fileUtils.py index f9147b18c59..ff793fb0824 100644 --- a/source/fileUtils.py +++ b/source/fileUtils.py @@ -1,8 +1,9 @@ #fileUtils.py #A part of NonVisual Desktop Access (NVDA) -#Copyright (C) 2017 NV Access Limited, Bram Duvigneau +#Copyright (C) 2017-2019 NV Access Limited, Bram Duvigneau #This file is covered by the GNU General Public License. #See the file COPYING for more details. + import os import ctypes import ctypes.wintypes @@ -11,9 +12,7 @@ from tempfile import NamedTemporaryFile from logHandler import log from six import text_type - -#: Constant; flag for MoveFileEx(). If a file with the destination filename already exists, it is overwritten. -MOVEFILE_REPLACE_EXISTING = 1 +import winKernel @contextmanager def FaultTolerantFile(name): @@ -39,9 +38,7 @@ def FaultTolerantFile(name): f.flush() os.fsync(f) f.close() - moveFileResult = ctypes.windll.kernel32.MoveFileExW(f.name, name, MOVEFILE_REPLACE_EXISTING) - if moveFileResult == 0: - raise ctypes.WinError() + winKernel.moveFileEx(f.name, name, winKernel.MOVEFILE_REPLACE_EXISTING) def getFileVersionInfo(name, *attributes): """Gets the specified file version info attributes from the provided file.""" diff --git a/source/globalCommands.py b/source/globalCommands.py index 17df752e8a6..cc6b4e53930 100755 --- a/source/globalCommands.py +++ b/source/globalCommands.py @@ -707,8 +707,8 @@ def script_moveMouseToNavigatorObject(self,gesture): # Translators: Reported when the object has no location for the mouse to move to it. ui.message(_("Object has no location")) return - x=left+(width/2) - y=top+(height/2) + x=left+(width//2) + y=top+(height//2) winUser.setCursorPos(x,y) mouseHandler.executeMouseMoveEvent(x,y) # Translators: Input help mode message for move mouse to navigator object command. @@ -779,8 +779,9 @@ def script_navigatorObject_current(self,gesture): if scriptHandler.getLastScriptRepeatCount()>=1: if curObject.TextInfo!=NVDAObjectTextInfo: textList=[] - if curObject.name and isinstance(curObject.name, basestring) and not curObject.name.isspace(): - textList.append(curObject.name) + name = curObject.name + if isinstance(name, str) and not name.isspace(): + textList.append(name) try: info=curObject.makeTextInfo(textInfos.POSITION_SELECTION) if not info.isCollapsed: @@ -793,7 +794,10 @@ def script_navigatorObject_current(self,gesture): # No caret or selection on this object. pass else: - textList=[prop for prop in (curObject.name, curObject.value) if prop and isinstance(prop, basestring) and not prop.isspace()] + textList=[] + for prop in (curObject.name, curObject.value): + if isinstance(prop,str) and not prop.isspace(): + textList.append(prop) text=" ".join(textList) if len(text)>0 and not text.isspace(): if scriptHandler.getLastScriptRepeatCount()==1: @@ -1139,18 +1143,7 @@ def script_review_currentCharacter(self,gesture): try: c = ord(info.text) except TypeError: - # This might be a character taking multiple code points. - # If it is a 32 bit character, encode it to UTF-32 and calculate the ord manually. - # In Python 3, this is no longer necessary. - try: - encoded = info.text.encode("utf_32_le") - except UnicodeEncodeError: - c = None - else: - if len(encoded)==4: - c = sum(ord(cp)< Optional[Tuple[BOOL, AcceptedGetPropTypes]]: + """ Use this method to implement GetPropValue. + It is wrapped by the callback GetPropValue to handle exceptions, and ensure valid return types. For instructions on implementing accPropServers, see https://msdn.microsoft.com/en-us/library/windows/desktop/dd373681(v=vs.85).aspx . For instructions specifically about this method, see https://msdn.microsoft.com/en-us/library/windows/desktop/dd318495(v=vs.85).aspx . @param pIDString: Contains a string that identifies the property being requested. @@ -91,24 +106,58 @@ def _getPropValue(self, pIDString, dwIDStringLen, idProp): to extract the HWND/idObject/idChild from the identity string. Note that, while one IAccPropServer implementation can annotate multiple accessible elements, it is still bound to one wx.Control. - @type pIDString: str @param dwIDStringLen: Specifies the length of the identity string specified by the pIDString parameter. - @type dwIDStringLen: int - @param idProp: Specifies a GUID indicating the desired property. - @type idProp: One of the oleacc.PROPID_* GUIDS - @return A tuple of the out params for the `IAccPropServer::GetPropValue` method: `VARIANT* pvarValue` and `BOOL* - pfHasProp`. When the pfHasProp part is FALSE / self.DOES_NOT_HAVE_PROP, then the pvarValue part must be VT_EMPTY. - Consider using self.NO_RETURN_VALUE instead. Returning (VT_EMPTY, HAS_PROP) IS valid, meaning the property exists - but is empty. + @param idProp: Specifies a GUID indicating the desired property. One of the values from oleacc.PROPID_* + @return Use L{self._hasProp} to return correct values or return None if unable to supply the property. """ raise NotImplementedError - def GetPropValue(self, pIDString, dwIDStringLen, idProp): + def _hasProp( + self, + value: AcceptedGetPropTypes + ) -> Optional[Tuple[BOOL, AcceptedGetPropTypes]]: + """Constructs a tuple for the `IAccPropServer::GetPropValue` method, two elements: + 1. `VARIANT pvarValue` + 2. `BOOL pfHasProp` (either self.HAS_PROP or self.DOES_NOT_HAVE_PROP)""" + return value, self.HAS_PROP + + def GetPropValue( + self, this, # unused "this" used to indicate to comTypes we want a low level implementation + pIDString: str, + dwIDStringLen: int, + idProp: GUID, + pvarValue: POINTER(VARIANT), + pfGotProp: POINTER(BOOL) + ) -> int: + """ Exposed method to get a prop value. + see L{_getPropValue} for more details of args. + Uses a low-level approach, because comtypes tries to clear the VARIANT even though it is an out param. + When the pfHasProp part is FALSE / self.DOES_NOT_HAVE_PROP, then the pvarValue.vt part must be VT_EMPTY. + """ + # ensure exceptions don't leave this function. They will get get swallowed by the caller. + # instead catch and log exceptions. try: - return self._getPropValue(pIDString, dwIDStringLen, idProp) - except Exception: + # Preset values for "no prop value", in case we return early. + pfGotProp.contents.value = self.DOES_NOT_HAVE_PROP + _VariantInit(pvarValue) + + ret = self._getPropValue(pIDString, dwIDStringLen, idProp) + if ret is None: + # We don't have the prop value, return early. + return S_OK + elif len(ret) != 2: + # We don't have the prop value, internal error. + raise RuntimeError("_getPropValue implementation must return None or two element tuple") + elif ret[1] != self.HAS_PROP: + # We don't have the prop value, return early. + return S_OK + + # we do have the prop value + pfGotProp.contents.value = self.HAS_PROP + pvarValue.contents.value = ret[0] + except Exception as e: # catch and log all exceptions so they are not swallowed by caller. log.exception() - return self.NO_RETURN_VALUE + return S_OK def _onDestroyControl(self, evt): evt.Skip() # Allow other handlers to process this event. diff --git a/source/gui/configProfiles.py b/source/gui/configProfiles.py index 7a6a40c93bd..dc395283e04 100644 --- a/source/gui/configProfiles.py +++ b/source/gui/configProfiles.py @@ -300,7 +300,7 @@ def __init__(self, parent): triggers.append(TriggerInfo(spec, disp, profile)) processed.add(spec) # Handle all other triggers. - for spec, profile in confTrigs.iteritems(): + for spec, profile in confTrigs.items(): if spec in processed: continue if spec.startswith("app:"): diff --git a/source/gui/installerGui.py b/source/gui/installerGui.py index 75d67bf7bc4..f8826b345cb 100644 --- a/source/gui/installerGui.py +++ b/source/gui/installerGui.py @@ -260,7 +260,7 @@ def __init__(self): def showInstallGui(): gui.mainFrame.prePopup() previous = installer.comparePreviousInstall() - if previous > 0: + if previous is not None and previous > 0: # The existing installation is newer, which means this will be a downgrade. d = InstallingOverNewerVersionDialog() with d: @@ -380,6 +380,6 @@ def doCreatePortable(portableDirectory,copyUserConfig=False,silent=False,startAf if startAfterCreate: # #4475: ensure that the first window of the new process is not hidden by providing SW_SHOWNORMAL shellapi.ShellExecute(None, None, - os.path.join(os.path.abspath(unicode(portableDirectory)),'nvda.exe'), + os.path.join(os.path.abspath(portableDirectory),'nvda.exe'), u"-r", None, winUser.SW_SHOWNORMAL) diff --git a/source/gui/logViewer.py b/source/gui/logViewer.py index 7e818cfbea2..f571737dd37 100755 --- a/source/gui/logViewer.py +++ b/source/gui/logViewer.py @@ -7,7 +7,6 @@ """Provides functionality to view the NVDA log. """ -import codecs import wx import globalVars import gui @@ -55,7 +54,7 @@ def refresh(self, evt=None): pos = self.outputCtrl.GetInsertionPoint() # Append new text to the output control which has been written to the log file since the last refresh. try: - f = codecs.open(globalVars.appArgs.logFileName, "r", encoding="UTF-8") + f = open(globalVars.appArgs.logFileName, "r", encoding="UTF-8") f.seek(self._lastFilePos) self.outputCtrl.AppendText(f.read()) self._lastFilePos = f.tell() @@ -78,10 +77,10 @@ def onSaveAsCommand(self, evt): if not filename: return try: - # codecs.open() forces binary mode, which is bad under Windows because line endings won't be converted to crlf automatically. - # Therefore, do the encoding manually. - file(filename, "w").write(self.outputCtrl.GetValue().encode("UTF-8")) - except (IOError, OSError), e: + # #9038: work with UTF-8 from the start. + with open(filename, "w", encoding="UTF-8") as f: + f.write(self.outputCtrl.GetValue()) + except (IOError, OSError) as e: # Translators: Dialog text presented when NVDA cannot save a log file. gui.messageBox(_("Error saving log: %s") % e.strerror, _("Error"), style=wx.OK | wx.ICON_ERROR, parent=self) diff --git a/source/gui/nvdaControls.py b/source/gui/nvdaControls.py index 5a1749d2f76..ca9aeb8dec4 100644 --- a/source/gui/nvdaControls.py +++ b/source/gui/nvdaControls.py @@ -3,20 +3,18 @@ #Copyright (C) 2016-2018 NV Access Limited, Derek Riemer #This file is covered by the GNU General Public License. #See the file COPYING for more details. +from ctypes.wintypes import BOOL +from typing import Any, Tuple, Optional import wx +from comtypes import GUID from wx.lib.mixins import listctrl as listmix from gui import accPropServer from gui.dpiScalingHelper import DpiScalingHelperMixin import oleacc import winUser import winsound -try: - # Python 3 import - from collections.abc import Callable -except ImportError: - # Python 2 import - from collections import Callable +from collections.abc import Callable class AutoWidthColumnListCtrl(wx.ListCtrl, listmix.ListCtrlAutoWidthMixin): """ @@ -104,17 +102,17 @@ def __init__(self, control, propertyAnnotations): def _getPropValue(self, pIDString, dwIDStringLen, idProp): control = self.control() # self.control held as a weak ref, ensure it stays alive for the duration of this method if control is None or not self.propertyAnnotations: - return self.NO_RETURN_VALUE + return None try: val = self.propertyAnnotations[idProp] if callable(val): val = val() - return val, self.HAS_PROP + return self._hasProp(val) except KeyError: pass - return self.NO_RETURN_VALUE + return None def _cleanup(self): # could contain references (via lambda) of our owner, set it to None to avoid a circular reference which @@ -135,19 +133,19 @@ def __init__(self, control): annotateChildren=True ) - def _getPropValue(self, pIDString, dwIDStringLen, idProp): + def _getPropValue(self, pIDString: str, dwIDStringLen: int, idProp: GUID) -> Optional[Tuple[BOOL, Any]]: control = self.control() # self.control held as a weak ref, ensure it stays alive for the duration of this method if control is None: - return self.NO_RETURN_VALUE + return None # Import late to prevent circular import. from IAccessibleHandler import accPropServices handle, objid, childid = accPropServices.DecomposeHwndIdentityString(pIDString, dwIDStringLen) if childid == winUser.CHILDID_SELF: - return self.NO_RETURN_VALUE + return None if idProp == oleacc.PROPID_ACC_ROLE: - return oleacc.ROLE_SYSTEM_CHECKBUTTON, self.HAS_PROP + return self._hasProp(oleacc.ROLE_SYSTEM_CHECKBUTTON) if idProp == oleacc.PROPID_ACC_STATE: states = oleacc.STATE_SYSTEM_SELECTABLE|oleacc.STATE_SYSTEM_FOCUSABLE @@ -157,7 +155,7 @@ def _getPropValue(self, pIDString, dwIDStringLen, idProp): # wx doesn't seem to have a method to check whether a list item is focused. # Therefore, assume that a selected item is focused,which is the case in single select list boxes. states |= oleacc.STATE_SYSTEM_SELECTED | oleacc.STATE_SYSTEM_FOCUSED - return states, self.HAS_PROP + return self._hasProp(states) class CustomCheckListBox(wx.CheckListBox): """Custom checkable list to fix a11y bugs in the standard wx checkable list box.""" @@ -199,12 +197,12 @@ def __init__(self, parent, id=wx.ID_ANY, autoSizeColumn="LAST", pos=wx.DefaultPo self.Bind(wx.EVT_LEFT_DOWN, self.onLeftDown) def GetCheckedItems(self): - return tuple(i for i in xrange(self.ItemCount) if self.IsChecked(i)) + return tuple(i for i in range(self.ItemCount) if self.IsChecked(i)) def SetCheckedItems(self, indexes): for i in indexes: assert 0 <= i < self.ItemCount, "Index (%s) out of range" % i - for i in xrange(self.ItemCount): + for i in range(self.ItemCount): self.CheckItem(i, i in indexes) CheckedItems = property(fget=GetCheckedItems, fset=SetCheckedItems) diff --git a/source/gui/settingsDialogs.py b/source/gui/settingsDialogs.py index dcc5485b5e4..f9e6c2504f1 100644 --- a/source/gui/settingsDialogs.py +++ b/source/gui/settingsDialogs.py @@ -5,8 +5,8 @@ #This file is covered by the GNU General Public License. #See the file COPYING for more details. +import logging from abc import abstractmethod -from six import with_metaclass import os import copy import re @@ -47,9 +47,9 @@ import weakref import time import keyLabels -from dpiScalingHelper import DpiScalingHelperMixin +from .dpiScalingHelper import DpiScalingHelperMixin -class SettingsDialog(with_metaclass(guiHelper.SIPABCMeta, wx.Dialog, DpiScalingHelperMixin)): +class SettingsDialog(wx.Dialog, DpiScalingHelperMixin, metaclass=guiHelper.SIPABCMeta): """A settings dialog. A settings dialog consists of one or more settings controls and OK and Cancel buttons and an optional Apply button. Action may be taken in response to the OK, Cancel or Apply buttons. @@ -76,6 +76,7 @@ class MultiInstanceError(RuntimeError): pass shouldSuspendConfigProfileTriggers = True def __new__(cls, *args, **kwargs): + # We are iterating over instanceItems only once, so it can safely be an iterator. instanceItems = SettingsDialog._instances.items() instancesOfSameClass = ( (dlg, state) for dlg, state in instanceItems if isinstance(dlg, cls) @@ -240,7 +241,7 @@ def _onWindowDestroy(self, evt): # redo the layout in whatever way makes sense for their particular content. _RWLayoutNeededEvent, EVT_RW_LAYOUT_NEEDED = wx.lib.newevent.NewCommandEvent() -class SettingsPanel(with_metaclass(guiHelper.SIPABCMeta, wx.Panel, DpiScalingHelperMixin)): +class SettingsPanel(wx.Panel, DpiScalingHelperMixin, metaclass=guiHelper.SIPABCMeta): """A settings panel, to be used in a multi category settings dialog. A settings panel consists of one or more settings controls. Action may be taken in response to the parent dialog's OK or Cancel buttons. @@ -589,12 +590,12 @@ def onCategoryChange(self, evt): evt.Skip() def _doSave(self): - for panel in self.catIdToInstanceMap.itervalues(): + for panel in self.catIdToInstanceMap.values(): if panel.isValid() is False: raise ValueError("Validation for %s blocked saving settings" % panel.__class__.__name__) - for panel in self.catIdToInstanceMap.itervalues(): + for panel in self.catIdToInstanceMap.values(): panel.onSave() - for panel in self.catIdToInstanceMap.itervalues(): + for panel in self.catIdToInstanceMap.values(): panel.postSave() def onOk(self,evt): @@ -603,12 +604,12 @@ def onOk(self,evt): except ValueError: log.debugWarning("", exc_info=True) return - for panel in self.catIdToInstanceMap.itervalues(): + for panel in self.catIdToInstanceMap.values(): panel.Destroy() super(MultiCategorySettingsDialog,self).onOk(evt) def onCancel(self,evt): - for panel in self.catIdToInstanceMap.itervalues(): + for panel in self.catIdToInstanceMap.values(): panel.onDiscard() panel.Destroy() super(MultiCategorySettingsDialog,self).onCancel(evt) @@ -784,7 +785,7 @@ def onSave(self): config.conf["general"]["askToExit"]=self.askToExitCheckBox.IsChecked() config.conf["general"]["playStartAndExitSounds"]=self.playStartAndExitSoundsCheckBox.IsChecked() logLevel=self.LOG_LEVELS[self.logLevelList.GetSelection()][0] - config.conf["general"]["loggingLevel"]=logHandler.levelNames[logLevel] + config.conf["general"]["loggingLevel"]=logging.getLevelName(logLevel) logHandler.setLogLevelFromConfig() if self.startAfterLogonCheckBox.IsEnabled(): config.setStartAfterLogon(self.startAfterLogonCheckBox.GetValue()) @@ -1071,7 +1072,9 @@ def makeStringSettingControl(self,setting): setattr( self, "_%ss"%setting.id, - getattr(self.driver,"available%ss"%setting.id.capitalize()).values() + # Settings are stored as an ordered dict. + # Therefore wrap this inside a list call. + list(getattr(self.driver,"available%ss"%setting.id.capitalize()).values()) ) l=getattr(self,"_%ss"%setting.id) labeledControl=guiHelper.LabeledControlHelper( @@ -1109,7 +1112,7 @@ def makeBooleanSettingControl(self,setting): def updateDriverSettings(self, changedSetting=None): """Creates, hides or updates existing GUI controls for all of supported settings.""" #firstly check already created options - for name,sizer in self.sizerDict.iteritems(): + for name,sizer in self.sizerDict.items(): if name == changedSetting: # Changing a setting shouldn't cause that setting itself to disappear. continue @@ -2334,7 +2337,7 @@ def setType(self, type): self.typeRadioBox.SetSelection(DictionaryEntryDialog.TYPE_LABELS_ORDERING.index(type)) class DictionaryDialog(SettingsDialog): - TYPE_LABELS = {t: l.replace("&", "") for t, l in DictionaryEntryDialog.TYPE_LABELS.iteritems()} + TYPE_LABELS = {t: l.replace("&", "") for t, l in DictionaryEntryDialog.TYPE_LABELS.items()} def __init__(self,parent,title,speechDict): self.title = title @@ -2569,7 +2572,7 @@ def updatePossiblePorts(self): if displayName != "auto": displayCls = braille._getDisplayDriver(displayName) try: - self.possiblePorts.extend(displayCls.getPossiblePorts().iteritems()) + self.possiblePorts.extend(displayCls.getPossiblePorts().items()) except NotImplementedError: pass if self.possiblePorts: @@ -2896,7 +2899,7 @@ def __init__(self,parent): def makeSettings(self, settingsSizer): self.filteredSymbols = self.symbols = [ - copy.copy(symbol) for symbol in self.symbolProcessor.computedSymbols.itervalues() + copy.copy(symbol) for symbol in self.symbolProcessor.computedSymbols.values() ] self.pendingRemovals = {} @@ -3142,7 +3145,7 @@ def OnRemoveClick(self, evt): def onOk(self, evt): self.onSymbolEdited() self.editingItem = None - for symbol in self.pendingRemovals.itervalues(): + for symbol in self.pendingRemovals.values(): self.symbolProcessor.deleteSymbol(symbol) for symbol in self.symbols: if not symbol.replacement: @@ -3259,7 +3262,7 @@ def onTreeSelect(self, evt): return data = self.tree.GetItemData(item) isCommand = isinstance(data, inputCore.AllGesturesScriptInfo) - isGesture = isinstance(data, basestring) + isGesture = isinstance(data, str) self.addButton.Enabled = isCommand or isGesture self.removeButton.Enabled = isGesture diff --git a/source/hwIo.py b/source/hwIo.py index 4403518ec8b..6f8e4fdedf4 100644 --- a/source/hwIo.py +++ b/source/hwIo.py @@ -10,12 +10,14 @@ See L{braille.BrailleDisplayDriver.isThreadSafe}. """ -import threading +import sys import ctypes from ctypes import byref from ctypes.wintypes import DWORD, USHORT +from typing import Optional, Any, Union, Tuple, Callable + import serial -from serial.win32 import MAXDWORD, OVERLAPPED, FILE_FLAG_OVERLAPPED, INVALID_HANDLE_VALUE, ERROR_IO_PENDING, COMMTIMEOUTS, CreateFile, SetCommTimeouts +from serial.win32 import OVERLAPPED, FILE_FLAG_OVERLAPPED, INVALID_HANDLE_VALUE, ERROR_IO_PENDING, COMMTIMEOUTS, CreateFile, SetCommTimeouts import winKernel import braille from logHandler import log @@ -32,24 +34,25 @@ class IoBase(object): This watches for data of a specified size and calls a callback when it is received. """ - def __init__(self, fileHandle, onReceive, writeFileHandle=None, onReceiveSize=1, writeSize=None): + def __init__( + self, + fileHandle: Union[ctypes.wintypes.HANDLE], + onReceive: Callable[[bytes], None], + writeFileHandle: Optional[ctypes.wintypes.HANDLE] = None, + onReceiveSize: int = 1 + ): """Constructor. - @param readFileHandle: A handle to an open I/O device opened for overlapped I/O. - If L{writeFileHandle} is specified, this is only for input + @param fileHandle: A handle to an open I/O device opened for overlapped I/O. + If L{writeFileHandle} is specified, this is only for input. + The serial implementation uses a _port_handle member for this argument. @param onReceive: A callable taking the received data as its only argument. - @type onReceive: callable(str) @param writeFileHandle: A handle to an open output device opened for overlapped I/O. @param onReceiveSize: The size (in bytes) of the data with which to call C{onReceive}. - @type onReceiveSize: int - @param writeSize: The size of the buffer for writes, - C{None} to use the length of the data written. - @param writeSize: int or None """ self._file = fileHandle self._writeFile = writeFileHandle if writeFileHandle is not None else fileHandle self._onReceive = onReceive self._readSize = onReceiveSize - self._writeSize = writeSize self._readBuf = ctypes.create_string_buffer(onReceiveSize) self._readOl = OVERLAPPED() self._recvEvt = winKernel.createEvent() @@ -64,14 +67,12 @@ def init(param): self._initApc = init braille._BgThread.queueApc(init) - def waitForRead(self, timeout): + def waitForRead(self, timeout:Union[int, float]) -> bool: """Wait for a chunk of data to be received and processed. This will return after L{onReceive} has been called or when the timeout elapses. @param timeout: The maximum time to wait in seconds. - @type timeout: int or float @return: C{True} if received data was processed before the timeout, C{False} if not. - @rtype: bool """ timeout= int(timeout*1000) while True: @@ -88,19 +89,28 @@ def waitForRead(self, timeout): log.debug("Waiting interrupted by completed i/o") timeout -= int((time.time()-curTime)*1000) - def write(self, data): + def _prepareWriteBuffer(self, data: bytes) -> Tuple[int, ctypes.c_char_p]: + """ Private helper method to allow derived classes to prepare buffers in different ways""" + size = len(data) + return ( + size, + ctypes.create_string_buffer(data) # this will append a null char, which is intentional + ) + + def write(self, data: bytes): + if not isinstance(data, bytes): + raise TypeError("Expected argument 'data' to be of type 'bytes'") if _isDebug(): log.debug("Write: %r" % data) - size = self._writeSize or len(data) - buf = ctypes.create_string_buffer(size) - buf.raw = data + + size, data = self._prepareWriteBuffer(data) if not ctypes.windll.kernel32.WriteFile(self._writeFile, data, size, None, byref(self._writeOl)): if ctypes.GetLastError() != ERROR_IO_PENDING: if _isDebug(): log.debug("Write failed: %s" % ctypes.WinError()) raise ctypes.WinError() - bytes = DWORD() - ctypes.windll.kernel32.GetOverlappedResult(self._writeFile, byref(self._writeOl), byref(bytes), True) + byteData = DWORD() + ctypes.windll.kernel32.GetOverlappedResult(self._writeFile, byref(self._writeOl), byref(byteData), True) def close(self): if _isDebug(): @@ -125,22 +135,25 @@ def _asyncRead(self): # onReceive can then optionally read additional bytes if it knows these are coming. ctypes.windll.kernel32.ReadFileEx(self._file, self._readBuf, self._readSize, byref(self._readOl), self._ioDoneInst) - def _ioDone(self, error, bytes, overlapped): + def _ioDone(self, error, numberOfBytes: int, overlapped): if not self._onReceive: # close has been called. self._ioDone = None return elif error != 0: raise ctypes.WinError(error) - self._notifyReceive(self._readBuf[:bytes]) + self._notifyReceive(self._readBuf[:numberOfBytes]) winKernel.kernel32.SetEvent(self._recvEvt) self._asyncRead() - def _notifyReceive(self, data): + def _notifyReceive(self, data: bytes): """Called when data is received. The base implementation just calls the onReceive callback provided to the constructor. This can be extended to perform tasks before/after the callback. + @type data: bytes """ + if not isinstance(data, bytes): + raise TypeError("Expected argument 'data' to be of type 'bytes'") if _isDebug(): log.debug("Read: %r" % data) try: @@ -153,15 +166,17 @@ class Serial(IoBase): This extends pyserial to call a callback when data is received. """ - def __init__(self, *args, **kwargs): + def __init__( + self, + *args, + onReceive: Callable[[bytes], None], + **kwargs): """Constructor. Pass the arguments you would normally pass to L{serial.Serial}. - There is also one additional keyword argument. + There is also one additional required keyword argument. @param onReceive: A callable taking a byte of received data as its only argument. This callable can then call C{read} to get additional data if desired. - @type onReceive: callable(str) """ - onReceive = kwargs.pop("onReceive") self._ser = None self.port = args[0] if len(args) >= 1 else kwargs["port"] if _isDebug(): @@ -177,13 +192,13 @@ def __init__(self, *args, **kwargs): self._setTimeout(None) super(Serial, self).__init__(self._ser._port_handle, onReceive) - def read(self, size=1): + def read(self, size=1) -> bytes: data = self._ser.read(size) if _isDebug(): log.debug("Read: %r" % data) return data - def write(self, data): + def write(self, data: bytes): if _isDebug(): log.debug("Write: %r" % data) self._ser.write(data) @@ -194,13 +209,13 @@ def close(self): super(Serial, self).close() self._ser.close() - def _notifyReceive(self, data): + def _notifyReceive(self, data: bytes): # Set the timeout for onReceive in case it does a sync read. self._setTimeout(self._origTimeout) super(Serial, self)._notifyReceive(data) self._setTimeout(None) - def _setTimeout(self, timeout): + def _setTimeout(self, timeout: Optional[int]): # #6035: pyserial reconfigures all settings of the port when setting a timeout. # This can cause error 'Cannot configure port, some setting was wrong.' # Therefore, manually set the timeouts using the Win32 API. @@ -208,14 +223,14 @@ def _setTimeout(self, timeout): timeouts = COMMTIMEOUTS() if timeout is not None: if timeout == 0: - timeouts.ReadIntervalTimeout = win32.MAXDWORD + timeouts.ReadIntervalTimeout = serial.win32.MAXDWORD else: timeouts.ReadTotalTimeoutConstant = max(int(timeout * 1000), 1) if timeout != 0 and self._ser._inter_byte_timeout is not None: timeouts.ReadIntervalTimeout = max(int(self._ser._inter_byte_timeout * 1000), 1) if self._ser._write_timeout is not None: if self._ser._write_timeout == 0: - timeouts.WriteTotalTimeoutConstant = win32.MAXDWORD + timeouts.WriteTotalTimeoutConstant = serial.win32.MAXDWORD else: timeouts.WriteTotalTimeoutConstant = max(int(self._ser._write_timeout * 1000), 1) SetCommTimeouts(self._ser._port_handle, ctypes.byref(timeouts)) @@ -243,16 +258,14 @@ class HIDP_CAPS (ctypes.Structure): class Hid(IoBase): """Raw I/O for HID devices. """ + _featureSize: int - def __init__(self, path, onReceive, exclusive=True): + def __init__(self, path: str, onReceive: Callable[[bytes], None], exclusive: bool = True): """Constructor. @param path: The device path. This can be retrieved using L{hwPortUtils.listHidDevices}. - @type path: unicode @param onReceive: A callable taking a received input report as its only argument. - @type onReceive: callable(str) @param exclusive: Whether to block other application's access to this device. - @type exclusive: bool """ if _isDebug(): log.debug("Opening device %s" % path) @@ -280,21 +293,35 @@ def __init__(self, path, onReceive, exclusive=True): % (caps.InputReportByteLength, caps.OutputReportByteLength, caps.FeatureReportByteLength)) self._featureSize = caps.FeatureReportByteLength + self._writeSize = caps.OutputReportByteLength # Reading any less than caps.InputReportByteLength is an error. - # On Windows 7, writing any less than caps.OutputReportByteLength is also an error. super(Hid, self).__init__(handle, onReceive, - onReceiveSize=caps.InputReportByteLength, - writeSize=caps.OutputReportByteLength) + onReceiveSize=caps.InputReportByteLength + ) + + def _prepareWriteBuffer(self, data: bytes) -> Tuple[int, ctypes.c_char_p]: + """ For HID devices, the buffer to be written must match the + OutputReportByteLength fetched from HIDP_CAPS, to ensure this is the case + we create a buffer of that size. We also check that data is not bigger than + the write size, which we do not currently support. If it becomes necessary to + support this, we could split the data and send it several chunks. + """ + # On Windows 7, writing any less than caps.OutputReportByteLength is also an error. + # See also: http://www.onarm.com/forum/20152/ + if len(data) > self._writeSize: + log.error(u"Attempting to send a buffer larger than supported.") + raise RuntimeError("Unable to send buffer of: %d", len(data)) + return ( + self._writeSize, + ctypes.create_string_buffer(data, self._writeSize) + ) - def getFeature(self, reportId): + def getFeature(self, reportId: bytes) -> bytes: """Get a feature report from this device. @param reportId: The report id. - @type reportId: str @return: The report, including the report id. - @rtype: str """ - buf = ctypes.create_string_buffer(self._featureSize) - buf[0] = reportId + buf = ctypes.create_string_buffer(reportId, size=self._featureSize) if not ctypes.windll.hid.HidD_GetFeature(self._file, buf, self._featureSize): if _isDebug(): log.debug("Get feature %r failed: %s" @@ -304,34 +331,40 @@ def getFeature(self, reportId): log.debug("Get feature: %r" % buf.raw) return buf.raw - def setFeature(self, report): + def setFeature(self, report: bytes) -> None: """Send a feature report to this device. @param report: The report, including its id. - @type report: str """ - length = len(report) - buf = ctypes.create_string_buffer(length) - buf.raw = report + buf = ctypes.create_string_buffer(report, size=len(report)) + bufSize = ctypes.sizeof(buf) if _isDebug(): log.debug("Set feature: %r" % report) - if not ctypes.windll.hid.HidD_SetFeature(self._file, buf, length): + result = ctypes.windll.hid.HidD_SetFeature( + self._file, + buf, + bufSize + ) + if not result: if _isDebug(): log.debug("Set feature failed: %s" % ctypes.WinError()) raise ctypes.WinError() - def setOutputReport(self,report): + def setOutputReport(self, report: bytes) -> None: """ Write the given report to the device using HidD_SetOutputReport. This is instead of using the standard WriteFile which may freeze with some USB HID implementations. @param report: The report, including its id. - @type report: str """ - length=len(report) - buf=ctypes.create_string_buffer(length) - buf.raw=report + buf = ctypes.create_string_buffer(report, size=len(report)) + bufSize = ctypes.sizeof(buf) if _isDebug(): log.debug("Set output report: %r" % report) - if not ctypes.windll.hid.HidD_SetOutputReport(self._writeFile,buf,length): + result = ctypes.windll.hid.HidD_SetOutputReport( + self._writeFile, + buf, + bufSize + ) + if not result: if _isDebug(): log.debug("Set output report failed: %s" % ctypes.WinError()) raise ctypes.WinError() @@ -346,16 +379,16 @@ class Bulk(IoBase): This implementation assumes that the used Bulk device has two separate end points for input and output. """ - def __init__(self, path, epIn, epOut, onReceive, onReceiveSize=1, writeSize=None): + def __init__( + self, path: str, epIn: int, epOut: int, + onReceive: Callable[[bytes], None], + onReceiveSize: int = 1 + ): """Constructor. @param path: The device path. - @type path: unicode @param epIn: The endpoint to read data from. - @type epIn: int @param epOut: The endpoint to write data to. - @type epOut: int @param onReceive: A callable taking a received input report as its only argument. - @type onReceive: callable(str) """ if _isDebug(): log.debug("Opening device %s" % path) @@ -374,8 +407,7 @@ def __init__(self, path, epIn, epOut, onReceive, onReceiveSize=1, writeSize=None log.debug("Open write handle failed: %s" % ctypes.WinError()) raise ctypes.WinError() super(Bulk, self).__init__(readHandle, onReceive, - writeFileHandle=writeHandle, onReceiveSize=onReceiveSize, - writeSize=writeSize) + writeFileHandle=writeHandle, onReceiveSize=onReceiveSize) def close(self): super(Bulk, self).close() @@ -383,3 +415,25 @@ def close(self): winKernel.closeHandle(self._file) if hasattr(self, "_writeFile") and self._writeFile is not INVALID_HANDLE_VALUE: winKernel.closeHandle(self._writeFile) + + +def boolToByte(arg: bool) -> bytes: + return arg.to_bytes( + length=1, + byteorder=sys.byteorder, # for a single byte big/little endian does not matter. + signed=False # Since this represents length, it makes no sense to send a negative value. + ) + + +def intToByte(arg: int) -> bytes: + """ Convert an int (value < 256) to a single byte bytes object + """ + return arg.to_bytes( + length=1, # Will raise if value overflows, eg arg > 255 + byteorder=sys.byteorder, # for a single byte big/little endian does not matter. + signed=False # Since this represents length, it makes no sense to send a negative value. + ) + +def getByte(arg: bytes, index: int) -> bytes: + """ Return the single byte at index""" + return arg[index:index+1] diff --git a/source/hwPortUtils.py b/source/hwPortUtils.py index f5f45ab889d..358cbd6a9e3 100644 --- a/source/hwPortUtils.py +++ b/source/hwPortUtils.py @@ -9,10 +9,7 @@ import itertools import ctypes from ctypes.wintypes import BOOL, WCHAR, HWND, DWORD, ULONG, WORD, USHORT -try: - import _winreg as winreg # Python 2.7 import -except ImportError: - import winreg # Python 3 import +import winreg import winKernel from winKernel import SYSTEMTIME import config @@ -39,12 +36,12 @@ class GUID(ctypes.Structure): ('Data4', ctypes.c_ubyte*8), ) def __str__(self): - return "{%08x-%04x-%04x-%s-%s}" % ( + return u"{%08x-%04x-%04x-%s-%s}" % ( self.Data1, self.Data2, self.Data3, - ''.join(["%02x" % d for d in self.Data4[:2]]), - ''.join(["%02x" % d for d in self.Data4[2:]]), + u''.join([u"%02x" % d for d in self.Data4[:2]]), + u''.join([u"%02x" % d for d in self.Data4[2:]]), ) class SP_DEVINFO_DATA(ctypes.Structure): @@ -73,7 +70,7 @@ def __str__(self): PSP_DEVICE_INTERFACE_DETAIL_DATA = ctypes.c_void_p class dummy(ctypes.Structure): - _fields_=(("d1", DWORD), ("d2", WCHAR)) + _fields_=((u"d1", DWORD), (u"d2", WCHAR)) _pack_ = 1 SIZEOF_SP_DEVICE_INTERFACE_DETAIL_DATA_W = ctypes.sizeof(dummy) @@ -107,7 +104,7 @@ class dummy(ctypes.Structure): CR_SUCCESS = 0 MAX_DEVICE_ID_LEN = 200 -GUID_CLASS_COMPORT = GUID(0x86e0d1e0L, 0x8089, 0x11d0, +GUID_CLASS_COMPORT = GUID(0x86e0d1e0, 0x8089, 0x11d0, (ctypes.c_ubyte*8)(0x9c, 0xe4, 0x08, 0x00, 0x3e, 0x30, 0x1f, 0x73)) GUID_DEVINTERFACE_USB_DEVICE = GUID(0xA5DCBF10, 0x6530, 0x11D2, (0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED)) @@ -140,7 +137,7 @@ def listComPorts(onlyAvailable=True): buf = ctypes.create_unicode_buffer(1024) g_hdi = SetupDiGetClassDevs(ctypes.byref(GUID_CLASS_COMPORT), None, NULL, flags) try: - for dwIndex in xrange(256): + for dwIndex in range(256): entry = {} did = SP_DEVICE_INTERFACE_DATA() did.cbSize = ctypes.sizeof(did) @@ -350,7 +347,7 @@ def listUsbDevices(onlyAvailable=True): buf = ctypes.create_unicode_buffer(1024) g_hdi = SetupDiGetClassDevs(GUID_DEVINTERFACE_USB_DEVICE, None, NULL, flags) try: - for dwIndex in xrange(256): + for dwIndex in range(256): did = SP_DEVICE_INTERFACE_DATA() did.cbSize = ctypes.sizeof(did) @@ -497,7 +494,7 @@ def listHidDevices(onlyAvailable=True): buf = ctypes.create_unicode_buffer(1024) g_hdi = SetupDiGetClassDevs(_hidGuid, None, NULL, flags) try: - for dwIndex in xrange(256): + for dwIndex in range(256): did = SP_DEVICE_INTERFACE_DATA() did.cbSize = ctypes.sizeof(did) diff --git a/source/inputCore.py b/source/inputCore.py index b6cd974fdb3..d66e32d498c 100644 --- a/source/inputCore.py +++ b/source/inputCore.py @@ -84,7 +84,7 @@ def _get_identifiers(self): Subclasses must implement this method. @return: One or more identifiers which uniquely identify this gesture. - @rtype: list or tuple of basestring + @rtype: list or tuple of str """ raise NotImplementedError @@ -95,7 +95,7 @@ def _get_normalizedIdentifiers(self): These normalized identifiers can be directly looked up in input gesture maps. Subclasses should not override this method. @return: One or more normalized identifiers which uniquely identify this gesture. - @rtype: list of basestring + @rtype: list of str """ return [normalizeGestureIdentifier(identifier) for identifier in self.identifiers] @@ -167,9 +167,9 @@ def getDisplayTextForIdentifier(cls, identifier): the gesture's source (e.g. "laptop keyboard") and the specific gesture (e.g. "alt+tab"). @param identifier: The normalized gesture identifier in question. - @type identifier: basestring + @type identifier: str @return: A tuple of (source, specificGesture). - @rtype: tuple of (basestring, basestring) + @rtype: tuple of (str, str) @raise Exception: If no display text can be determined. """ raise NotImplementedError @@ -191,7 +191,7 @@ def __init__(self, entries=None): #: @type: bool self.lastUpdateContainedError = False #: The file name for this gesture map, if any. - #: @type: basestring + #: @type: str self.fileName = None if entries: self.update(entries) @@ -243,7 +243,7 @@ def load(self, filename): self.fileName = filename try: conf = configobj.ConfigObj(filename, file_error=True, encoding="UTF-8") - except (configobj.ConfigObjError,UnicodeDecodeError), e: + except (configobj.ConfigObjError,UnicodeDecodeError) as e: log.warning("Error in gesture map '%s': %s"%(filename, e)) self.lastUpdateContainedError = True return @@ -268,19 +268,19 @@ def update(self, entries): @type entries: mapping of str to mapping """ self.lastUpdateContainedError = False - for locationName, location in entries.iteritems(): + for locationName, location in entries.items(): try: module, className = locationName.rsplit(".", 1) except: log.error("Invalid module/class specification: %s" % locationName) self.lastUpdateContainedError = True continue - for script, gestures in location.iteritems(): + for script, gestures in location.items(): if script == "None": script = None if gestures == "": gestures = () - elif isinstance(gestures, basestring): + elif isinstance(gestures, str): gestures = [gestures] for gesture in gestures: try: @@ -353,7 +353,7 @@ def save(self): out = configobj.ConfigObj(encoding="UTF-8") out.filename = self.fileName - for gesture, scripts in self._map.iteritems(): + for gesture, scripts in self._map.items(): for module, className, script in scripts: key = "%s.%s" % (module, className) try: @@ -661,7 +661,7 @@ def getScriptCategory(self, cls, script): def addObj(self, obj, isAncestor=False): scripts = {} for cls in obj.__class__.__mro__: - for scriptName, script in cls.__dict__.iteritems(): + for scriptName, script in cls.__dict__.items(): if not scriptName.startswith("script_"): continue if isAncestor and not getattr(script, "canPropagate", False): @@ -675,9 +675,9 @@ def addObj(self, obj, isAncestor=False): continue self.addResult(scriptInfo) scripts[script] = scriptInfo - for gesture, script in obj._gestureMap.iteritems(): + for gesture, script in obj._gestureMap.items(): try: - scriptInfo = scripts[script.__func__] + scriptInfo = scripts[script] except KeyError: continue key = (scriptInfo.cls, gesture) @@ -733,7 +733,7 @@ def registerGestureSource(source, gestureCls): "br" will be used if it is registered. This registration is used, for example, to get the display text for a gesture identifier. @param source: The source prefix for associated gesture identifiers. - @type source: basestring + @type source: str @param gestureCls: The input gesture class. @type gestureCls: L{InputGesture} """ @@ -761,9 +761,9 @@ def getDisplayTextForGestureIdentifier(identifier): the gesture's source (e.g. "laptop keyboard") and the specific gesture (e.g. "alt+tab"). @param identifier: The normalized gesture identifier in question. - @type identifier: basestring + @type identifier: str @return: A tuple of (source, specificGesture). - @rtype: tuple of (basestring, basestring) + @rtype: tuple of (str, str) @raise LookupError: If no display text can be determined. """ gcls = _getGestureClsForIdentifier(identifier) diff --git a/source/installer.py b/source/installer.py index 9662e9daa98..aeb33878299 100644 --- a/source/installer.py +++ b/source/installer.py @@ -2,14 +2,11 @@ #A part of NonVisual Desktop Access (NVDA) #This file is covered by the GNU General Public License. #See the file COPYING for more details. -#Copyright (C) 2011-2017 NV Access Limited, Joseph Lee, Babbage B.V. +#Copyright (C) 2011-2019 NV Access Limited, Joseph Lee, Babbage B.V. from ctypes import * from ctypes.wintypes import * -try: - import _winreg as winreg # Python 2.7 import -except ImportError: - import winreg # Python 3 import +import winreg import threading import time import os @@ -25,6 +22,7 @@ import addonHandler import easeOfAccess import COMRegistrationFixes +import winKernel _wsh=None def _getWSH(): @@ -77,7 +75,7 @@ def getStartMenuFolder(noDefault=False): def getInstallPath(noDefault=False): try: - k=winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\NVDA") + k=winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE,r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\NVDA") return winreg.QueryValueEx(k,"UninstallDirectory")[0] except WindowsError: return defaultInstallPath if not noDefault else None @@ -91,11 +89,15 @@ def comparePreviousInstall(): if not path or not os.path.isdir(path): return None try: - return cmp( - os.path.getmtime(os.path.join(path, "nvda_slave.exe")), - os.path.getmtime("nvda_slave.exe")) + oldTime=os.path.getmtime(os.path.join(path, "nvda_slave.exe")) + newTime=os.path.getmtime("nvda_slave.exe") except OSError: return None + # cmp no longer exists in Python3. + # Per the Python3 What's New docs: + # cmp can be replaced with (a>b)-(anewTime)-(oldTime0: if vkChar == 43: # "+" # A gesture identifier can't include "+" except as a separator. return "plus" - return unichr(vkChar).lower() + return chr(vkChar).lower() if self.vkCode == 0xFF: # #3468: This key is unknown to Windows. diff --git a/source/languageHandler.py b/source/languageHandler.py index e3ec22791d6..c1b78042c33 100644 --- a/source/languageHandler.py +++ b/source/languageHandler.py @@ -8,7 +8,7 @@ This module assists in NVDA going global through language services such as converting Windows locale ID's to friendly names and presenting available languages. """ -import __builtin__ +import builtins import os import sys import ctypes @@ -37,7 +37,7 @@ def localeNameToWindowsLCID(localeName): # Windows Vista (NT 6.0) and later is able to convert locale names to LCIDs. # Because NVDA supports Windows 7 (NT 6.1) SP1 and later, just use it directly. localeName=localeName.replace('_','-') - LCID=ctypes.windll.kernel32.LocaleNameToLCID(unicode(localeName),0) + LCID=ctypes.windll.kernel32.LocaleNameToLCID(localeName,0) # #6259: In Windows 10, LOCALE_CUSTOM_UNSPECIFIED is returned for any locale name unknown to Windows. # This was observed for Aragonese ("an"). # See https://msdn.microsoft.com/en-us/library/system.globalization.cultureinfo.lcid(v=vs.110).aspx. @@ -108,7 +108,8 @@ def getAvailableLanguages(presentational=False): displayNames.append("%s, %s"%(desc,entry) if desc else entry) #Prepare a zipped view of language codes and descriptions. # #7284: especially for sorting by description. - langs = zip(locales,displayNames) + # Python 3: zip function changed from returning a list to an iterator, thus wrap this inside a list call. + langs = list(zip(locales,displayNames)) if presentational: langs.sort(key=lambda lang: lang[1]) #include a 'user default, windows' language, which just represents the default language for this user account @@ -120,20 +121,22 @@ def getAvailableLanguages(presentational=False): def makePgettext(translations): """Obtaina pgettext function for use with a gettext translations instance. pgettext is used to support message contexts, - but Python 2.7's gettext module doesn't support this, + but Python's gettext module doesn't support this, so NVDA must provide its own implementation. """ if isinstance(translations, gettext.GNUTranslations): def pgettext(context, message): - message = unicode(message) try: # Look up the message with its context. return translations._catalog[u"%s\x04%s" % (context, message)] except KeyError: return message - else: + elif isinstance(translations, gettext.NullTranslations): + # A language with out a translation catalog, such as English. def pgettext(context, message): - return unicode(message) + return message + else: + raise ValueError("%s is Not a GNUTranslations or NullTranslations object"%translations) return pgettext def getWindowsLanguage(): @@ -190,9 +193,10 @@ def setLanguage(lang): except IOError: trans=gettext.translation("nvda",fallback=True) curLang="en" - trans.install(unicode=True) + trans.install() # Install our pgettext function. - __builtin__.__dict__["pgettext"] = makePgettext(trans) + import builtins + builtins.pgettext = makePgettext(trans) def getLanguage(): return curLang diff --git a/source/locationHelper.py b/source/locationHelper.py index 92575c50765..6d7c9e323ac 100644 --- a/source/locationHelper.py +++ b/source/locationHelper.py @@ -6,7 +6,8 @@ """Classes and helper functions for working with rectangles and coordinates.""" -from collections import namedtuple, Sequence +from collections import namedtuple +from collections.abc import Sequence import windowUtils import winUser from ctypes.wintypes import RECT, POINT, DWORD @@ -151,6 +152,10 @@ def __eq__(self,other): return NotImplemented return self.x == other.x and self.y == other.y + # As __eq__ was defined on this class, we must provide __hash__ to remain hashable. + def __hash__(self): + return super().__hash__() + def __ne__(self,other): if not isinstance(other,POINT_CLASSES): return NotImplemented @@ -319,6 +324,10 @@ def __eq__(self,other): return NotImplemented return other.left == self.left and other.top == self.top and other.right == self.right and other.bottom == self.bottom + # As __eq__ was defined on this class, we must provide __hash__ to remain hashable. + def __hash__(self): + return super().__hash__() + def __ne__(self,other): if not isinstance(other,RECT_CLASSES): return NotImplemented diff --git a/source/logHandler.py b/source/logHandler.py index 2eaa0b6cec8..6943e922bdd 100755 --- a/source/logHandler.py +++ b/source/logHandler.py @@ -1,6 +1,6 @@ #logHandler.py #A part of NonVisual Desktop Access (NVDA) -#Copyright (C) 2007-2018 NV Access Limited, Rui Batista, Joseph Lee +#Copyright (C) 2007-2019 NV Access Limited, Rui Batista, Joseph Lee, Leonard de Ruijter #This file is covered by the GNU General Public License. #See the file COPYING for more details. @@ -12,8 +12,6 @@ import warnings from encodings import utf_8 import logging -# #7105: Python 3 split the following into two dictionaries. -from logging import _levelNames as levelNames import inspect import winsound import traceback @@ -78,29 +76,27 @@ def getCodePath(f): if not member: continue memberType=type(member) - if memberType is FunctionType and member.func_code is f.f_code: + if memberType is FunctionType and member.__code__ is f.f_code: # the function was found as a standard method className=cls.__name__ - elif memberType is classmethod and type(member.__func__) is FunctionType and member.__func__.func_code is f.f_code: + elif memberType is classmethod and type(member.__func__) is FunctionType and member.__func__.__code__ is f.f_code: # function was found as a class method className=cls.__name__ elif memberType is property: - if type(member.fget) is FunctionType and member.fget.func_code is f.f_code: + if type(member.fget) is FunctionType and member.fget.__code__ is f.f_code: # The function was found as a property getter className=cls.__name__ - elif type(member.fset) is FunctionType and member.fset.func_code is f.f_code: + elif type(member.fset) is FunctionType and member.fset.__code__ is f.f_code: # the function was found as a property setter className=cls.__name__ if className: break - return ".".join([x for x in path,className,funcName if x]) + return ".".join(x for x in (path,className,funcName) if x) # Function to strip the base path of our code from traceback text to improve readability. if getattr(sys, "frozen", None): # We're running a py2exe build. - # The base path already seems to be stripped in this case, so do nothing. - def stripBasePathFromTracebackText(text): - return text + stripBasePathFromTracebackText = lambda text: text else: BASE_PATH = os.path.split(__file__)[0] + os.sep TB_BASE_PATH_PREFIX = ' File "' @@ -147,7 +143,7 @@ def _log(self, level, msg, args, exc_info=None, extra=None, codepath=None, activ msg += ("\nStack trace:\n" + stripBasePathFromTracebackText("".join(traceback.format_list(stack_info)).rstrip())) - res = logging.Logger._log(self,level, msg, args, exc_info, extra) + res = super()._log(level, msg, args, exc_info, extra) if activateLogViewer: # Make the log text we just wrote appear in the log viewer. @@ -175,8 +171,7 @@ def exception(self, msg="", exc_info=True, **kwargs): However, certain exceptions which aren't considered errors (or aren't errors that we can fix) are expected and will therefore be logged at a lower level. """ import comtypes - import watchdog - from watchdog import RPC_E_CALL_CANCELED + from core import CallCancelled, RPC_E_CALL_CANCELED if exc_info is True: exc_info = sys.exc_info() @@ -184,7 +179,7 @@ def exception(self, msg="", exc_info=True, **kwargs): if ( (isinstance(exc, WindowsError) and exc.winerror in (ERROR_INVALID_WINDOW_HANDLE, ERROR_TIMEOUT, RPC_S_SERVER_UNAVAILABLE, RPC_S_CALL_FAILED_DNE, EPT_S_NOT_REGISTERED, RPC_E_CALL_CANCELED)) or (isinstance(exc, comtypes.COMError) and (exc.hresult in (E_ACCESSDENIED, CO_E_OBJNOTCONNECTED, EVENT_E_ALL_SUBSCRIBERS_FAILED, RPC_E_CALL_REJECTED, RPC_E_CALL_CANCELED, RPC_E_DISCONNECTED) or exc.hresult & 0xFFFF == RPC_S_SERVER_UNAVAILABLE)) - or isinstance(exc, watchdog.CallCancelled) + or isinstance(exc, CallCancelled) ): level = self.DEBUGWARNING else: @@ -212,18 +207,7 @@ def emit(self, record): except WindowsError: pass -class FileHandler(logging.StreamHandler): - - def __init__(self, filename, mode): - # We need to open the file in text mode to get CRLF line endings. - # Therefore, we can't use codecs.open(), as it insists on binary mode. See PythonIssue:691291. - # We know that \r and \n are safe in UTF-8, so PythonIssue:691291 doesn't matter here. - logging.StreamHandler.__init__(self, utf_8.StreamWriter(file(filename, mode))) - - def close(self): - self.flush() - self.stream.close() - logging.StreamHandler.close(self) +class FileHandler(logging.FileHandler): def handle(self,record): # Only play the error sound if this is a test version. @@ -239,19 +223,10 @@ def handle(self,record): nvwave.playWaveFile("waves\\error.wav") except: pass - return logging.StreamHandler.handle(self,record) + return super().handle(record) class Formatter(logging.Formatter): - def format(self, record): - s = logging.Formatter.format(self, record) - if isinstance(s, str): - # Log text must be unicode. - # The string is probably encoded according to our thread locale, so use mbcs. - # If there are any errors, just replace the character, as there's nothing else we can do. - s = unicode(s, "mbcs", "replace") - return s - def formatException(self, ex): return stripBasePathFromTracebackText(super(Formatter, self).formatException(ex)) @@ -288,9 +263,11 @@ def redirectStdout(logger): sys.stdout = StreamRedirector("stdout", logger, logging.WARNING) sys.stderr = StreamRedirector("stderr", logger, logging.ERROR) +# Register our logging class as the class for all loggers. +logging.setLoggerClass(Logger) #: The singleton logger instance. #: @type: L{Logger} -log = Logger("nvda") +log = logging.getLogger("nvda") def _getDefaultLogFilePath(): if getattr(sys, "frozen", None): @@ -339,8 +316,7 @@ def initialize(shouldDoRemoteLogging=False): os.rename(globalVars.appArgs.logFileName, oldLogFileName) except (IOError, WindowsError): pass # Probably log does not exist, don't care. - # Our FileHandler always outputs in UTF-8. - logHandler = FileHandler(globalVars.appArgs.logFileName, mode="wt") + logHandler = FileHandler(globalVars.appArgs.logFileName, mode="w",encoding="utf-8") else: logHandler = RemoteHandler() logFormatter = Formatter("%(codepath)s:\n%(message)s") @@ -360,11 +336,12 @@ def setLogLevelFromConfig(): return import config levelName=config.conf["general"]["loggingLevel"] - level = levelNames.get(levelName) + # logging.getLevelName can give you a level number if given a name. + level = logging.getLevelName(levelName) # The lone exception to level higher than INFO is "OFF" (100). # Setting a log level to something other than options found in the GUI is unsupported. if level not in (log.DEBUG, log.IO, log.DEBUGWARNING, log.INFO, log.OFF): log.warning("invalid setting for logging level: %s" % levelName) level = log.INFO - config.conf["general"]["loggingLevel"] = levelNames[log.INFO] + config.conf["general"]["loggingLevel"] = logging.getLevelName(log.INFO) log.setLevel(level) diff --git a/source/louisHelper.py b/source/louisHelper.py index 1cd21f42c58..c89064a03cc 100644 --- a/source/louisHelper.py +++ b/source/louisHelper.py @@ -52,10 +52,10 @@ def terminate(): def translate(tableList, inbuf, typeform=None, cursorPos=None, mode=0): """ Convenience wrapper for louis.translate that: - * returns a list of integers instead of an string with cells, and + * returns a list of integers instead of a string with cells, and * distinguishes between cursor position 0 (cursor at first character) and None (no cursor at all) """ - text = unicode(inbuf).replace('\0','') + text = inbuf.replace('\0','') braille, brailleToRawPos, rawToBraillePos, brailleCursorPos = louis.translate( tableList, text, diff --git a/source/mathPres/__init__.py b/source/mathPres/__init__.py index cf0cb52c823..5b55d706985 100644 --- a/source/mathPres/__init__.py +++ b/source/mathPres/__init__.py @@ -29,16 +29,16 @@ class MathPresentationProvider(object): def getSpeechForMathMl(self, mathMl): """Get speech output for specified MathML markup. @param mathMl: The MathML markup. - @type mathMl: basestring + @type mathMl: str @return: A speech sequence. - @rtype: list of unicode and/or L{speech.SpeechCommand} + @rtype: list of str and/or L{speech.SpeechCommand} """ raise NotImplementedError def getBrailleForMathMl(self, mathMl): """Get braille output for specified MathML markup. @param mathMl: The MathML markup. - @type mathMl: basestring + @type mathMl: str @return: A string of Unicode braille. @rtype: unicode """ @@ -136,7 +136,7 @@ def getMathMlFromTextInfo(pos): @param pos: The TextInfo in question. @type pos: L{textInfos.TextInfo} @return: The MathML or C{None} if there is no math. - @rtype: basestring + @rtype: str """ pos = pos.copy() pos.expand(textInfos.UNIT_CHARACTER) @@ -172,7 +172,7 @@ def interactWithMathMl(mathMl): def getLanguageFromMath(mathMl): """Get the language specified in a math tag. @return: The language or C{None} if unspeicifed. - @rtype: basestring + @rtype: str """ m = RE_MATH_LANG.search(mathMl) if m: diff --git a/source/mathPres/mathPlayer.py b/source/mathPres/mathPlayer.py index e21627a4dd8..7b297f0520a 100644 --- a/source/mathPres/mathPlayer.py +++ b/source/mathPres/mathPlayer.py @@ -21,9 +21,9 @@ # Break. r" ?" # Pronunciation of characters. - ur"|(?P[^<]) ?" + r"|(?P[^<]) ?" # Specific pronunciation. - ur"| (?P[^ <]+) ?" + r"| (?P[^ <]+) ?" # Prosody. r"| ?" r"|(?P) ?" diff --git a/source/mathType.py b/source/mathType.py index b6052b6f96e..6cd5b7efbc8 100644 --- a/source/mathType.py +++ b/source/mathType.py @@ -7,10 +7,7 @@ """Utilities for working with MathType. """ -try: - import _winreg as winreg # Python 2.7 import -except ImportError: - import winreg # Python 3 import +import winreg import ctypes import mathPres diff --git a/source/mouseHandler.py b/source/mouseHandler.py index b11f7978925..6ea1abe7ad3 100644 --- a/source/mouseHandler.py +++ b/source/mouseHandler.py @@ -200,7 +200,7 @@ def getTotalWidthAndHeightAndMinimumPosition(displays): def executeMouseMoveEvent(x,y): global currentMouseWindow desktopObject=api.getDesktopObject() - displays = [ wx.Display(i).GetGeometry() for i in xrange(wx.Display.GetCount()) ] + displays = [ wx.Display(i).GetGeometry() for i in range(wx.Display.GetCount()) ] x, y = getMouseRestrictedToScreens(x, y, displays) screenWidth, screenHeight, minPos = getTotalWidthAndHeightAndMinimumPosition(displays) diff --git a/source/nvda.pyw b/source/nvda.pyw index 7fbcb4db104..4d8c5a4d6b0 100755 --- a/source/nvda.pyw +++ b/source/nvda.pyw @@ -26,7 +26,7 @@ import gettext try: gettext.translation('nvda',localedir='locale',languages=[locale.getdefaultlocale()[0]]).install(True) except: - gettext.install('nvda',unicode=True) + gettext.install('nvda') import time import argparse @@ -54,14 +54,14 @@ class NoConsoleOptionParser(argparse.ArgumentParser): def print_help(self, file=None): """Shows help in a standard Windows message dialog""" - winUser.MessageBox(0, unicode(self.format_help()), u"Help", 0) + winUser.MessageBox(0, self.format_help(), u"Help", 0) def error(self, message): """Shows an error in a standard Windows message dialog, and then exits NVDA""" out = "" out = self.format_usage() out += "\nerror: %s" % message - winUser.MessageBox(0, unicode(out), u"Error", 0) + winUser.MessageBox(0, out, u"Error", 0) sys.exit(2) globalVars.startTime=time.time() @@ -72,10 +72,6 @@ if not winVersion.isSupportedOS(): winUser.MessageBox(0, ctypes.FormatError(winUser.ERROR_OLD_WIN_VERSION), None, winUser.MB_ICONERROR) sys.exit(1) -def decodeMbcs(string): - """Decode a multi-byte character set string""" - return string.decode("mbcs") - def stringToBool(string): """Wrapper for configobj.validate.is_boolean to raise the proper exception for wrong values.""" from configobj.validate import is_boolean, ValidateError @@ -90,9 +86,9 @@ quitGroup = parser.add_mutually_exclusive_group() quitGroup.add_argument('-q','--quit',action="store_true",dest='quit',default=False,help="Quit already running copy of NVDA") quitGroup.add_argument('-r','--replace',action="store_true",dest='replace',default=False,help="Quit already running copy of NVDA and start this one") parser.add_argument('-k','--check-running',action="store_true",dest='check_running',default=False,help="Report whether NVDA is running via the exit code; 0 if running, 1 if not running") -parser.add_argument('-f','--log-file',dest='logFileName',type=decodeMbcs,help="The file where log messages should be written to") +parser.add_argument('-f','--log-file',dest='logFileName',type=str,help="The file where log messages should be written to") parser.add_argument('-l','--log-level',dest='logLevel',type=int,default=0,choices=[10, 12, 15, 20, 30, 40, 50, 100],help="The lowest level of message logged (debug 10, input/output 12, debugwarning 15, info 20, warning 30, error 40, critical 50, off 100), default is info") -parser.add_argument('-c','--config-path',dest='configPath',default=None,type=decodeMbcs,help="The path where all settings for NVDA are stored") +parser.add_argument('-c','--config-path',dest='configPath',default=None,type=str,help="The path where all settings for NVDA are stored") parser.add_argument('-m','--minimal',action="store_true",dest='minimal',default=False,help="No sounds, no interface, no start message etc") parser.add_argument('-s','--secure',action="store_true",dest='secure',default=False,help="Secure mode (disable Python console)") parser.add_argument('--disable-addons',action="store_true",dest='disableAddons',default=False,help="Disable all add-ons") @@ -104,7 +100,7 @@ installGroup.add_argument('--install',action="store_true",dest='install',default installGroup.add_argument('--install-silent',action="store_true",dest='installSilent',default=False,help="Installs NVDA silently (does not start the new copy after installation).") installGroup.add_argument('--create-portable',action="store_true",dest='createPortable',default=False,help="Creates a portable copy of NVDA (starting the new copy after installation)") installGroup.add_argument('--create-portable-silent',action="store_true",dest='createPortableSilent',default=False,help="Creates a portable copy of NVDA silently (does not start the new copy after installation).") -parser.add_argument('--portable-path',dest='portablePath',default=None,type=decodeMbcs,help="The path where a portable copy will be created") +parser.add_argument('--portable-path',dest='portablePath',default=None,type=str,help="The path where a portable copy will be created") parser.add_argument('--launcher',action="store_true",dest='launcher',default=False,help="Started from the launcher") parser.add_argument('--enable-start-on-logon',metavar="True|False",type=stringToBool,dest='enableStartOnLogon',default=None, help="When installing, enable NVDA's start on the logon screen") @@ -177,12 +173,9 @@ if not mutex or ctypes.windll.kernel32.GetLastError()==ERROR_ALREADY_EXISTS: isSecureDesktop = desktopName == "Winlogon" if isSecureDesktop: + import winreg try: - import _winreg as winreg # Python 2.7 import - except ImportError: - import winreg # Python 3 import - try: - k = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, ur"SOFTWARE\NVDA") + k = winreg.OpenKey(winreg.HKEY_LOCAL_MACHINE, r"SOFTWARE\NVDA") if not winreg.QueryValueEx(k, u"serviceDebug")[0]: globalVars.appArgs.secure = True except WindowsError: diff --git a/source/nvda_eoaProxy.pyw b/source/nvda_eoaProxy.pyw index 204fbe5c223..dd9669d8daf 100644 --- a/source/nvda_eoaProxy.pyw +++ b/source/nvda_eoaProxy.pyw @@ -35,7 +35,7 @@ def isSecureDesktop(): def waitForNvdaStart(): # Wait up to 10 seconds for NVDA to start. - for attempt in xrange(11): + for attempt in range(11): process = getNvdaProcess() if process: return process diff --git a/source/nvda_slave.pyw b/source/nvda_slave.pyw index 632682b9ea3..b945bd67688 100755 --- a/source/nvda_slave.pyw +++ b/source/nvda_slave.pyw @@ -12,9 +12,9 @@ import gettext import locale #Localization settings try: - gettext.translation('nvda',localedir='locale',languages=[locale.getdefaultlocale()[0]]).install(True) + gettext.translation('nvda',localedir='locale',languages=[locale.getdefaultlocale()[0]]).install() except: - gettext.install('nvda',unicode=True) + gettext.install('nvda') import sys import os @@ -48,12 +48,12 @@ def main(): import shellapi import winUser shellapi.ShellExecute(0,None, - ur"%s\nvda.exe"%sys.exec_prefix.decode("mbcs"), - subprocess.list2cmdline(args).decode("mbcs"), + r"%s\nvda.exe"%sys.prefix, + subprocess.list2cmdline(args), None,winUser.SW_SHOWNORMAL) elif action=="setNvdaSystemConfig": import config - config._setSystemConfig(args[0].decode('mbcs')) + config._setSystemConfig(args[0]) elif action == "config_setStartOnLogonScreen": enable = bool(int(args[0])) import config @@ -69,7 +69,7 @@ def main(): shellapi.ShellExecute(0,None,path,None,None,winUser.SW_SHOWNORMAL) elif action == "addons_installAddonPackage": try: - addonPath=unicode(args[0], "mbcs") + addonPath=args[0] except IndexError: raise ValueError("Addon path was not provided.") #Load nvdaHelperRemote.dll but with an altered search path so it can pick up other dlls in lib @@ -91,7 +91,7 @@ def main(): comHelper._lresultFromGetActiveObject(args[0], bool(int(args[1])))) sys.__stdout__.flush() try: - raw_input() + input() except EOFError: pass else: @@ -100,7 +100,7 @@ def main(): except installer.RetriableFailure: logHandler.log.error("Task failed, try again",exc_info=True) sys.exit(2) - except Exception, e: + except Exception as e: logHandler.log.error("slave error",exc_info=True) sys.exit(1) diff --git a/source/nvwave.py b/source/nvwave.py index 7bf011cf0fb..040a9d7603f 100644 --- a/source/nvwave.py +++ b/source/nvwave.py @@ -117,7 +117,7 @@ def __init__(self, channels, samplesPerSec, bitsPerSample, @param bitsPerSample: The number of bits per sample. @type bitsPerSample: int @param outputDevice: The device ID or name of the audio output device to use. - @type outputDevice: int or basestring + @type outputDevice: int or str @param closeWhenIdle: If C{True}, close the output device when no audio is being played. @type closeWhenIdle: bool @param wantDucking: if true then background audio will be ducked on Windows 8 and higher @@ -130,7 +130,7 @@ def __init__(self, channels, samplesPerSec, bitsPerSample, self.channels=channels self.samplesPerSec=samplesPerSec self.bitsPerSample=bitsPerSample - if isinstance(outputDevice, basestring): + if isinstance(outputDevice, str): outputDevice = outputDeviceNameToID(outputDevice, True) self.outputDeviceID = outputDevice if wantDucking: @@ -146,7 +146,7 @@ def __init__(self, channels, samplesPerSec, bitsPerSample, BITS_PER_BYTE = 8 MS_PER_SEC = 1000 self._minBufferSize = samplesPerSec * channels * (bitsPerSample / BITS_PER_BYTE) / MS_PER_SEC * self.MIN_BUFFER_MS - self._buffer = "" + self._buffer = b"" else: self._minBufferSize = None #: Function to call when the previous chunk of audio has finished playing. @@ -170,7 +170,7 @@ def open(self): wfx.nChannels = self.channels wfx.nSamplesPerSec = self.samplesPerSec wfx.wBitsPerSample = self.bitsPerSample - wfx.nBlockAlign = self.bitsPerSample / 8 * self.channels + wfx.nBlockAlign: int = self.bitsPerSample // 8 * self.channels wfx.nAvgBytesPerSec = self.samplesPerSec * wfx.nBlockAlign waveout = HWAVEOUT(0) with self._global_waveout_lock: @@ -196,7 +196,7 @@ def feed(self, data, onDone=None): # so we can accurately call onDone at the end of this chunk. if onDone or len(self._buffer) > self._minBufferSize: self._feedUnbuffered(self._buffer, onDone=onDone) - self._buffer = "" + self._buffer = b"" def _feedUnbuffered(self, data, onDone=None): if self._audioDucker and not self._audioDucker.enable(): @@ -212,7 +212,7 @@ def _feedUnbuffered(self, data, onDone=None): try: with self._global_waveout_lock: winmm.waveOutWrite(self._waveout, LPWAVEHDR(whdr), sizeof(WAVEHDR)) - except WindowsError, e: + except WindowsError as e: self.close() raise e self.sync() @@ -275,7 +275,7 @@ def idle(self): return self._idleUnbuffered() if self._buffer: self._feedUnbuffered(self._buffer) - self._buffer = "" + self._buffer = b"" return self._idleUnbuffered() def _idleUnbuffered(self): @@ -293,7 +293,7 @@ def stop(self): """ if self._audioDucker: self._audioDucker.disable() if self._minBufferSize: - self._buffer = "" + self._buffer = b"" with self._waveout_lock: if not self._waveout: return @@ -332,7 +332,7 @@ def __del__(self): def _getOutputDevices(): caps = WAVEOUTCAPS() - for devID in xrange(-1, winmm.waveOutGetNumDevs()): + for devID in range(-1, winmm.waveOutGetNumDevs()): try: winmm.waveOutGetDevCapsW(devID, byref(caps), sizeof(caps)) yield devID, caps.szPname diff --git a/source/objidl.py b/source/objidl.py index 8d4dfc4e764..186f4020a0d 100644 --- a/source/objidl.py +++ b/source/objidl.py @@ -4,8 +4,8 @@ #See the file COPYING for more details. from ctypes import * -from ctypes.wintypes import HWND, HRESULT, BOOL -from comtypes import GUID, COMMETHOD, IUnknown, tagBIND_OPTS2 +from ctypes.wintypes import HWND, BOOL +from comtypes import HRESULT, GUID, COMMETHOD, IUnknown, tagBIND_OPTS2 from comtypes.persist import IPersist WSTRING = c_wchar_p diff --git a/source/oleacc.py b/source/oleacc.py index 959d5e649f5..260470df755 100644 --- a/source/oleacc.py +++ b/source/oleacc.py @@ -8,7 +8,7 @@ import winUser # Include functions from oleacc.dll in the module namespace. m=comtypes.client.GetModule('oleacc.dll') -globals().update((key, val) for key, val in m.__dict__.iteritems() if not key.startswith("_")) +globals().update((key, val) for key, val in m.__dict__.items() if not key.startswith("_")) NAVDIR_MIN=0 NAVDIR_UP=1 @@ -192,7 +192,7 @@ def CreateStdAccessibleProxy(hwnd,className,objectID,interface=IAccessible): @param hwnd: the handle of the window this accessible object should represent. @type hwnd: int @param className: the window class name to use. - @type className: basestring + @type className: str @param objectID: an OBJID_* constant or custom value stating the specific object in the window. @type objectID: int @param interface: the requested COM interface for this object. Defaults to IAccessible. diff --git a/source/pythonConsole.py b/source/pythonConsole.py index becad036104..fd623025b6f 100755 --- a/source/pythonConsole.py +++ b/source/pythonConsole.py @@ -2,7 +2,7 @@ #A part of NonVisual Desktop Access (NVDA) #This file is covered by the GNU General Public License. #See the file COPYING for more details. -#Copyright (C) 2008-2017 NV Access Limited +#Copyright (C) 2008-2019 NV Access Limited, Leonard de Ruijter import watchdog @@ -10,7 +10,7 @@ To use, call L{initialize} to create a singleton instance of the console GUI. This can then be accessed externally as L{consoleUI}. """ -import __builtin__ +import builtins import os import code import codeop @@ -105,11 +105,10 @@ def __init__(self, outputFunc, setPromptFunc, exitFunc, echoFunc=None, **kwargs) self.namespace = {} self.initNamespace() #: The variables last added to the namespace containing a snapshot of NVDA's state. - #: @type: dict + #: @type: Optional[dict] self._namespaceSnapshotVars = None - # Can't use super here because stupid code.InteractiveConsole doesn't sub-class object. Grrr! - code.InteractiveConsole.__init__(self, locals=self.namespace, **kwargs) + super().__init__(locals=self.namespace, **kwargs) self.compile = CommandCompiler() self.prompt = ">>>" self.lastResult = None @@ -131,19 +130,31 @@ def push(self, line): stdout, stderr = sys.stdout, sys.stderr sys.stdout = sys.stderr = self # Prevent this from messing with the gettext "_" builtin. - saved_ = __builtin__._ + saved_ = builtins._ self.lastResult = None - more = code.InteractiveConsole.push(self, line) + more = super().push(line) sys.stdout, sys.stderr = stdout, stderr - if __builtin__._ is not saved_: - self.lastResult = __builtin__._ + if builtins._ is not saved_: + self.lastResult = builtins._ # Preserve the namespace if gettext has explicitly been pushed there if "_" not in self.namespace or self.namespace["_"] is not saved_: - self.namespace["_"] = __builtin__._ - __builtin__._ = saved_ + self.namespace["_"] = builtins._ + builtins._ = saved_ self.prompt = "..." if more else ">>>" return more + def showsyntaxerror(self, filename=None): + excepthook = sys.excepthook + sys.excepthook = sys.__excepthook__ + super().showsyntaxerror(filename=filename) + sys.excepthook = excepthook + + def showtraceback(self): + excepthook = sys.excepthook + sys.excepthook = sys.__excepthook__ + super().showtraceback() + sys.excepthook = excepthook + def initNamespace(self): """(Re-)Initialize the console namespace with useful globals. """ @@ -335,8 +346,8 @@ def _findBestCompletion(self, original, completions): longestComp = comp longestCompLen = compLen # Find the longest common prefix. - for prefixLen in xrange(longestCompLen, 0, -1): - prefix = comp[:prefixLen] + for prefixLen in range(longestCompLen, 0, -1): + prefix = longestComp[:prefixLen] for comp in completions: if not comp.startswith(prefix): break diff --git a/source/queueHandler.py b/source/queueHandler.py index b8a9533b000..013693d70f9 100644 --- a/source/queueHandler.py +++ b/source/queueHandler.py @@ -5,10 +5,7 @@ #See the file COPYING for more details. import types -try: - from Queue import Queue # Python 2.7 import -except ImportError: - from queue import Queue # Python 3 import +from queue import Queue import globalVars from logHandler import log import watchdog @@ -45,7 +42,7 @@ def isRunningGenerators(): log.debug("generators running: %s"%res) def flushQueue(queue): - for count in xrange(queue.qsize()+1): + for count in range(queue.qsize()+1): if not queue.empty(): (func,args,kwargs)=queue.get_nowait() watchdog.alive() @@ -62,8 +59,8 @@ def isPendingItems(queue): return res def pumpAll(): - # This dict can mutate during iteration, so use keys(). - for ID in generators.keys(): + # This dict can mutate during iteration, so wrap the keys in a list. + for ID in list(generators): # KeyError could occur within the generator itself, so retrieve the generator first. try: gen = generators[ID] diff --git a/source/remotePythonConsole.py b/source/remotePythonConsole.py index 33301866d80..60d39d68442 100644 --- a/source/remotePythonConsole.py +++ b/source/remotePythonConsole.py @@ -11,7 +11,7 @@ """ import threading -import SocketServer +import socketserver import wx import pythonConsole from logHandler import log @@ -22,7 +22,7 @@ server = None -class RequestHandler(SocketServer.StreamRequestHandler): +class RequestHandler(socketserver.StreamRequestHandler): def setPrompt(self, prompt): if not self._keepRunning: @@ -72,7 +72,7 @@ def handle(self): def initialize(): global server - server = SocketServer.TCPServer(("", PORT), RequestHandler) + server = socketserver.TCPServer(("", PORT), RequestHandler) server.daemon_threads = True thread = threading.Thread(target=server.serve_forever) thread.daemon = True diff --git a/source/scriptHandler.py b/source/scriptHandler.py index 39e78ee90b5..2d050c9ed35 100644 --- a/source/scriptHandler.py +++ b/source/scriptHandler.py @@ -7,6 +7,7 @@ import time import weakref import inspect +import types import config import speech import sayAllHandler @@ -32,9 +33,6 @@ def _makeKbEmulateScript(scriptName): keyName = scriptName[3:] emuGesture = keyboardHandler.KeyboardInputGesture.fromName(keyName) func = lambda gesture: inputCore.manager.emulateGesture(emuGesture) - if isinstance(scriptName, unicode): - # __name__ must be str; i.e. can't be unicode. - scriptName = scriptName.encode("mbcs") func.__name__ = "script_%s" % scriptName func.__doc__ = _("Emulates pressing %s on the system keyboard") % emuGesture.displayName return func @@ -267,9 +265,8 @@ def script( if gestures is None: gestures = [] def script_decorator(decoratedScript): - # Scripts are unbound instance methods in python 2 and functions in python 3. - # Therefore, we use inspect.isroutine to check whether a script is either a function or instance method. - if not inspect.isroutine(decoratedScript): + # Decoratable scripts are functions, not bound instance methods. + if not isinstance(decoratedScript, types.FunctionType): log.warning( "Using the script decorator is unsupported for %r" % decoratedScript, stack_info=True diff --git a/source/setup.py b/source/setup.py index e105e777cc3..f057dd1d3db 100755 --- a/source/setup.py +++ b/source/setup.py @@ -8,117 +8,100 @@ import os import copy import gettext -gettext.install("nvda", unicode=True) -from distutils.core import setup +gettext.install("nvda") +from setuptools import setup import py2exe as py2exeModule from glob import glob import fnmatch from versionInfo import * -from py2exe import build_exe +from py2exe import distutils_buildexe +from py2exe.dllfinder import DllFinder import wx -import imp +import importlib.machinery -MAIN_MANIFEST_EXTRA = r""" - - - - - - - - - - - - - - - - - - - - - - +RT_MANIFEST = 24 +manifest_template = """\ + + + + + + + + + + + + + + + + + + + + + + """ -def getModuleExtention(thisModType): - for ext,mode,modType in imp.get_suffixes(): - if modType==thisModType: - return ext - raise ValueError("unknown mod type %s"%thisModType) - # py2exe's idea of whether a dll is a system dll appears to be wrong sometimes, so monkey patch it. -origIsSystemDLL = build_exe.isSystemDLL -def isSystemDLL(pathname): - dll = os.path.basename(pathname).lower() - if dll in ("msvcp71.dll", "msvcp90.dll", "gdiplus.dll","mfc71.dll", "mfc90.dll"): - # These dlls don't exist on many systems, so make sure they're included. - return 0 - elif dll.startswith("api-ms-win-") or dll in ("powrprof.dll", "mpr.dll", "crypt32.dll"): +orig_determine_dll_type = DllFinder.determine_dll_type +def determine_dll_type(self, imagename): + dll = os.path.basename(imagename).lower() + if dll.startswith("api-ms-win-") or dll in ("powrprof.dll", "mpr.dll", "crypt32.dll"): # These are definitely system dlls available on all systems and must be excluded. # Including them can cause serious problems when a binary build is run on a different version of Windows. - return 1 - return origIsSystemDLL(pathname) -build_exe.isSystemDLL = isSystemDLL + return None + return orig_determine_dll_type(self, imagename) +DllFinder.determine_dll_type = determine_dll_type -class py2exe(build_exe.py2exe): +class py2exe(distutils_buildexe.py2exe): """Overridden py2exe command to: - * Add a command line option --enable-uiAccess to enable uiAccess for the main executable - * Add extra info to the manifest - * Don't copy w9xpopen, as NVDA will never run on Win9x + * Add a command line option --enable-uiAccess to enable uiAccess for the main executable and EOA proxy + * Add a manifest to the executables """ - user_options = build_exe.py2exe.user_options + [ + user_options = distutils_buildexe.py2exe.user_options + [ ("enable-uiAccess", "u", "enable uiAccess for the main executable"), ] def initialize_options(self): - build_exe.py2exe.initialize_options(self) + super(py2exe, self).initialize_options() self.enable_uiAccess = False - def copy_w9xpopen(self, modules, dlls): - pass - def run(self): dist = self.distribution if self.enable_uiAccess: # Add a target for nvda_uiAccess, using nvda_noUIAccess as a base. target = copy.deepcopy(dist.windows[0]) target["dest_base"] = "nvda_uiAccess" - target["uac_info"] = (target["uac_info"][0], True) + target['uiAccess'] = True dist.windows.insert(1, target) # nvda_eoaProxy should have uiAccess. target = dist.windows[3] - target["uac_info"] = (target["uac_info"][0], True) - - build_exe.py2exe.run(self) - - def build_manifest(self, target, template): - mfest, rid = build_exe.py2exe.build_manifest(self, target, template) - if getattr(target, "script", "").endswith(".pyw"): - # This is one of the main application executables. - mfest = mfest[:mfest.rindex("")] - mfest += MAIN_MANIFEST_EXTRA + "" - return mfest, rid + target['uiAccess'] = True + # Add a manifest resource to every target at runtime. + for target in dist.windows: + target["other_resources"] = [ + ( + RT_MANIFEST, + 1, + (manifest_template % dict(uiAccess=target['uiAccess'])).encode("utf-8") + ), + ] + super(py2exe, self).run() def getLocaleDataFiles(): wxDir=wx.__path__[0] @@ -146,8 +129,6 @@ def getRecursiveDataFiles(dest,source,excludes=()): [rulesList.extend(getRecursiveDataFiles(os.path.join(dest,dirName),os.path.join(source,dirName),excludes=excludes)) for dirName in os.listdir(source) if os.path.isdir(os.path.join(source,dirName)) and not dirName.startswith('.')] return rulesList -compiledModExtention = getModuleExtention(imp.PY_COMPILED) -sourceModExtention = getModuleExtention(imp.PY_SOURCE) setup( name = name, version=version, @@ -169,10 +150,12 @@ def getRecursiveDataFiles(dest,source,excludes=()): { "script":"nvda.pyw", "dest_base":"nvda_noUIAccess", - "uac_info": ("asInvoker", False), + "uiAccess": False, "icon_resources":[(1,"images/nvda.ico")], + "other_resources": [], # Populated at run time "version":formatBuildVersionString(), "description":"NVDA application", + "product_name":name, "product_version":version, "copyright":copyright, "company_name":publisher, @@ -180,9 +163,12 @@ def getRecursiveDataFiles(dest,source,excludes=()): # The nvda_uiAccess target will be added at runtime if required. { "script": "nvda_slave.pyw", + "uiAccess": False, "icon_resources": [(1,"images/nvda.ico")], + "other_resources": [], # Populated at run time "version":formatBuildVersionString(), "description": name, + "product_name":name, "product_version": version, "copyright": copyright, "company_name": publisher, @@ -190,10 +176,12 @@ def getRecursiveDataFiles(dest,source,excludes=()): { "script": "nvda_eoaProxy.pyw", # uiAccess will be enabled at runtime if appropriate. - "uac_info": ("asInvoker", False), + "uiAccess": False, "icon_resources": [(1,"images/nvda.ico")], + "other_resources": [], # Populated at run time "version":formatBuildVersionString(), "description": "NVDA Ease of Access proxy", + "product_name":name, "product_version": version, "copyright": copyright, "company_name": publisher, @@ -201,8 +189,22 @@ def getRecursiveDataFiles(dest,source,excludes=()): ], options = {"py2exe": { "bundle_files": 3, - "excludes": ["Tkinter", - "serial.loopback_connection", "serial.rfc2217", "serial.serialcli", "serial.serialjava", "serial.serialposix", "serial.socket_connection"], + "excludes": ["tkinter", + "serial.loopback_connection", + "serial.rfc2217", + "serial.serialcli", + "serial.serialjava", + "serial.serialposix", + "serial.socket_connection", + # netbios (from pywin32) is optionally used by Python3's uuid module. + # This is not needed. + # We also need to exclude win32wnet explicitly. + "netbios", + "win32wnet", + # winxptheme is optionally used by wx.lib.agw.aui. + # We don't need this. + "winxptheme", + ], "packages": ["NVDAObjects","virtualBuffers","appModules","comInterfaces","brailleDisplayDrivers","synthDrivers"], "includes": [ "nvdaBuiltin", @@ -224,8 +226,22 @@ def getRecursiveDataFiles(dest,source,excludes=()): ] + ( getLocaleDataFiles() + getRecursiveDataFiles("synthDrivers", "synthDrivers", - excludes=("*%s" % sourceModExtention, "*%s" % compiledModExtention, "*.exp", "*.lib", "*.pdb")) - + getRecursiveDataFiles("brailleDisplayDrivers", "brailleDisplayDrivers", excludes=("*%s"%sourceModExtention,"*%s"%compiledModExtention)) + excludes=tuple( + "*%s" % ext + for ext in importlib.machinery.SOURCE_SUFFIXES + importlib.machinery.BYTECODE_SUFFIXES + ) + ( + "*.exp", + "*.lib", + "*.pdb", + "__pycache__" + )) + + getRecursiveDataFiles("brailleDisplayDrivers", "brailleDisplayDrivers", + excludes=tuple( + "*%s" % ext + for ext in importlib.machinery.SOURCE_SUFFIXES + importlib.machinery.BYTECODE_SUFFIXES + ) + ( + "__pycache__", + )) + getRecursiveDataFiles('documentation', '../user_docs', excludes=('*.t2t', '*.t2tconf', '*/developerGuide.*')) ), ) diff --git a/source/sourceEnv.py b/source/sourceEnv.py index 2bc646538c7..87335de57b8 100644 --- a/source/sourceEnv.py +++ b/source/sourceEnv.py @@ -19,6 +19,7 @@ os.path.join(TOP_DIR, "include", "comtypes"), os.path.join(TOP_DIR, "include", "configobj", "src"), os.path.join(TOP_DIR, "include", "wxPython"), + os.path.join(TOP_DIR, "include", "py2exe"), os.path.join(TOP_DIR, "miscDeps", "python"), ) diff --git a/source/speech/__init__.py b/source/speech/__init__.py index 55c3f62a066..010cee29b18 100755 --- a/source/speech/__init__.py +++ b/source/speech/__init__.py @@ -138,7 +138,7 @@ def spellTextInfo(info,useCharacterDescriptions=False,priority=None): return curLanguage=None for field in info.getTextWithFields({}): - if isinstance(field,basestring): + if isinstance(field,str): speakSpelling(field,curLanguage,useCharacterDescriptions=useCharacterDescriptions,priority=priority) elif isinstance(field,textInfos.FieldCommand) and field.command=="formatChange": curLanguage=field.field.get('language') @@ -230,7 +230,7 @@ def speakObjectProperties(obj, reason=controlTypes.REASON_QUERY, priority=None, #Fetch the values for all wanted properties newPropertyValues={} positionInfo=None - for name,value in allowedProperties.iteritems(): + for name,value in allowedProperties.items(): if name=="includeTableCellCoords": # This is verbosity info. newPropertyValues[name]=value @@ -428,9 +428,9 @@ def speakText(text,reason=controlTypes.REASON_MESSAGE,symbolLevel=None,priority= def splitTextIndentation(text): """Splits indentation from the rest of the text. @param text: The text to split. - @type text: basestring + @type text: str @return: Tuple of indentation and content. - @rtype: (basestring, basestring) + @rtype: (str, str) """ return RE_INDENTATION_SPLIT.match(text).groups() @@ -441,11 +441,11 @@ def splitTextIndentation(text): def getIndentationSpeech(indentation, formatConfig): """Retrieves the phrase to be spoken for a given string of indentation. @param indentation: The string of indentation. - @type indentation: unicode + @type indentation: str @param formatConfig: The configuration to use. @type formatConfig: dict @return: The phrase to be spoken. - @rtype: unicode + @rtype: str """ speechIndentConfig = formatConfig["reportLineIndentation"] toneIndentConfig = formatConfig["reportLineIndentationWithTones"] and speechMode == speechMode_talk @@ -500,7 +500,7 @@ def speak(speechSequence, symbolLevel=None, priority=None): import speechViewer if speechViewer.isActive: for item in speechSequence: - if isinstance(item, basestring): + if isinstance(item, str): speechViewer.appendText(item) global beenCanceled if speechMode==speechMode_off: @@ -526,7 +526,7 @@ def speak(speechSequence, symbolLevel=None, priority=None): curLanguage=item.lang if not curLanguage or (not autoDialectSwitching and curLanguage.split('_')[0]==defaultLanguageRoot): curLanguage=defaultLanguage - elif isinstance(item,basestring): + elif isinstance(item,str): if not item: continue if autoLanguageSwitching and curLanguage!=prevLanguage: speechSequence.append(LangChangeCommand(curLanguage)) @@ -545,13 +545,13 @@ def speak(speechSequence, symbolLevel=None, priority=None): symbolLevel=config.conf["speech"]["symbolLevel"] curLanguage=defaultLanguage inCharacterMode=False - for index in xrange(len(speechSequence)): + for index in range(len(speechSequence)): item=speechSequence[index] if isinstance(item,CharacterModeCommand): inCharacterMode=item.state if autoLanguageSwitching and isinstance(item,LangChangeCommand): curLanguage=item.lang - if isinstance(item,basestring): + if isinstance(item,str): speechSequence[index]=processText(curLanguage,item,symbolLevel) if not inCharacterMode: speechSequence[index]+=CHUNK_SEPARATOR @@ -836,7 +836,7 @@ def speakTextInfo(info, useCache=True, formatConfig=None, unit=None, reason=cont raise ValueError("unknown field: %s"%field) #Calculate how many fields in the old and new controlFieldStacks are the same commonFieldCount=0 - for count in xrange(min(len(newControlFieldStack),len(controlFieldStackCache))): + for count in range(min(len(newControlFieldStack),len(controlFieldStackCache))): # #2199: When comparing controlFields try using uniqueID if it exists before resorting to compairing the entire dictionary oldUniqueID=controlFieldStackCache[count].get('uniqueID') newUniqueID=newControlFieldStack[count].get('uniqueID') @@ -849,7 +849,7 @@ def speakTextInfo(info, useCache=True, formatConfig=None, unit=None, reason=cont # We don't do this for focus because hearing "out of list", etc. isn't useful when tabbing or using quick navigation and makes navigation less efficient. if reason!=controlTypes.REASON_FOCUS: endingBlock=False - for count in reversed(xrange(commonFieldCount,len(controlFieldStackCache))): + for count in reversed(range(commonFieldCount,len(controlFieldStackCache))): text=info.getControlFieldSpeech(controlFieldStackCache[count],controlFieldStackCache[0:count],"end_removedFromControlFieldStack",formatConfig,extraDetail,reason=reason) if text: speechSequence.append(text) @@ -865,7 +865,7 @@ def speakTextInfo(info, useCache=True, formatConfig=None, unit=None, reason=cont #Get speech text for any fields that are in both controlFieldStacks, if extra detail is not requested if not extraDetail: - for count in xrange(commonFieldCount): + for count in range(commonFieldCount): field=newControlFieldStack[count] text=info.getControlFieldSpeech(field,newControlFieldStack[0:count],"start_inControlFieldStack",formatConfig,extraDetail,reason=reason) if text: @@ -878,7 +878,7 @@ def speakTextInfo(info, useCache=True, formatConfig=None, unit=None, reason=cont # When true, we are inside a clickable field, and should therefore not announce any more new clickable fields inClickable=False #Get speech text for any fields in the new controlFieldStack that are not in the old controlFieldStack - for count in xrange(commonFieldCount,len(newControlFieldStack)): + for count in range(commonFieldCount,len(newControlFieldStack)): field=newControlFieldStack[count] if not inClickable and formatConfig['reportClickable']: states=field.get('states') @@ -909,7 +909,7 @@ def speakTextInfo(info, useCache=True, formatConfig=None, unit=None, reason=cont if onlyInitialFields or (unit in (textInfos.UNIT_CHARACTER,textInfos.UNIT_WORD) and len(textWithFields)>0 and len(textWithFields[0])==1 and all((isinstance(x,textInfos.FieldCommand) and x.command=="controlEnd") for x in itertools.islice(textWithFields,1,None) )): if not onlyCache: - if onlyInitialFields or any(isinstance(x,basestring) for x in speechSequence): + if onlyInitialFields or any(isinstance(x,str) for x in speechSequence): speak(speechSequence,priority=priority) if not onlyInitialFields: speakSpelling(textWithFields[0],locale=language if autoLanguageSwitching else None,priority=priority) @@ -931,7 +931,7 @@ def speakTextInfo(info, useCache=True, formatConfig=None, unit=None, reason=cont allIndentation="" indentationDone=False for command in textWithFields: - if isinstance(command,basestring): + if isinstance(command,str): # Text should break a run of clickables inClickable=False if reportIndentation and not indentationDone: @@ -1010,7 +1010,7 @@ def speakTextInfo(info, useCache=True, formatConfig=None, unit=None, reason=cont # Don't add this text if it is blank. relativeBlank=True for x in relativeSpeechSequence: - if isinstance(x,basestring) and not isBlank(x): + if isinstance(x,str) and not isBlank(x): relativeBlank=False break if not relativeBlank: @@ -1022,7 +1022,7 @@ def speakTextInfo(info, useCache=True, formatConfig=None, unit=None, reason=cont speechSequence.append(LangChangeCommand(None)) lastLanguage=None if not extraDetail: - for count in reversed(xrange(min(len(newControlFieldStack),commonFieldCount))): + for count in reversed(range(min(len(newControlFieldStack),commonFieldCount))): text=info.getControlFieldSpeech(newControlFieldStack[count],newControlFieldStack[0:count],"end_inControlFieldStack",formatConfig,extraDetail,reason=reason) if text: speechSequence.append(text) @@ -1092,8 +1092,11 @@ def getSpeechTextForProperties(reason=controlTypes.REASON_QUERY,**propertyValues # Don't update the oldTableID if no tableID was given. if tableID and not sameTable: oldTableID = tableID - rowSpan = propertyValues.get("rowSpan") - columnSpan = propertyValues.get("columnSpan") + # When fetching row and column span + # default the values to 1 to make further checks a lot simpler. + # After all, a table cell that has no rowspan implemented is assumed to span one row. + rowSpan = propertyValues.get("rowSpan") or 1 + columnSpan = propertyValues.get("columnSpan") or 1 if rowNumber and (not sameTable or rowNumber != oldRowNumber or rowSpan != oldRowSpan): rowHeaderText = propertyValues.get("rowHeaderText") if rowHeaderText: @@ -1437,9 +1440,9 @@ def getFormatFieldSpeech(attrs,attrsCache=None,formatConfig=None,reason=None,uni backgroundColor2=attrs.get("background-color2") oldBackgroundColor2=attrsCache.get("background-color2") if attrsCache is not None else None bgColorChanged=backgroundColor!=oldBackgroundColor or backgroundColor2!=oldBackgroundColor2 - bgColorText=backgroundColor.name if isinstance(backgroundColor,colors.RGB) else unicode(backgroundColor) + bgColorText=backgroundColor.name if isinstance(backgroundColor,colors.RGB) else backgroundColor if backgroundColor2: - bg2Name=backgroundColor2.name if isinstance(backgroundColor2,colors.RGB) else unicode(backgroundColor2) + bg2Name=backgroundColor2.name if isinstance(backgroundColor2,colors.RGB) else backgroundColor2 # Translators: Reported when there are two background colors. # This occurs when, for example, a gradient pattern is applied to a spreadsheet cell. # {color1} will be replaced with the first background color. @@ -1450,12 +1453,12 @@ def getFormatFieldSpeech(attrs,attrsCache=None,formatConfig=None,reason=None,uni # {color} will be replaced with the text color. # {backgroundColor} will be replaced with the background color. textList.append(_("{color} on {backgroundColor}").format( - color=color.name if isinstance(color,colors.RGB) else unicode(color), + color=color.name if isinstance(color,colors.RGB) else color, backgroundColor=bgColorText)) elif color and color!=oldColor: # Translators: Reported when the text color changes (but not the background color). # {color} will be replaced with the text color. - textList.append(_("{color}").format(color=color.name if isinstance(color,colors.RGB) else unicode(color))) + textList.append(_("{color}").format(color=color.name if isinstance(color,colors.RGB) else color)) elif backgroundColor and bgColorChanged: # Translators: Reported when the background color changes (but not the text color). # {backgroundColor} will be replaced with the background color. @@ -1660,7 +1663,7 @@ def getFormatFieldSpeech(attrs,attrsCache=None,formatConfig=None,reason=None,uni _("no first line indent"), ), } - for attr,(label,noVal) in indentLabels.iteritems(): + for attr,(label,noVal) in indentLabels.items(): newVal=attrs.get(attr) oldVal=attrsCache.get(attr) if attrsCache else None if (newVal or oldVal is not None) and newVal!=oldVal: @@ -1760,7 +1763,7 @@ def getTableInfoSpeech(tableInfo,oldTableInfo,extraDetail=False): textList.append(_("row %s")%rowNumber) return " ".join(textList) -re_last_pause=re.compile(ur"^(.*(?<=[^\s.!?])[.!?][\"'”’)]?(?:\s+|$))(.*$)",re.DOTALL|re.UNICODE) +re_last_pause=re.compile(r"^(.*(?<=[^\s.!?])[.!?][\"'”’)]?(?:\s+|$))(.*$)",re.DOTALL|re.UNICODE) def speakWithoutPauses(speechSequence,detectBreaks=True): """ @@ -1774,7 +1777,7 @@ def speakWithoutPauses(speechSequence,detectBreaks=True): if detectBreaks and speechSequence: sequenceLen=len(speechSequence) spoke = False - for index in xrange(sequenceLen): + for index in range(sequenceLen): if isinstance(speechSequence[index],EndUtteranceCommand): if index>0 and lastStartIndex" if empty else ">") @@ -145,7 +147,7 @@ def _outputTags(self): for tag in reversed(self._openTags): self._closeTag(tag) del self._openTags[:] - for tag, attrs in self._tags.iteritems(): + for tag, attrs in self._tags.items(): self._openTag(tag, attrs) self._openTags.append(tag) self._tagsChanged = False @@ -154,7 +156,7 @@ def generateXml(self, commands): """Generate XML from a sequence of balancer commands and text. """ for command in commands: - if isinstance(command, basestring): + if isinstance(command, str): self._outputTags() self._text(command) elif isinstance(command, EncloseAllCommand): @@ -206,7 +208,7 @@ def generateBalancerCommands(self, speechSequence): @rtype: generator """ for item in speechSequence: - if isinstance(item, basestring): + if isinstance(item, str): yield item elif isinstance(item, speech.SpeechCommand): name = type(item).__name__ diff --git a/source/synthDriverHandler.py b/source/synthDriverHandler.py index 5ce2e9fadd0..d4574bd3953 100644 --- a/source/synthDriverHandler.py +++ b/source/synthDriverHandler.py @@ -7,6 +7,7 @@ import os import pkgutil +import importlib import config import baseObject import winVersion @@ -38,7 +39,7 @@ def changeVoice(synth, voice): speechDictHandler.loadVoiceDict(synth) def _getSynthDriver(name): - return __import__("synthDrivers.%s" % name, globals(), locals(), ("synthDrivers",)).SynthDriver + return importlib.import_module("synthDrivers.%s" % name, package="synthDrivers").SynthDriver def getSynthList(): synthList=[] @@ -274,7 +275,7 @@ def speak(self,speechSequence): if item is None: # No more items. break - if isinstance(item,basestring): + if isinstance(item,str): # Merge the text between commands into a single chunk. text+=item elif isinstance(item,speech.IndexCommand): diff --git a/source/synthDrivers/_espeak.py b/source/synthDrivers/_espeak.py index 7f0233dbbca..306b6c5d47e 100755 --- a/source/synthDrivers/_espeak.py +++ b/source/synthDrivers/_espeak.py @@ -8,10 +8,7 @@ import time import nvwave import threading -try: - import Queue as queue # Python 2.7 import -except ImportError: - import queue # Python 3 import +import queue from ctypes import * import config import globalVars @@ -121,10 +118,21 @@ class espeak_VOICE(Structure): def __eq__(self, other): return isinstance(other, type(self)) and addressof(self) == addressof(other) + # As __eq__ was defined on this class, we must provide __hash__ to remain hashable. + # The default hash implementation is fine for our purposes. + def __hash__(self): + return super().__hash__() + # constants that can be returned by espeak_callback CALLBACK_CONTINUE_SYNTHESIS=0 CALLBACK_ABORT_SYNTHESIS=1 +def encodeEspeakString(text): + return text.encode('utf8') + +def decodeEspeakString(data): + return data.decode('utf8') + t_espeak_callback=CFUNCTYPE(c_int,POINTER(c_short),c_int,POINTER(espeak_EVENT)) @t_espeak_callback @@ -136,12 +144,12 @@ def callback(wav,numsamples,event): indexes = [] for e in event: if e.type==espeakEVENT_MARK: - indexNum = int(e.id.name) + indexNum = int(decodeEspeakString(e.id.name)) # e.audio_position is ms since the start of this utterance. # Convert to bytes since the start of the utterance. BYTES_PER_SAMPLE = 2 MS_PER_SEC = 1000 - bytesPerMS = player.samplesPerSec * BYTES_PER_SAMPLE / MS_PER_SEC + bytesPerMS = player.samplesPerSec * BYTES_PER_SAMPLE // MS_PER_SEC indexByte = e.audio_position * bytesPerMS # Subtract bytes in the utterance that have already been handled # to give us the byte offset into the samples for this callback. @@ -154,7 +162,7 @@ def callback(wav,numsamples,event): onIndexReached(None) isSpeaking = False return CALLBACK_CONTINUE_SYNTHESIS - wav = string_at(wav, numsamples * sizeof(c_short)) if numsamples>0 else "" + wav = string_at(wav, numsamples * sizeof(c_short)) if numsamples>0 else b"" prevByte = 0 for indexNum, indexByte in indexes: player.feed(wav[prevByte:indexByte], @@ -185,10 +193,8 @@ def run(self): log.error("Error running function from queue", exc_info=True) bgQueue.task_done() -def _execWhenDone(func, *args, **kwargs): +def _execWhenDone(func, *args, mustBeAsync=False, **kwargs): global bgQueue - # This can't be a kwarg in the function definition because it will consume the first non-keywor dargument which is meant for func. - mustBeAsync = kwargs.pop("mustBeAsync", False) if mustBeAsync or bgQueue.unfinished_tasks != 0: # Either this operation must be asynchronous or There is still an operation in progress. # Therefore, run this asynchronously in the background thread. @@ -264,10 +270,11 @@ def setVoice(voice): setVoiceByName(voice.identifier) def setVoiceByName(name): - _execWhenDone(espeakDLL.espeak_SetVoiceByName,name) + _execWhenDone(espeakDLL.espeak_SetVoiceByName,encodeEspeakString(name)) def _setVoiceAndVariant(voice=None, variant=None): - res = getCurrentVoice().identifier.split("+") + v=getCurrentVoice() + res = decodeEspeakString(v.identifier).split("+") if not voice: voice = res[0] if not variant: @@ -276,12 +283,12 @@ def _setVoiceAndVariant(voice=None, variant=None): else: variant = "none" if variant == "none": - espeakDLL.espeak_SetVoiceByName(voice) + espeakDLL.espeak_SetVoiceByName(encodeEspeakString(voice)) else: try: - espeakDLL.espeak_SetVoiceByName("%s+%s" % (voice, variant)) + espeakDLL.espeak_SetVoiceByName(encodeEspeakString("%s+%s" % (voice, variant))) except: - espeakDLL.espeak_SetVoiceByName(voice) + espeakDLL.espeak_SetVoiceByName(encodeEspeakString(voice)) def setVoiceAndVariant(voice=None, variant=None): _execWhenDone(_setVoiceAndVariant, voice=voice, variant=variant) @@ -289,11 +296,11 @@ def setVoiceAndVariant(voice=None, variant=None): def _setVoiceByLanguage(lang): v=espeak_VOICE() lang=lang.replace('_','-') - v.languages=lang + v.languages=encodeEspeakString(lang) try: espeakDLL.espeak_SetVoiceByProperties(byref(v)) except: - v.languages="en" + v.languages=encodeEspeakString("en") espeakDLL.espeak_SetVoiceByProperties(byref(v)) def setVoiceByLanguage(lang): @@ -321,8 +328,9 @@ def initialize(indexCallback=None): espeakDLL.espeak_ListVoices.restype=POINTER(POINTER(espeak_VOICE)) espeakDLL.espeak_GetCurrentVoice.restype=POINTER(espeak_VOICE) espeakDLL.espeak_SetVoiceByName.argtypes=(c_char_p,) + eSpeakPath=os.path.abspath("synthDrivers") sampleRate=espeakDLL.espeak_Initialize(AUDIO_OUTPUT_SYNCHRONOUS,300, - os.path.abspath("synthDrivers"),0) + os.fsencode(eSpeakPath),0) if sampleRate<0: raise OSError("espeak_Initialize %d"%sampleRate) player = nvwave.WavePlayer(channels=1, samplesPerSec=sampleRate, bitsPerSample=16, @@ -356,16 +364,23 @@ def getVariantDict(): # Translators: name of the default espeak varient. variantDict={"none": pgettext("espeakVarient", "none")} for fileName in os.listdir(dir): - if os.path.isfile("%s\\%s"%(dir,fileName)): - file=codecs.open("%s\\%s"%(dir,fileName)) - for line in file: - if line.startswith('name '): - temp=line.split(" ") - if len(temp) ==2: - name=temp[1].rstrip() - break - name=None - file.close() + absFilePath = os.path.join(dir, fileName) + if os.path.isfile(absFilePath): + # In python 3, open assumes the default system encoding by default. + # This fails if Windows' "use Unicode UTF-8 for worldwide language support" option is enabled. + # The expected encoding is unknown, therefore use latin-1 to stay as close to Python 2 behavior as possible. + try: + with open(absFilePath, 'r', encoding="latin-1") as file: + for line in file: + if line.startswith('name '): + temp=line.split(" ") + if len(temp) ==2: + name=temp[1].rstrip() + break + name=None + except: + log.error("Couldn't parse espeak variant file %s" % fileName, exc_info=True) + continue if name is not None: variantDict[fileName]=name return variantDict diff --git a/source/synthDrivers/espeak.py b/source/synthDrivers/espeak.py index d4019f01851..2f2ad27b54c 100644 --- a/source/synthDrivers/espeak.py +++ b/source/synthDrivers/espeak.py @@ -8,7 +8,6 @@ import os from collections import OrderedDict from . import _espeak -import Queue import threading import languageHandler from synthDriverHandler import SynthDriver, VoiceInfo, synthIndexReached, synthDoneSpeaking @@ -73,7 +72,6 @@ def _get_language(self): } def _processText(self, text): - text = unicode(text) # We need to make several replacements. return text.translate({ 0x1: None, # used for embedded commands @@ -91,7 +89,7 @@ def speak(self,speechSequence): # . # However, eSpeak doesn't seem to mind. for item in speechSequence: - if isinstance(item,basestring): + if isinstance(item,str): textList.append(self._processText(item)) elif isinstance(item,speech.IndexCommand): textList.append(""%item.index) @@ -120,11 +118,11 @@ def speak(self,speechSequence): if not prosody: continue textList.append("") elif isinstance(item,speech.PhonemeCommand): - # We can't use unicode.translate because we want to reject unknown characters. + # We can't use str.translate because we want to reject unknown characters. try: phonemes="".join([self.IPA_TO_ESPEAK[char] for char in item.ipa]) # There needs to be a space after the phoneme command. @@ -200,11 +198,11 @@ def _set_volume(self,volume): def _getAvailableVoices(self): voices=OrderedDict() for v in _espeak.getVoiceList(): - l=v.languages[1:] + l=_espeak.decodeEspeakString(v.languages[1:]) # #7167: Some languages names contain unicode characters EG: Norwegian Bokmål - name=v.name.decode("UTF-8") + name=_espeak.decodeEspeakString(v.name) # #5783: For backwards compatibility, voice identifies should always be lowercase - identifier=os.path.basename(v.identifier).lower() + identifier=os.path.basename(_espeak.decodeEspeakString(v.identifier)).lower() voices[identifier]=VoiceInfo(identifier,name,l) return voices @@ -215,7 +213,7 @@ def _get_voice(self): if not curVoice: return "" # #5783: For backwards compatibility, voice identifies should always be lowercase - return curVoice.identifier.split('+')[0].lower() + return _espeak.decodeEspeakString(curVoice.identifier).split('+')[0].lower() def _set_voice(self, identifier): if not identifier: @@ -249,4 +247,4 @@ def _set_variant(self,val): _espeak.setVoiceAndVariant(variant=self._variant) def _getAvailableVariants(self): - return OrderedDict((ID,VoiceInfo(ID, name)) for ID, name in self._variantDict.iteritems()) + return OrderedDict((ID,VoiceInfo(ID, name)) for ID, name in self._variantDict.items()) diff --git a/source/synthDrivers/oneCore.py b/source/synthDrivers/oneCore.py index ba3d38ce8cd..512a2a4d4cc 100644 --- a/source/synthDrivers/oneCore.py +++ b/source/synthDrivers/oneCore.py @@ -11,13 +11,10 @@ import sys from collections import OrderedDict import ctypes -try: - import _winreg as winreg # Python 2.7 import -except ImportError: - import winreg # Python 3 import +import winreg import wave -import cStringIO from synthDriverHandler import SynthDriver, VoiceInfo, synthIndexReached, synthDoneSpeaking +import io from logHandler import log import config import nvwave @@ -120,13 +117,8 @@ class SynthDriver(SynthDriver): @classmethod def check(cls): - if not hasattr(sys, "frozen"): - # #3793: Source copies don't report the correct version on Windows 10 because Python isn't manifested for higher versions. - # We want this driver to work for source copies on Windows 10, so just return True here. - # If this isn't in fact Windows 10, it will fail when constructed, which is okay. - return True - # For binary copies, only present this as an available synth if this is Windows 10. - return winVersion.winVersion.major >= 10 + # Only present this as an available synth if this is Windows 10. + return winVersion.isWin10() def _get_supportsProsodyOptions(self): self.supportsProsodyOptions = self._dll.ocSpeech_supportsProsodyOptions() @@ -207,7 +199,7 @@ def cancel(self): if self.supportsProsodyOptions: # In this case however, we must keep any parameter changes. self._queuedSpeech = [item for item in self._queuedSpeech - if not isinstance(item, basestring)] + if not isinstance(item, str)] else: self._queuedSpeech = [] if self._player: @@ -329,7 +321,7 @@ def _callback(self, bytes, len, markers): self._processQueue() return # This gets called in a background thread. - stream = cStringIO.StringIO(ctypes.string_at(bytes, len)) + stream = io.BytesIO(ctypes.string_at(bytes, len)) wav = wave.open(stream, "r") self._maybeInitPlayer(wav) data = wav.readframes(wav.getnframes()) @@ -349,7 +341,7 @@ def _callback(self, bytes, len, markers): # pos is a time offset in 100-nanosecond units. # Convert this to a byte offset. # Order the equation so we don't have to do floating point. - pos = pos * self._bytesPerSec / HUNDRED_NS_PER_SEC + pos = pos * self._bytesPerSec // HUNDRED_NS_PER_SEC # Push audio up to this marker. self._player.feed(data[prevPos:pos], onDone=lambda index=index: synthIndexReached.notify(synth=self, index=index)) @@ -406,7 +398,7 @@ def _isVoiceValid(self,ID): except WindowsError as e: log.debugWarning("Could not open registry value 'langDataPath', %r" % e) return False - if not langDataPath or not isinstance(langDataPath[0], basestring): + if not langDataPath or not isinstance(langDataPath[0], str): log.debugWarning("Invalid langDataPath value") return False if not os.path.isfile(os.path.expandvars(langDataPath[0])): @@ -417,7 +409,7 @@ def _isVoiceValid(self,ID): except WindowsError as e: log.debugWarning("Could not open registry value 'langDataPath', %r" % e) return False - if not voicePath or not isinstance(voicePath[0],basestring): + if not voicePath or not isinstance(voicePath[0],str): log.debugWarning("Invalid voicePath value") return False if not os.path.isfile(os.path.expandvars(voicePath[0] + '.apm')): @@ -431,7 +423,7 @@ def _get_voice(self): def _set_voice(self, id): voices = self.availableVoices # Try setting the requested voice - for voice in voices.itervalues(): + for voice in voices.values(): if voice.id == id: self._dll.ocSpeech_setVoice(self._handle, voice.onecoreIndex) return @@ -449,16 +441,16 @@ def _getDefaultVoice(self): voices = self.availableVoices # Try matching to NVDA language fullLanguage=languageHandler.getWindowsLanguage() - for voice in voices.itervalues(): + for voice in voices.values(): if voice.language==fullLanguage: return voice.id baseLanguage=fullLanguage.split('_')[0] if baseLanguage!=fullLanguage: - for voice in voices.itervalues(): + for voice in voices.values(): if voice.language.startswith(baseLanguage): return voice.id # Just use the first available - for voice in voices.itervalues(): + for voice in voices.values(): return voice.id raise RuntimeError("No voices available") diff --git a/source/synthDrivers/sapi4.py b/source/synthDrivers/sapi4.py index 20c1e395306..21d33cd8ee9 100755 --- a/source/synthDrivers/sapi4.py +++ b/source/synthDrivers/sapi4.py @@ -6,10 +6,7 @@ import locale from collections import OrderedDict -try: - import _winreg as winreg # Python 2.7 import -except ImportError: - import winreg # Python 3 import +import winreg from comtypes import COMObject, COMError from ctypes import * from synthDriverHandler import SynthDriver,VoiceInfo, synthIndexReached, synthDoneSpeaking @@ -91,7 +88,7 @@ def speak(self,speechSequence): charMode=False item=None for item in speechSequence: - if isinstance(item,basestring): + if isinstance(item,str): textList.append(item.replace('\\','\\\\')) elif isinstance(item,speech.IndexCommand): textList.append("\\mrk=%d\\"%item.index) diff --git a/source/synthDrivers/sapi5.py b/source/synthDrivers/sapi5.py index c5abc1e0c91..e2ec5e0bd27 100644 --- a/source/synthDrivers/sapi5.py +++ b/source/synthDrivers/sapi5.py @@ -13,10 +13,7 @@ from ctypes import * import comtypes.client from comtypes import COMError -try: - import _winreg as winreg # Python 2.7 import -except ImportError: - import winreg # Python 3 import +import winreg import audioDucking import NVDAHelper import globalVars @@ -37,9 +34,9 @@ class FunctionHooker(object): def __init__(self,targetDll,importDll,funcName,newFunction): hook=NVDAHelper.localLib.dllImportTableHooks_hookSingle(targetDll,importDll,funcName,newFunction) if hook: - print "hooked %s"%funcName + log.debug("hooked %s"%funcName) else: - print "could not hook %s"%funcName + log.debug("could not hook %s"%funcName) raise RuntimeError("could not hook %s"%funcName) def __del__(self): @@ -147,7 +144,7 @@ def _getAvailableVoices(self): v=self._getVoiceTokens() # #2629: Iterating uses IEnumVARIANT and GetBestInterface doesn't work on tokens returned by some token enumerators. # Therefore, fetch the items by index, as that method explicitly returns the correct interface. - for i in xrange(len(v)): + for i in range(len(v)): try: ID=v[i].Id name=v[i].GetDescription() @@ -184,7 +181,7 @@ def _get_lastIndex(self): return None def _percentToRate(self, percent): - return (percent - 50) / 5 + return (percent - 50) // 5 def _set_rate(self,rate): self.tts.Rate = self._percentToRate(rate) @@ -220,7 +217,7 @@ def _set_voice(self,value): tokens = self._getVoiceTokens() # #2629: Iterating uses IEnumVARIANT and GetBestInterface doesn't work on tokens returned by some token enumerators. # Therefore, fetch the items by index, as that method explicitly returns the correct interface. - for i in xrange(len(tokens)): + for i in range(len(tokens)): voice=tokens[i] if value==voice.Id: break @@ -230,7 +227,7 @@ def _set_voice(self,value): self._initTts(voice=voice) def _percentToPitch(self, percent): - return percent / 2 - 25 + return percent // 2 - 25 IPA_TO_SAPI = { u"θ": u"th", @@ -272,9 +269,9 @@ def outputTags(): for tag in reversed(openedTags): textList.append("" % tag) del openedTags[:] - for tag, attrs in tags.iteritems(): + for tag, attrs in tags.items(): textList.append("<%s" % tag) - for attr, val in attrs.iteritems(): + for attr, val in attrs.items(): textList.append(' %s="%s"' % (attr, val)) textList.append(">") openedTags.append(tag) @@ -287,7 +284,7 @@ def outputTags(): volume = self.volume for item in speechSequence: - if isinstance(item, basestring): + if isinstance(item, str): outputTags() textList.append(item.replace("<", "<")) elif isinstance(item, speech.IndexCommand): diff --git a/source/synthSettingsRing.py b/source/synthSettingsRing.py index 5b1d7c735bf..215dc1eeca6 100644 --- a/source/synthSettingsRing.py +++ b/source/synthSettingsRing.py @@ -38,7 +38,7 @@ def _get_reportValue(self): class StringSynthSetting(SynthSetting): def __init__(self,synth,setting): - self._values=getattr(synth,"available%ss"%setting.id.capitalize()).values() + self._values=list(getattr(synth,"available%ss"%setting.id.capitalize()).values()) super(StringSynthSetting,self).__init__(synth,setting,0,len(self._values)-1) def _get_value(self): diff --git a/source/tableUtils.py b/source/tableUtils.py index 145b43de154..179e35e1ddc 100644 --- a/source/tableUtils.py +++ b/source/tableUtils.py @@ -8,7 +8,7 @@ class HeaderCellInfo(object): def __init__(self,**kwargs): self.rowSpan=self.colSpan=1 self.minColumnNumber=self.maxColumnNumber=self.minRowNumber=self.maxRowNumber=None - for name,value in kwargs.iteritems(): + for name,value in kwargs.items(): setattr(self,name,value) class HeaderCellTracker(object): diff --git a/source/textInfos/__init__.py b/source/textInfos/__init__.py index e0a0364c1f0..391d3f644bf 100755 --- a/source/textInfos/__init__.py +++ b/source/textInfos/__init__.py @@ -181,6 +181,11 @@ def __eq__(self,other): if isinstance(other,Bookmark) and self.infoClass==other.infoClass and self.data==other.data: return True + # As __eq__ was defined on this class, we must provide __hash__ to remain hashable. + # The default hash implementation is fine for our purposes. + def __hash__(self): + return super().__hash__() + def __ne__(self,other): return not self==other @@ -257,7 +262,7 @@ def _get_text(self): """The text with in this range. Subclasses must implement this. @return: The text. - @rtype: unicode + @rtype: str @note: The text is not guaranteed to be the exact length of the range in offsets. """ raise NotImplementedError @@ -268,7 +273,7 @@ def getTextWithFields(self,formatConfig=None): @param formatConfig: Document formatting configuration, useful if you wish to force a particular configuration for a particular task. @type formatConfig: dict @return: A sequence of text strings interspersed with associated field commands. - @rtype: list of unicode and L{FieldCommand} + @rtype: list of str and L{FieldCommand} """ return [self.text] @@ -484,7 +489,7 @@ def getFormatFieldSpeech(self, attrs, attrsCache=None, formatConfig=None, reason If extended, the superclass should be called first. @param separator: The text used to separate chunks of format information; defaults to L{speech.CHUNK_SEPARATOR}. - @type separator: basestring + @type separator: str """ # Import late to avoid circular import. import speech diff --git a/source/textInfos/offsets.py b/source/textInfos/offsets.py index 7b7b319c2e6..ff3e8de8fc4 100755 --- a/source/textInfos/offsets.py +++ b/source/textInfos/offsets.py @@ -14,46 +14,31 @@ import locationHelper from treeInterceptorHandler import TreeInterceptor import api -from six.moves import range - -HIGH_SURROGATE_FIRST = u"\uD800" -HIGH_SURROGATE_LAST = u"\uDBFF" -LOW_SURROGATE_FIRST = u"\uDC00" -LOW_SURROGATE_LAST = u"\uDFFF" - -class Offsets(object): +import textUtils +from dataclasses import dataclass +from typing import Optional +import locale +from logHandler import log + +@dataclass +class Offsets: """Represents two offsets.""" + #: the first offset. + startOffset: int + #: the second offset. + endOffset: int - def __init__(self,startOffset,endOffset): - """ - @param startOffset: the first offset. - @type startOffset: integer - @param endOffset: the second offset. - @type endOffset: integer - """ - self.startOffset=startOffset - self.endOffset=endOffset - - def __eq__(self,other): - if isinstance(other,self.__class__) and self.startOffset==other.startOffset and self.endOffset==other.endOffset: - return True - else: - return False - - def __ne__(self,other): - return not self==other - def findStartOfLine(text,offset,lineLength=None): """Searches backwards through the given text from the given offset, until it finds the offset that is the start of the line. With out a set line length, it searches for new line / cariage return characters, with a set line length it simply moves back to sit on a multiple of the line length. -@param text: the text to search -@type text: string -@param offset: the offset of the text to start at -@type offset: int -@param lineLength: The number of characters that makes up a line, None if new line characters should be looked at instead -@type lineLength: int or None -@return: the found offset -@rtype: int -""" + @param text: the text to search + @type text: str + @param offset: the offset of the text to start at + @type offset: int + @param lineLength: The number of characters that makes up a line, None if new line characters should be looked at instead + @type lineLength: int or None + @return: the found offset + @rtype: int + """ if not text: return 0 if offset>=len(text): @@ -71,15 +56,15 @@ def findStartOfLine(text,offset,lineLength=None): def findEndOfLine(text,offset,lineLength=None): """Searches forwards through the given text from the given offset, until it finds the offset that is the start of the next line. With out a set line length, it searches for new line / cariage return characters, with a set line length it simply moves forward to sit on a multiple of the line length. -@param text: the text to search -@type text: unicode -@param offset: the offset of the text to start at -@type offset: int -@param lineLength: The number of characters that makes up a line, None if new line characters should be looked at instead -@type lineLength: int or None -@return: the found offset -@rtype: int -""" + @param text: the text to search + @type text: str + @param offset: the offset of the text to start at + @type offset: int + @param lineLength: The number of characters that makes up a line, None if new line characters should be looked at instead + @type lineLength: int or None + @return: the found offset + @rtype: int + """ if not text: return 0 if offset>=len(text): @@ -98,15 +83,15 @@ def findEndOfLine(text,offset,lineLength=None): def findStartOfWord(text,offset,lineLength=None): """Searches backwards through the given text from the given offset, until it finds the offset that is the start of the word. It checks to see if a character is alphanumeric, or is another symbol , or is white space. -@param text: the text to search -@type text: unicode -@param offset: the offset of the text to start at -@type offset: int -@param lineLength: The number of characters that makes up a line, None if new line characters should be looked at instead -@type lineLength: int or None -@return: the found offset -@rtype: int -""" + @param text: the text to search + @type text: str + @param offset: the offset of the text to start at + @type offset: int + @param lineLength: The number of characters that makes up a line, None if new line characters should be looked at instead + @type lineLength: int or None + @return: the found offset + @rtype: int + """ if offset>=len(text): return offset while offset>0 and text[offset].isspace(): @@ -120,15 +105,15 @@ def findStartOfWord(text,offset,lineLength=None): def findEndOfWord(text,offset,lineLength=None): """Searches forwards through the given text from the given offset, until it finds the offset that is the start of the next word. It checks to see if a character is alphanumeric, or is another symbol , or is white space. -@param text: the text to search -@type text: unicode -@param offset: the offset of the text to start at -@type offset: int -@param lineLength: The number of characters that makes up a line, None if new line characters should be looked at instead -@type lineLength: int or None -@return: the found offset -@rtype: int -""" + @param text: the text to search + @type text: str + @param offset: the offset of the text to start at + @type offset: int + @param lineLength: The number of characters that makes up a line, None if new line characters should be looked at instead + @type lineLength: int or None + @return: the found offset + @rtype: int + """ if offset>=len(text): return offset+1 if unicodedata.category(text[offset])[0] in "LMN": @@ -158,8 +143,12 @@ class OffsetsTextInfo(textInfos.TextInfo): Note that the base implementation of L{_getPointFromOffset} uses L{_getBoundingRectFromOffset}. """ - detectFormattingAfterCursorMaybeSlow=True #: honours documentFormatting config option if true - set to false if this is not at all slow. - useUniscribe=True #Use uniscribe to calculate word offsets etc + #: Honours documentFormatting config option if true - set to false if this is not at all slow. + detectFormattingAfterCursorMaybeSlow: bool = True + #: Use uniscribe to calculate word offsets etc. + useUniscribe: bool = True + #: The encoding internal to the underlying text info implementation. + encoding: Optional[str] = textUtils.WCHAR_ENCODING def __eq__(self,other): if self is other or (isinstance(other,OffsetsTextInfo) and self._startOffset==other._startOffset and self._endOffset==other._endOffset): @@ -167,6 +156,11 @@ def __eq__(self,other): else: return False + # As __eq__ was defined on this class, we must provide __hash__ to remain hashable. + # The default hash implementation is fine for our purposes. + def __hash__(self): + return super().__hash__() + def _get_locationText(self): textList=[] storyLength=self._getStoryLength() or 1 @@ -271,7 +265,7 @@ def _getStoryLength(self): def _getStoryText(self): """Retrieve the entire text of the object. @return: The entire text of the object. - @rtype: unicode + @rtype: str """ raise NotImplementedError @@ -282,10 +276,15 @@ def _getTextRange(self,start,end): @param end: The end offset (exclusive). @type end: int @return: The text contained in the requested range. - @rtype: unicode + @rtype: str """ text=self._getStoryText() - return text[start:end] if text else u"" + if self.encoding == textUtils.WCHAR_ENCODING: + offsetConverter = textUtils.WideStringOffsetConverter(text) + start, end = offsetConverter.wideToStrOffsets(start, end) + elif self.encoding not in (None, "utf_32_le", locale.getlocale()[1]): + raise NotImplementedError + return text[start:end] def _getFormatFieldAndOffsets(self,offset,formatConfig,calculateOffsets=True): """Retrieve the formatting information for a given offset and the offsets spanned by that field. @@ -303,43 +302,50 @@ def _getFormatFieldAndOffsets(self,offset,formatConfig,calculateOffsets=True): return formatField,(startOffset,endOffset) def _getCharacterOffsets(self,offset): - # Windows Unicode is UTF-16, so a character may be two offsets for code points beyond 16 bits. - if offset > 0: - chars = self._getTextRange(offset - 1, offset + 2) - # Slicing avoids the need to check length. If invalid, it'll be the empty string. - prevChar = chars[0:1] - curChar = chars[1:2] - nextChar = chars[2:3] - else: - chars = self._getTextRange(offset, offset + 2) - prevChar = u"" # Empty string, any subsequent comparisons will evaluate to False. - # Slicing avoids the need to check length. If invalid, it'll be the empty string. - curChar = chars[0:1] - nextChar = chars[1:2] - if HIGH_SURROGATE_FIRST <= curChar <= HIGH_SURROGATE_LAST and LOW_SURROGATE_FIRST <= nextChar <= LOW_SURROGATE_LAST: - # curChar is a high (leading) surrogate; - # nextChar is a low surrogate and also part of this character. - return offset, offset + 2 - elif HIGH_SURROGATE_FIRST <= prevChar <= HIGH_SURROGATE_LAST and LOW_SURROGATE_FIRST <= curChar <= LOW_SURROGATE_LAST: - # curChar is a low (trailing) surrogate; - # prevChar is a high surrogate and also part of this character. - return offset - 1, offset + 1 + if self.encoding == textUtils.WCHAR_ENCODING: + lineStart,lineEnd=self._getLineOffsets(offset) + lineText=self._getTextRange(lineStart,lineEnd) + offsetConverter = textUtils.WideStringOffsetConverter(lineText) + relOffset = offset - lineStart + relStrStart, relStrEnd = offsetConverter.wideToStrOffsets(relOffset, relOffset + 1) + relWideStringStart, relWideStringEnd = offsetConverter.strToWideOffsets(relStrStart, relStrEnd) + return (relWideStringStart + lineStart, relWideStringEnd + lineStart) + elif self.encoding not in (None, "utf_32_le", locale.getlocale()[1]): + raise NotImplementedError return offset, offset + 1 def _getWordOffsets(self,offset): - lineStart,lineEnd=self._getLineOffsets(offset) - lineText=self._getTextRange(lineStart,lineEnd) - #Convert NULL and non-breaking space to space to make sure that words will break on them - lineText=lineText.translate({0:u' ',0xa0:u' '}) + if self.encoding not in (textUtils.WCHAR_ENCODING, None, "utf_32_le", locale.getlocale()[1]): + raise NotImplementedError + lineStart, lineEnd = self._getLineOffsets(offset) + relOffset = offset - lineStart + lineText = self._getTextRange(lineStart,lineEnd) + # Convert NULL and non-breaking space to space to make sure that words will break on them + lineText = lineText.translate({0:u' ',0xa0:u' '}) if self.useUniscribe: - start=ctypes.c_int() - end=ctypes.c_int() - #uniscribe does some strange things when you give it a string with not more than two alphanumeric chars in a row. - #Inject two alphanumeric characters at the end to fix this - lineText+="xx" - if NVDAHelper.localLib.calculateWordOffsets(lineText,len(lineText),offset-lineStart,ctypes.byref(start),ctypes.byref(end)): - return start.value+lineStart,min(end.value+lineStart,lineEnd) + relStart=ctypes.c_int() + relEnd=ctypes.c_int() + # uniscribe does some strange things when you give it a string with not more than two alphanumeric chars in a row. + # Inject two alphanumeric characters at the end to fix this + lineText += "xx" + # We can't rely on len(lineText) to calculate the length of the line. + lineLength = (lineEnd - lineStart) + 2 + if NVDAHelper.localLib.calculateWordOffsets(lineText, lineLength, relOffset, ctypes.byref(relStart), ctypes.byref(relEnd)): + relStart = relStart.value + relEnd = relEnd.value + if self.encoding != textUtils.WCHAR_ENCODING: + # We need to convert the uniscribe based offsets to str offsets. + offsetConverter = textUtils.WideStringOffsetConverter(lineText) + relStart, relEnd = offsetConverter.wideToStrOffsets(relStart, relEnd) + return (relStart + lineStart , relEnd + lineStart) #Fall back to the older word offsets detection that only breaks on non alphanumeric + if self.encoding == textUtils.WCHAR_ENCODING: + offsetConverter = textUtils.WideStringOffsetConverter(lineText) + relStrOffset = offsetConverter.wideToStrOffsets(relOffset, relOffset)[0] + relStrStart = findStartOfWord(lineText, relStrOffset) + relStrEnd = findEndOfWord(lineText, relStrOffset) + relWideStringStart, relWideStringEnd = offsetConverter.strToWideOffsets(relStrStart, relStrEnd) + return (relWideStringStart + lineStart, relWideStringEnd + lineStart) start=findStartOfWord(lineText,offset-lineStart)+lineStart end=findEndOfWord(lineText,offset-lineStart)+lineStart return [start,end] @@ -347,9 +353,16 @@ def _getWordOffsets(self,offset): def _getLineNumFromOffset(self,offset): return None - def _getLineOffsets(self,offset): text=self._getStoryText() + if self.encoding == textUtils.WCHAR_ENCODING: + offsetConverter = textUtils.WideStringOffsetConverter(text) + strOffset = offsetConverter.wideToStrOffsets(offset, offset)[0] + strStart=findStartOfLine(text, strOffset) + strEnd=findEndOfLine(text, strOffset) + return offsetConverter.strToWideOffsets(strStart, strEnd) + elif self.encoding not in (None, "utf_32_le", locale.getlocale()[1]): + raise NotImplementedError start=findStartOfLine(text,offset) end=findEndOfLine(text,offset) return [start,end] @@ -357,7 +370,6 @@ def _getLineOffsets(self,offset): def _getParagraphOffsets(self,offset): return self._getLineOffsets(offset) - def _getReadingChunkOffsets(self,offset): return self._getLineOffsets(offset) @@ -396,7 +408,7 @@ def __init__(self,obj,position): # This is a direct TextInfo to TextInfo copy. # Copy over the contents of the property cache, and any private instance variables (includes the TextInfo's offsets) self._propertyCache.update(position._propertyCache) - self.__dict__.update({x:y for x,y in position.__dict__.iteritems() if x.startswith('_') and x!='_propertyCache'}) + self.__dict__.update({x:y for x,y in position.__dict__.items() if x.startswith('_') and x!='_propertyCache'}) elif position==textInfos.POSITION_FIRST: self._startOffset=self._endOffset=0 elif position==textInfos.POSITION_LAST: diff --git a/source/textUtils.py b/source/textUtils.py new file mode 100644 index 00000000000..69cbebb921c --- /dev/null +++ b/source/textUtils.py @@ -0,0 +1,237 @@ +# -*- coding: UTF-8 -*- +#textUtils.py +#A part of NonVisual Desktop Access (NVDA) +#This file is covered by the GNU General Public License. +#See the file COPYING for more details. +#Copyright (C) 2018-2019 NV Access Limited, Babbage B.V. + +""" +Classes and utilities to deal with offsets variable width encodings, particularly utf_16. +""" + +import encodings +import sys +import ctypes +from collections.abc import ByteString +from typing import Tuple, Optional +import locale +from logHandler import log + +WCHAR_ENCODING = "utf_16_le" + +class WideStringOffsetConverter: + R""" + Object that holds a string in both its decoded and its UTF-16 encoded form. + The object allows for easy conversion between offsets in str type strings, + and offsets in wide character (UTF-16) strings (that are aware of surrogate characters). + This representation is used by all wide character strings in Windows (i.e. with characters of type L{ctypes.c_wchar}). + + In Python 3 strings, every offset in a string corresponds with one unicode codepoint. + In UTF-16 encoded strings, 32-bit unicode characters (such as emoji) + are encoded as one high surrogate and one low surrogate character. + Therefore, they take not one, but two offsets in such a string. + This behavior is equivalent to how Python 2 unicode strings behave, + which are internally encoded as UTF-16. + + For example: 😂 takes one offset in a Python 3 string. + However, in a Python 2 string or UTF-16 encoded wide string, + this character internally consists of two characters: \ud83d and \ude02. + """ + + _encoding: str = WCHAR_ENCODING + _bytesPerIndex: int = ctypes.sizeof(ctypes.c_wchar) + + def __init__(self, text: str): + super().__init__() + if not isinstance(text, str): + raise TypeError("Value must be of type str") + self.decoded: str = text + self.encoded: bytes = text.encode(self._encoding, errors="surrogatepass") + + def __repr__(self): + return "{}({})".format(self.__class__.__name__, repr(self.decoded)) + + @property + def wideStringLength(self) -> int: + """Returns the length of the string in its wide character (UTF-16) representation.""" + return len(self.encoded) // self._bytesPerIndex + + @property + def strLength(self) -> int: + """Returns the length of the string in its pythonic string representation.""" + return len(self.decoded) + + def strToWideOffsets( + self, + strStart: int, + strEnd: int, + raiseOnError: bool =False + ) -> Tuple[int, int]: + """ + This method takes two offsets from the str representation + of the string the object is initialized with, and converts them to wide character string offsets. + @param strStart: The start offset in the str representation of the string. + @param strEnd: The end offset in the str representation of the string. + This offset is exclusive. + @param raiseOnError: Raises an IndexError when one of the given offsets + exceeds L{strLength} or is lower than zero. + If C{False}, the out of range offset will be bounded to the range of the string. + @raise ValueError: if strEnd < strStart + """ + # Optimisation, don't do anything special if offsets are collapsed at the start. + if 0 == strEnd == strStart: + return (0, 0) + if strEnd < strStart: + raise ValueError( + "strEnd=%d must be greater than or equal to strStart=%d" + % (strEnd, strStart) + ) + if strStart < 0 or strStart > self.strLength: + if raiseOnError: + raise IndexError("str start index out of range") + strStart = max(0, min(strStart, self.strLength)) + if strEnd < 0 or strEnd > self.strLength: + if raiseOnError: + raise IndexError("str end index out of range") + strEnd = max(0, min(strEnd, self.strLength)) + # If the original string contains surrogate characters, we want to preserve them + if strStart == 0: + wideStringStart: int = 0 + else: + precedingBytes: bytes = self.decoded[:strStart].encode(self._encoding, errors="surrogatepass") + wideStringStart= len(precedingBytes) // self._bytesPerIndex + if strStart == strEnd: + return (wideStringStart, wideStringStart) + encodedRange: bytes = self.decoded[strStart:strEnd].encode(self._encoding, errors="surrogatepass") + wideStringEnd: int = wideStringStart + (len(encodedRange) // self._bytesPerIndex) + return (wideStringStart, wideStringEnd) + + def wideToStrOffsets( + self, + wideStringStart: int, + wideStringEnd: int, + raiseOnError: bool = False + ) -> Tuple[int, int]: + r""" + This method takes two offsets from the wide character representation + of the string the object is initialized with, and converts them to str offsets. + wideStringEnd is considered an exclusive offset. + If either wideStringStart or wideStringEnd corresponds with an offset + in the middel of a surrogate pair, it is yet counted as one offset in the string. + For example, when L{decoded} is "😂", which is one offset in the str representation, + this method returns (0, 1) in all of the following cases: + * wideStringStart=0, wideStringEnd=1 + * wideStringStart=0, wideStringEnd=2 + * wideStringStart=1, wideStringEnd=2 + However, wideStringStart=1, wideStringEnd=1 results in (0, 0) + @param wideStringStart: The start offset in the wide character representation of the string. + @param wideStringEnd: The end offset in the wide character representation of the string. + This offset is exclusive. + @param raiseOnError: Raises an IndexError when one of the given offsets + exceeds L{wideStringLength} or is lower than zero. + If C{False}, the out of range offset will be bounded to the range of the string. + @raise ValueError: if wideStringEnd < wideStringStart + """ + # Optimisation, don't do anything special if offsets are collapsed at the start. + if 0 == wideStringEnd == wideStringStart: + return (0, 0) + if wideStringEnd < wideStringStart: + raise ValueError( + "wideStringEnd=%d must be greater than or equal to wideStringStart=%d" + % (wideStringEnd, wideStringStart) + ) + if wideStringStart < 0 or wideStringStart > self.wideStringLength: + if raiseOnError: + raise IndexError("Wide string start index out of range") + wideStringStart = max(0, min(wideStringStart, self.wideStringLength)) + if wideStringEnd < 0 or wideStringEnd > self.wideStringLength: + if raiseOnError: + raise IndexError("Wide string end index out of range") + wideStringEnd = max(0, min(wideStringEnd, self.wideStringLength)) + bytesStart: int = wideStringStart * self._bytesPerIndex + bytesEnd: int = wideStringEnd * self._bytesPerIndex + precedingStr= self.encoded[:bytesStart].decode(self._encoding, errors="surrogatepass") + strStart= len(precedingStr) + if bytesStart == bytesEnd and bytesEnd <= (len(self.encoded) - self._bytesPerIndex): + # Though we are trying to fetch str offsets for a single offset, + # we need to make sure to avoid off by one errors caused by surrogates + correctedBytesEnd = bytesEnd + self._bytesPerIndex + else: + correctedBytesEnd = bytesEnd + decodedRange: str = self.encoded[bytesStart:correctedBytesEnd].decode(self._encoding, errors="surrogatepass") + strEnd: int = strStart + len(decodedRange) + # In the case where precedingStr ends with a high surrogate, + # and decodedRange ends with a low surrogate character + # They take one offset in the resulting string, so our offsets are off by one. + if ( + precedingStr + and isHighSurrogate(precedingStr[-1]) + and decodedRange + and isLowSurrogate(decodedRange[0]) + ): + strStart -= 1 + strEnd -= 1 + if correctedBytesEnd > bytesEnd: + # Compensate for the case where we stretched our offsets earlier + strEnd -= (correctedBytesEnd - bytesEnd) // self._bytesPerIndex + return (strStart, strEnd) + +def getTextFromRawBytes( + buf: bytes, + numChars: int, + encoding: Optional[str] = None, + errorsFallback: str = "replace" +): + """ + Gets a string from a raw bytes object, decoded using the specified L{encoding}. + In most cases, the bytes object is fetched by passing the raw attribute of a ctypes.c_char-Array to this function. + If L{encoding} is C{None}, the bytes object is inspected on whether it contains single byte or multi byte characters. + As a first attempt, the bytes are encoded using the surrogatepass error handler. + This handler behaves like strict for all encodings without surrogates, + while making sure that surrogates are properly decoded when using UTF-16. + If that fails, the exception is logged and the bytes are decoded + according to the L{errorsFallback} error handler. + """ + if encoding is None: + # If the buffer we got contains any non null characters from numChars to the buffer's end, + # the buffer most likely contains multibyte characters. + # Note that in theory, it could also be a multibyte character string + # with nulls taking up the second half of the string. + # Unfortunately, there isn't a good way to detect those cases. + if numChars > 1 and any(buf[numChars:]): + encoding = WCHAR_ENCODING + else: + encoding = locale.getlocale()[1] + else: + encoding = encodings.normalize_encoding(encoding).lower() + if encoding.startswith("utf_16"): + numBytes = numChars * 2 + elif encoding.startswith("utf_32"): + numBytes = numChars * 4 + else: # All other encodings are single byte. + numBytes = numChars + rawText: bytes = buf[:numBytes] + if not any(rawText): + # rawText is empty or only contains null characters. + # If this is a range with only null characters in it, there's not much we can do about this. + return "" + try: + text = rawText.decode(encoding, errors="surrogatepass") + except UnicodeDecodeError: + log.debugWarning("Error decoding text in %r, probably wrong encoding assumed or incomplete data" % buf) + text = rawText.decode(encoding, errors=errorsFallback) + return text + +HIGH_SURROGATE_FIRST = u"\uD800" +HIGH_SURROGATE_LAST = u"\uDBFF" + +def isHighSurrogate(ch: str) -> bool: + """Returns if the given character is a high surrogate UTF-16 character.""" + return HIGH_SURROGATE_FIRST <= ch <= HIGH_SURROGATE_LAST + +LOW_SURROGATE_FIRST = u"\uDC00" +LOW_SURROGATE_LAST = u"\uDFFF" + +def isLowSurrogate(ch: str) -> bool: + """Returns if the given character is a low surrogate UTF-16 character.""" + return LOW_SURROGATE_FIRST <= ch <= LOW_SURROGATE_LAST diff --git a/source/touchHandler.py b/source/touchHandler.py index ecc5a962dfe..2928c81d3b3 100644 --- a/source/touchHandler.py +++ b/source/touchHandler.py @@ -290,9 +290,8 @@ def notifyInteraction(self, obj): @param obj: The NVDAObject with which the user is interacting. @type obj: L{NVDAObjects.NVDAObject} """ - l, t, w, h = obj.location oledll.oleacc.AccNotifyTouchInteraction(gui.mainFrame.Handle, obj.windowHandle, - POINT(l + (w / 2), t + (h / 2))) + obj.location.center.toPOINT()) handler=None diff --git a/source/touchTracker.py b/source/touchTracker.py index bd92d6268b5..c0428b214e6 100644 --- a/source/touchTracker.py +++ b/source/touchTracker.py @@ -200,14 +200,14 @@ def makePreheldTrackerFromSingleTouchTrackers(self,trackers): numFingers=len(childTrackers) if numFingers==0: return if numFingers==1: return childTrackers[0] - avgX=sum(t.x for t in childTrackers)/numFingers - avgY=sum(t.y for t in childTrackers)/numFingers + avgX: int = sum(t.x for t in childTrackers) // numFingers + avgY: int = sum(t.y for t in childTrackers) // numFingers tracker=MultiTouchTracker(action_hold,avgX,avgY,childTrackers[0].startTime,time.time(),numFingers) tracker.childTrackers=childTrackers return tracker def makePreheldTrackerForTracker(self,tracker): - curHoverSet={x for x in self.singleTouchTrackersByID.itervalues() if x.action==action_hover} + curHoverSet={x for x in self.singleTouchTrackersByID.values() if x.action==action_hover} excludeHoverSet={x for x in tracker.iterAllRawSingleTouchTrackers() if x.action==action_hover} return self.makePreheldTrackerFromSingleTouchTrackers(curHoverSet-excludeHoverSet) @@ -257,8 +257,8 @@ def makeMergedTrackerIfPossible(self,oldTracker,newTracker): childTrackers.extend(oldTracker.childTrackers) if oldTracker.numFingers>1 else childTrackers.append(oldTracker) childTrackers.extend(newTracker.childTrackers) if newTracker.numFingers>1 else childTrackers.append(newTracker) numFingers=oldTracker.numFingers+newTracker.numFingers - avgX=sum(t.x for t in childTrackers)/numFingers - avgY=sum(t.y for t in childTrackers)/numFingers + avgX: int =sum(t.x for t in childTrackers) // numFingers + avgY: int = sum(t.y for t in childTrackers) // numFingers mergedTracker=MultiTouchTracker(newTracker.action,avgX,avgY,oldTracker.startTime,newTracker.endTime,numFingers,newTracker.actionCount,pluralTimeout=newTracker.pluralTimeout) mergedTracker.childTrackers=childTrackers elif self.numUnknownTrackers==0 and newTracker.pluralTimeout is not None and newTracker.startTime>=oldTracker.endTime and newTracker.startTime=self.NOT_LINK_BLOCK_MIN_LEN + def _isSuitableNotLinkBlock(self, textRange): + return (textRange._endOffset - textRange._startOffset) >= self.NOT_LINK_BLOCK_MIN_LEN - def getEnclosingContainerRange(self,range): + def getEnclosingContainerRange(self, textRange): formatConfig=config.conf['documentFormatting'].copy() formatConfig.update({"reportBlockQuotes":True,"reportTables":True,"reportLists":True,"reportFrames":True}) controlFields=[] - for cmd in range.getTextWithFields(): + for cmd in textRange.getTextWithFields(): if not isinstance(cmd,textInfos.FieldCommand) or cmd.command!="controlStart": break controlFields.append(cmd.field) @@ -662,7 +667,7 @@ def getEnclosingContainerRange(self,range): if not containerField: return None docHandle=int(containerField['controlIdentifier_docHandle']) ID=int(containerField['controlIdentifier_ID']) - offsets=range._getOffsetsFromFieldIdentifier(docHandle,ID) + offsets = textRange._getOffsetsFromFieldIdentifier(docHandle,ID) return self.makeTextInfo(textInfos.offsets.Offsets(*offsets)) @classmethod @@ -682,7 +687,7 @@ def _handleUpdate(self): def getControlFieldForNVDAObject(self, obj): docHandle, objId = self.getIdentifierFromNVDAObject(obj) - objId = unicode(objId) + objId = str(objId) info = self.makeTextInfo(obj) info.collapse() info.expand(textInfos.UNIT_CHARACTER) diff --git a/source/virtualBuffers/adobeAcrobat.py b/source/virtualBuffers/adobeAcrobat.py index 7a82768a458..3fc0b25ac4a 100644 --- a/source/virtualBuffers/adobeAcrobat.py +++ b/source/virtualBuffers/adobeAcrobat.py @@ -56,7 +56,7 @@ def _normalizeControlField(self,attrs): accRole = accRole.lower() role=IAccessibleHandler.IAccessibleRolesToNVDARoles.get(accRole,controlTypes.ROLE_UNKNOWN) - states=set(IAccessibleHandler.IAccessibleStatesToNVDAStates[x] for x in [1< 0 + self.isWindowless = rootNVDAObject.event_objectID is not None and rootNVDAObject.event_objectID > 0 def __contains__(self,obj): if self.isWindowless: @@ -125,10 +125,8 @@ def _activateNVDAObject(self, obj): if not l: log.debugWarning("no location for field") return - x=(l[0]+l[2]/2) - y=l[1]+(l[3]/2) oldX,oldY=winUser.getCursorPos() - winUser.setCursorPos(x,y) + winUser.setCursorPos(*l.center) mouseHandler.executeMouseEvent(winUser.MOUSEEVENTF_LEFTDOWN,0,0) mouseHandler.executeMouseEvent(winUser.MOUSEEVENTF_LEFTUP,0,0) winUser.setCursorPos(oldX,oldY) diff --git a/source/virtualBuffers/gecko_ia2.py b/source/virtualBuffers/gecko_ia2.py index ddc8067cab8..d7fe3b3a1c9 100755 --- a/source/virtualBuffers/gecko_ia2.py +++ b/source/virtualBuffers/gecko_ia2.py @@ -60,8 +60,8 @@ def _normalizeControlField(self,attrs): role=IAccessibleHandler.IAccessibleRolesToNVDARoles.get(accRole,controlTypes.ROLE_UNKNOWN) if attrs.get('IAccessible2::attribute_tag',"").lower()=="blockquote": role=controlTypes.ROLE_BLOCKQUOTE - states=set(IAccessibleHandler.IAccessibleStatesToNVDAStates[x] for x in [1< +#Copyright (C) 2006-2019 NV Access Limited, Rui Batista, Aleksey Sadovoy, Peter Vagner, Mozilla Corporation, Babbage B.V., Joseph Lee #This file is covered by the GNU General Public License. #See the file COPYING for more details. +"""Functions that wrap Windows API functions from kernel32.dll and advapi32.dll""" + import contextlib import ctypes import ctypes.wintypes @@ -38,10 +40,10 @@ DATE_LONGDATE=0x00000002 TIME_NOSECONDS=0x00000002 # Wait return types -WAIT_ABANDONED = 0x00000080L -WAIT_IO_COMPLETION = 0x000000c0L -WAIT_OBJECT_0 = 0x00000000L -WAIT_TIMEOUT = 0x00000102L +WAIT_ABANDONED = 0x00000080 +WAIT_IO_COMPLETION = 0x000000c0 +WAIT_OBJECT_0 = 0x00000000 +WAIT_TIMEOUT = 0x00000102 WAIT_FAILED = 0xffffffff # Image file machine constants IMAGE_FILE_MACHINE_UNKNOWN = 0 @@ -83,7 +85,7 @@ def createWaitableTimer(securityAttributes=None, manualReset=False, name=None): If C{True}, the timer is a manual-reset notification timer. @type manualReset: bool @param name: Defaults to C{None}, the timer object is created without a name. - @type name: unicode + @type name: str """ res = kernel32.CreateWaitableTimerW(securityAttributes, manualReset, name) if res==0: @@ -383,3 +385,15 @@ def forget(self): Necessary if you pass this HGLOBAL to an API that takes ownership and therefore will handle freeing itself. """ self.value=None + +MOVEFILE_COPY_ALLOWED = 0x2 +MOVEFILE_CREATE_HARDLINK = 0x10 +MOVEFILE_DELAY_UNTIL_REBOOT = 0x4 +MOVEFILE_FAIL_IF_NOT_TRACKABLE = 0x20 +MOVEFILE_REPLACE_EXISTING = 0x1 +MOVEFILE_WRITE_THROUGH = 0x8 + +def moveFileEx(lpExistingFileName: str, lpNewFileName: str, dwFlags: int): + # If MoveFileExW fails, Windows will raise appropriate errors. + if not kernel32.MoveFileExW(lpExistingFileName, lpNewFileName, dwFlags): + raise ctypes.WinError() diff --git a/source/winUser.py b/source/winUser.py index 776e9b89e75..f83d3336504 100644 --- a/source/winUser.py +++ b/source/winUser.py @@ -10,6 +10,7 @@ from ctypes import * from ctypes.wintypes import * import winKernel +from textUtils import WCHAR_ENCODING #dll handles user32=windll.user32 @@ -525,10 +526,6 @@ def FindWindow(className, windowName): IDCANCEL=3 def MessageBox(hwnd, text, caption, type): - if isinstance(text, bytes): - text = text.decode('mbcs') - if isinstance(caption, bytes): - caption = caption.decode('mbcs') res = user32.MessageBoxW(hwnd, text, caption, type) if res == 0: raise WinError() @@ -656,13 +653,13 @@ def setClipboardData(format,data): # For now only unicode is a supported format if format!=CF_UNICODETEXT: raise ValueError("Unsupported format") - text=unicode(data) + text = data + bufLen = len(text.encode(WCHAR_ENCODING, errors="surrogatepass")) + 2 # Allocate global memory - h=winKernel.HGLOBAL.alloc(winKernel.GMEM_MOVEABLE,(len(text)+1)*2) + h=winKernel.HGLOBAL.alloc(winKernel.GMEM_MOVEABLE, bufLen) # Acquire a lock to the global memory receiving a local memory address with h.lock() as addr: # Write the text into the allocated memory - bufLen=len(text)+1 buf=(c_wchar*bufLen).from_address(addr) buf.value=text # Set the clipboard data with the global memory diff --git a/source/winVersion.py b/source/winVersion.py index 242403ee18d..153796c1c7c 100644 --- a/source/winVersion.py +++ b/source/winVersion.py @@ -30,7 +30,6 @@ def isUwpOcrAvailable(): def isWin10(version=1507, atLeast=True): """ Returns True if NVDA is running on the supplied release version of Windows 10. If no argument is supplied, returns True for all public Windows 10 releases. - @note: this function will always return False for source copies of NVDA due to a Python bug. @param version: a release version of Windows 10 (such as 1903). @param atLeast: return True if NVDA is running on at least this Windows 10 build (i.e. this version or higher). """ diff --git a/source/wincon.py b/source/wincon.py index cdd6d8904ff..c38b10f4266 100755 --- a/source/wincon.py +++ b/source/wincon.py @@ -1,5 +1,6 @@ from ctypes import * from ctypes.wintypes import * +import textUtils """ Lower level utility functions and constants for NVDA's @@ -55,11 +56,12 @@ def GetConsoleSelectionInfo(): return info def ReadConsoleOutputCharacter(handle,length,x,y): - buf=create_unicode_buffer(length) + # Use a string buffer, as from an unicode buffer, we can't get the raw data. + buf=create_string_buffer(length * 2) numCharsRead=c_int() if windll.kernel32.ReadConsoleOutputCharacterW(handle,buf,length,COORD(x,y),byref(numCharsRead))==0: raise WinError() - return buf.value + return textUtils.getTextFromRawBytes(buf.raw, numChars=numCharsRead.value, encoding=textUtils.WCHAR_ENCODING) def ReadConsoleOutput(handle, length, rect): BufType=CHAR_INFO*length diff --git a/source/windowUtils.py b/source/windowUtils.py index 672cb908804..406460c8586 100644 --- a/source/windowUtils.py +++ b/source/windowUtils.py @@ -23,7 +23,7 @@ def findDescendantWindow(parent, visible=None, controlID=None, className=None): @param controlID: The control ID of the window or C{None} if irrelevant. @type controlID: int @param className: The class name of the window or C{None} if irrelevant. - @type className: basestring + @type className: str @return: The handle of the matching descendant window. @rtype: int @raise LookupError: if no matching window is found. @@ -138,7 +138,7 @@ class CustomWindow(object): """ #: The class name of this window. - #: @type: unicode + #: @type: str className = None _hwndsToInstances = weakref.WeakValueDictionary() @@ -147,9 +147,9 @@ def __init__(self, windowName=None): """Constructor. @raise WindowsError: If an error occurs. """ - if not isinstance(self.className, unicode): + if not isinstance(self.className, str): raise ValueError("className attribute must be a unicode string") - if windowName and not isinstance(windowName, unicode): + if windowName and not isinstance(windowName, str): raise ValueError("windowName must be a unicode string") self._wClass = WNDCLASSEXW( cbSize=ctypes.sizeof(WNDCLASSEXW), diff --git a/tests/checkPot.py b/tests/checkPot.py index 8b9a6a97c15..a84dd41a1d2 100644 --- a/tests/checkPot.py +++ b/tests/checkPot.py @@ -2,7 +2,7 @@ #A part of NonVisual Desktop Access (NVDA) #This file is covered by the GNU General Public License. #See the file COPYING for more details. -#Copyright (C) 2017 NV Access Limited +#Copyright (C) 2017-2019 NV Access Limited """Check a translation template (pot) for strings without translator comments. """ @@ -113,7 +113,7 @@ def checkPot(fileName): errors = 0 expectedErrors = 0 unexpectedSuccesses = 0 - with file(fileName, "rt") as pot: + with open(fileName, "rt") as pot: for line in pot: line = line.rstrip() if not line: diff --git a/tests/system/libraries/nvdaRobotLib.py b/tests/system/libraries/nvdaRobotLib.py index 60cf322cfc5..efd50c51ebb 100644 --- a/tests/system/libraries/nvdaRobotLib.py +++ b/tests/system/libraries/nvdaRobotLib.py @@ -63,8 +63,7 @@ def _findDepPath(depFileName, searchPaths): # relative to the python path requiredPythonImportsForSystemTestSpyPackage = [ r"robotremoteserver", - r"SimpleXMLRPCServer", - r"xmlrpclib", + r"xmlrpc", ] def _createNvdaSpyPackage(): diff --git a/tests/system/libraries/systemTestSpy.py b/tests/system/libraries/systemTestSpy.py index 37af4dfe803..f2bc3c31565 100644 --- a/tests/system/libraries/systemTestSpy.py +++ b/tests/system/libraries/systemTestSpy.py @@ -9,7 +9,7 @@ """ import globalPluginHandler import threading -from systemTestUtils import _blockUntilConditionMet +from .systemTestUtils import _blockUntilConditionMet from logHandler import log from time import clock as _timer @@ -64,7 +64,7 @@ def _flattenCommandsSeparatingWithNewline(self, commandArray): def _getJoinedBaseStringsFromCommands(self, speechCommandArray): wsChars = whitespaceMinusSlashN - baseStrings = [c.strip(wsChars) for c in speechCommandArray if isinstance(c, basestring)] + baseStrings = [c.strip(wsChars) for c in speechCommandArray if isinstance(c, str)] return ''.join(baseStrings).strip() # Public methods @@ -95,7 +95,7 @@ def getIndexOfSpeech(self, speech, startFromIndex=0): with threading.Lock(): for index, commands in enumerate(self._nvdaSpeech[startFromIndex:]): index = index + startFromIndex - baseStrings = [c.strip() for c in commands if isinstance(c, basestring)] + baseStrings = [c.strip() for c in commands if isinstance(c, str)] if any(speech in x for x in baseStrings): return index return -1 diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py index 20437f8a3c6..465e3870c90 100644 --- a/tests/unit/__init__.py +++ b/tests/unit/__init__.py @@ -2,7 +2,7 @@ #A part of NonVisual Desktop Access (NVDA) #This file is covered by the GNU General Public License. #See the file COPYING for more details. -#Copyright (C) 2017 NV Access Limited +#Copyright (C) 2017-2019 NV Access Limited """NVDA unit testing. All unit tests should reside within this package and should be @@ -21,7 +21,7 @@ import gettext #Localization settings locale.setlocale(locale.LC_ALL,'') -gettext.install('nvda',unicode=True) +gettext.install('nvda') # The path to the unit tests. UNIT_DIR = os.path.dirname(os.path.abspath(__file__)) @@ -40,7 +40,7 @@ class AppArgs: # Ideally, this would be an in-memory, default configuration. # However, config currently requires a path. # We use the unit test directory, since we want a clean config. - configPath = UNIT_DIR.decode("mbcs") + configPath = UNIT_DIR secure = False disableAddons = True launcher = False @@ -80,7 +80,7 @@ class AppArgs: braille.handler.displaySize=40 braille.handler.enabled = True # The focus and navigator objects need to be initialized to something. -from objectProvider import PlaceholderNVDAObject,NVDAObjectWithRole +from .objectProvider import PlaceholderNVDAObject,NVDAObjectWithRole phObj = PlaceholderNVDAObject() import api api.setFocusObject(phObj) diff --git a/tests/unit/test_baseObject.py b/tests/unit/test_baseObject.py index e9ab15906fe..a1729e4543d 100644 --- a/tests/unit/test_baseObject.py +++ b/tests/unit/test_baseObject.py @@ -2,13 +2,13 @@ #A part of NonVisual Desktop Access (NVDA) #This file is covered by the GNU General Public License. #See the file COPYING for more details. -#Copyright (C) 2018 NV Access Limited, Babbage B.V. +#Copyright (C) 2018-2019 NV Access Limited, Babbage B.V. """Unit tests for the baseObject module, its classes and their derivatives.""" import unittest from baseObject import AutoPropertyObject, ScriptableObject -from objectProvider import PlaceholderNVDAObject +from .objectProvider import PlaceholderNVDAObject from scriptHandler import script from abc import abstractmethod @@ -137,14 +137,14 @@ class TestAbstractAutoPropertyObjects(unittest.TestCase): """ def test_abstractProperty(self): - self.assertRaisesRegexp(TypeError, + self.assertRaisesRegex(TypeError, "^Can't instantiate abstract class AutoPropertyObjectWithAbstractProperty " "with abstract methods x", AutoPropertyObjectWithAbstractProperty ) def test_subclassedAbstractProperty(self): - self.assertRaisesRegexp(TypeError, + self.assertRaisesRegex(TypeError, "^Can't instantiate abstract class SubclassedAutoPropertyObjectWithAbstractProperty " "with abstract methods x", SubclassedAutoPropertyObjectWithAbstractProperty diff --git a/tests/unit/test_braille.py b/tests/unit/test_braille.py index 753310eecee..cdb3c13a5a6 100644 --- a/tests/unit/test_braille.py +++ b/tests/unit/test_braille.py @@ -2,14 +2,14 @@ #A part of NonVisual Desktop Access (NVDA) #This file is covered by the GNU General Public License. #See the file COPYING for more details. -#Copyright (C) 2017 NV Access Limited, Babbage B.V. +#Copyright (C) 2017-2019 NV Access Limited, Babbage B.V. """Unit tests for the braille module. """ import unittest import braille -from objectProvider import PlaceholderNVDAObject, NVDAObjectWithRole +from .objectProvider import PlaceholderNVDAObject, NVDAObjectWithRole import controlTypes from config import conf import api diff --git a/tests/unit/test_brailleTables.py b/tests/unit/test_brailleTables.py index 5abd1f3f89f..d3644903ad3 100644 --- a/tests/unit/test_brailleTables.py +++ b/tests/unit/test_brailleTables.py @@ -2,7 +2,7 @@ #A part of NonVisual Desktop Access (NVDA) #This file is covered by the GNU General Public License. #See the file COPYING for more details. -#Copyright (C) 2018 NV Access Limited, Babbage B.V. +#Copyright (C) 2018-2019 NV Access Limited, Babbage B.V. """Unit tests for the brailleTables module. """ @@ -26,5 +26,5 @@ def test_tableExistence(self): def test_renamedTableExistence(self): """Tests whether all defined renamed tables are part of the actual list of tables.""" tableNames = [table.fileName for table in brailleTables.listTables()] - for name in brailleTables.RENAMED_TABLES.itervalues(): + for name in brailleTables.RENAMED_TABLES.values(): self.assertIn(name, tableNames) diff --git a/tests/unit/test_controlTypes.py b/tests/unit/test_controlTypes.py index 23d0842a845..e48631a3442 100644 --- a/tests/unit/test_controlTypes.py +++ b/tests/unit/test_controlTypes.py @@ -2,7 +2,7 @@ #A part of NonVisual Desktop Access (NVDA) #This file is covered by the GNU General Public License. #See the file COPYING for more details. -#Copyright (C) 2017 NV Access Limited, Babbage B.V. +#Copyright (C) 2017-2019 NV Access Limited, Babbage B.V. """Unit tests for the controlTypes module. """ @@ -15,13 +15,13 @@ class TestLabels(unittest.TestCase): def test_roleLabels(self): """Test to check whether every role has its own label in controlTypes.roleLabels""" - for name, const in controlTypes.__dict__.iteritems(): + for name, const in vars(controlTypes).items(): if name.startswith("ROLE_"): self.assertIsNotNone(controlTypes.roleLabels.get(const),msg="{name} has no label".format(name=name)) def test_positiveStateLabels(self): """Test to check whether every state has its own label in controlTypes.stateLabels""" - for name, const in controlTypes.__dict__.iteritems(): + for name, const in vars(controlTypes).items(): if name.startswith("STATE_"): self.assertIsNotNone(controlTypes.stateLabels.get(const),msg="{name} has no label".format(name=name)) diff --git a/tests/unit/test_extensionPoints.py b/tests/unit/test_extensionPoints.py index 5bac3917550..9bed87b295a 100644 --- a/tests/unit/test_extensionPoints.py +++ b/tests/unit/test_extensionPoints.py @@ -2,13 +2,14 @@ #A part of NonVisual Desktop Access (NVDA) #This file is covered by the GNU General Public License. #See the file COPYING for more details. -#Copyright (C) 2017 NV Access Limited +#Copyright (C) 2017-2019 NV Access Limited, Leonard de Ruijter """Unit tests for the extensionPoints module. """ import unittest import extensionPoints +from functools import partial class ExampleClass(object): def method(self): @@ -142,6 +143,22 @@ def handlerMethod(self, a): extensionPoints.callWithSupportedKwargs(h.handlerMethod, 'a value') self.assertEqual(calledKwargs, {'a': 'a value'}) + def test_instanceMethodHandlerTakesParams_givenRequiredKwarg(self): + """Test to ensure that a instance method handler gets the correct arguments, including implicit "self" + Handler takes a required keyword argument. + callWithSupportedKwargs given a keyword arg with a matching name. + Handler should get required kwarg. + """ + calledKwargs = {} + + class handlerClass(): + def handlerMethod(self, *, a): + calledKwargs['a'] = a + + h = handlerClass() + extensionPoints.callWithSupportedKwargs(h.handlerMethod, a='a value') + self.assertEqual(calledKwargs, {'a': 'a value'}) + def test_instanceMethodHandlerTakesParams_givenMatchingNameKwarg(self): """Test to ensure that a instance method handler gets the correct arguments, including implicit "self" Handler takes a parameter. @@ -242,7 +259,6 @@ def handler(a): with self.assertRaises(TypeError): extensionPoints.callWithSupportedKwargs(handler, b='b value') - def test_handlerTakesTwoParamsWithoutDefaults_NotEnoughPositionalsGiven_exceptionRaised(self): """ Tests that handlers that when a handler expects params which are not provided, then the function is not called. The handler function takes a param with no default value set. @@ -448,6 +464,22 @@ def test_lambdaHandler(self): self.action.notify(a='a value') self.assertEqual(calledKwargs, {'a': 'a value'}) + def test_partialHandler(self): + """ Test that a L{functools.partial} can be used as a handler. + Note: the partial must be kept alive, since register uses a weak reference to it. + """ + + calledKwargs = {} + + def handler(a, b): + calledKwargs['a'] = a + calledKwargs['b'] = b + + p = partial(handler, a=1) + self.action.register(p) + self.action.notify(b='a value') + self.assertEqual(calledKwargs, {'a': 1, 'b': 'a value'}) + def test_handlerException(self): """Test that a handler which raises an exception doesn't affect later handlers. """ @@ -494,6 +526,17 @@ def handler(a=0): self.action.notify(a=1) self.assertEqual(calledKwargs, {"a": 1}) + def test_handlerParamsWithRequiredKwarg(self): + """ Test that a handler that accepts required keyword arguments receives arguments + """ + calledKwargs = {} + def handler(*, a): + calledKwargs["a"] = a + + self.action.register(handler) + self.action.notify(a=1) + self.assertEqual(calledKwargs, {"a": 1}) + class TestFilter(unittest.TestCase): def setUp(self): @@ -600,6 +643,19 @@ def handler(value, a=0): self.filter.apply("some value", a=1) self.assertEqual(calledKwargs, {"value": "some value", "a": 1}) + def test_handlerParamsWithRequiredKwarg(self): + """ Test that a handler that accepts required keyword arguments receives arguments + """ + calledKwargs = {} + + def handler(value, *, a): + calledKwargs['value'] = value + calledKwargs["a"] = a + + self.filter.register(handler) + self.filter.apply("some value", a=1) + self.assertEqual(calledKwargs, {"value": "some value", "a": 1}) + class TestDecider(unittest.TestCase): def setUp(self): @@ -712,4 +768,16 @@ def handler(a=0): self.decider.register(handler) self.decider.decide(a=1) - self.assertEqual(calledKwargs, {"a": 1}) \ No newline at end of file + self.assertEqual(calledKwargs, {"a": 1}) + + def test_handlerParamsWithRequiredKwarg(self): + """ Test that a handler that accepts required keyword arguments receives arguments + """ + calledKwargs = {} + + def handler(*, a): + calledKwargs["a"] = a + + self.decider.register(handler) + self.decider.decide(a=1) + self.assertEqual(calledKwargs, {"a": 1}) diff --git a/tests/unit/test_scriptHandler.py b/tests/unit/test_scriptHandler.py index 72ddbb31c8c..35ffa861823 100644 --- a/tests/unit/test_scriptHandler.py +++ b/tests/unit/test_scriptHandler.py @@ -2,7 +2,7 @@ #A part of NonVisual Desktop Access (NVDA) #This file is covered by the GNU General Public License. #See the file COPYING for more details. -#Copyright (C) 2018 NV Access Limited, Babbage B.V. +#Copyright (C) 2018-2019 NV Access Limited, Babbage B.V. """Unit tests for the scriptHandler module.""" @@ -29,7 +29,7 @@ def script_test(self, gesture): self.assertEqual(script_test.__doc__, "description") self.assertEqual(script_test.category, SCRCAT_MISC) - self.assertItemsEqual(script_test.gestures, ["kb:a", "kb:b", "kb:c"]) + self.assertCountEqual(script_test.gestures, ["kb:a", "kb:b", "kb:c"]) self.assertTrue(script_test.canPropagate) self.assertTrue(script_test.bypassInputHelp) self.assertEqual(script_test.resumeSayAllMode, CURSOR_CARET) diff --git a/tests/unit/test_textInfos.py b/tests/unit/test_textInfos.py index c08122ea9ee..b9615f5f528 100644 --- a/tests/unit/test_textInfos.py +++ b/tests/unit/test_textInfos.py @@ -16,6 +16,8 @@ class TestCharacterOffsets(unittest.TestCase): """ Tests for textInfos.offsets.OffsetsTextInfo for its ability to deal with UTF-16 surrogate characters (i.e. whether a surrogate pair is treated as one character). + These tests are also implicit tests for the textUtils module, + as its logic is used for character offset calculation in wide character strings. """ def test_nonSurrogateForward(self): @@ -43,7 +45,7 @@ def test_nonSurrogateBackward(self): self.assertEqual(ti.offsets, (0, 1)) # One offset def test_surrogatePairsForward(self): - obj = BasicTextProvider(text=u"\ud83e\udd26\ud83d\ude0a\ud83d\udc4d") # 🤦😊👍 + obj = BasicTextProvider(text=u"\U0001f926\U0001f60a\U0001f44d") # 🤦😊👍 ti = obj.makeTextInfo(Offsets(0, 0)) ti.expand(textInfos.UNIT_CHARACTER) # Range at 🤦 self.assertEqual(ti.offsets, (0, 2)) # Two offsets @@ -55,7 +57,7 @@ def test_surrogatePairsForward(self): self.assertEqual(ti.offsets, (4, 6)) # Two offsets def test_surrogatePairsBackward(self): - obj = BasicTextProvider(text=u"\ud83e\udd26\ud83d\ude0a\ud83d\udc4d") # 🤦😊👍 + obj = BasicTextProvider(text=u"\U0001f926\U0001f60a\U0001f44d") # 🤦😊👍 ti = obj.makeTextInfo(Offsets(5, 5)) ti.expand(textInfos.UNIT_CHARACTER) # Range at 👍 self.assertEqual(ti.offsets, (4, 6)) # Two offsets @@ -67,7 +69,7 @@ def test_surrogatePairsBackward(self): self.assertEqual(ti.offsets, (0, 2)) # Two offsets def test_mixedSurrogatePairsAndNonSurrogatesForward(self): - obj = BasicTextProvider(text=u"a\ud83e\udd26b") # a🤦b + obj = BasicTextProvider(text=u"a\U0001f926b") # a🤦b ti = obj.makeTextInfo(Offsets(0, 0)) ti.expand(textInfos.UNIT_CHARACTER) # Range at a self.assertEqual(ti.offsets, (0, 1)) # One offset @@ -79,7 +81,7 @@ def test_mixedSurrogatePairsAndNonSurrogatesForward(self): self.assertEqual(ti.offsets, (3, 4)) # One offset def test_mixedSurrogatePairsAndNonSurrogatesBackward(self): - obj = BasicTextProvider(text=u"a\ud83e\udd26b") # a🤦b + obj = BasicTextProvider(text=u"a\U0001f926b") # a🤦b ti = obj.makeTextInfo(Offsets(3, 3)) ti.expand(textInfos.UNIT_CHARACTER) # Range at c self.assertEqual(ti.offsets, (3, 4)) # One offset @@ -95,7 +97,7 @@ def test_mixedSurrogatePairsNonSurrogatesAndSingleSurrogatesForward(self): Tests surrogate pairs, non surrogates as well as single surrogate characters (i.e. incomplete pairs) """ - obj = BasicTextProvider(text=u"a\ud83e\ud83e\udd26\udd26b") + obj = BasicTextProvider(text=u"a\ud83e\U0001f926\udd26b") ti = obj.makeTextInfo(Offsets(0, 0)) ti.expand(textInfos.UNIT_CHARACTER) # Range at a self.assertEqual(ti.offsets, (0, 1)) # One offset @@ -113,7 +115,7 @@ def test_mixedSurrogatePairsNonSurrogatesAndSingleSurrogatesForward(self): self.assertEqual(ti.offsets, (5, 6)) # One offset def test_mixedSurrogatePairsNonSurrogatesAndSingleSurrogatesBackward(self): - obj = BasicTextProvider(text=u"a\ud83e\ud83e\udd26\udd26b") + obj = BasicTextProvider(text=u"a\ud83e\U0001f926\udd26b") ti = obj.makeTextInfo(Offsets(5, 5)) ti.expand(textInfos.UNIT_CHARACTER) # Range at c self.assertEqual(ti.offsets, (5, 6)) # One offset diff --git a/tests/unit/test_textUtils.py b/tests/unit/test_textUtils.py new file mode 100644 index 00000000000..f916e38cd31 --- /dev/null +++ b/tests/unit/test_textUtils.py @@ -0,0 +1,231 @@ +# -*- coding: UTF-8 -*- +#tests/unit/test_textUtils.py +#A part of NonVisual Desktop Access (NVDA) +#This file is covered by the GNU General Public License. +#See the file COPYING for more details. +#Copyright (C) 2019 NV Access Limited, Babbage B.V., Leonard de Ruijter + +"""Unit tests for the textUtils module.""" + +import unittest +from textUtils import WideStringOffsetConverter + +FACE_PALM = u"\U0001f926" # 🤦 +SMILE = u"\U0001f60a" # 😊 +THUMBS_UP = u"\U0001f44d" # 👍 + +class TestStrToWideOffsets(unittest.TestCase): + """ + Tests that ensure that offsets in a string are properly converted to wide string offsets. + Every string offset for 32-bit unicode characters (e.g. emoji) take two offsets in a wide string representation. + """ + + def test_nonSurrogate(self): + converter = WideStringOffsetConverter(text="abc") + self.assertEqual(converter.wideStringLength, 3) + self.assertEqual(converter.strToWideOffsets(0, 0), (0, 0)) + self.assertEqual(converter.strToWideOffsets(0, 1), (0, 1)) + self.assertEqual(converter.strToWideOffsets(0, 2), (0, 2)) + self.assertEqual(converter.strToWideOffsets(0, 3), (0, 3)) + self.assertEqual(converter.strToWideOffsets(1, 1), (1, 1)) + self.assertEqual(converter.strToWideOffsets(1, 2), (1, 2)) + self.assertEqual(converter.strToWideOffsets(1, 3), (1, 3)) + self.assertEqual(converter.strToWideOffsets(2, 2), (2, 2)) + self.assertEqual(converter.strToWideOffsets(2, 3), (2, 3)) + self.assertEqual(converter.strToWideOffsets(3, 3), (3, 3)) + + def test_surrogatePairs(self): + converter = WideStringOffsetConverter(text=FACE_PALM + SMILE + THUMBS_UP) + self.assertEqual(converter.wideStringLength, 6) + self.assertEqual(converter.strToWideOffsets(0, 0), (0, 0)) + self.assertEqual(converter.strToWideOffsets(0, 1), (0, 2)) + self.assertEqual(converter.strToWideOffsets(0, 2), (0, 4)) + self.assertEqual(converter.strToWideOffsets(0, 3), (0, 6)) + self.assertEqual(converter.strToWideOffsets(1, 1), (2, 2)) + self.assertEqual(converter.strToWideOffsets(1, 2), (2, 4)) + self.assertEqual(converter.strToWideOffsets(1, 3), (2, 6)) + self.assertEqual(converter.strToWideOffsets(2, 2), (4, 4)) + self.assertEqual(converter.strToWideOffsets(2, 3), (4, 6)) + self.assertEqual(converter.strToWideOffsets(3, 3), (6, 6)) + + def test_mixedSurrogatePairsAndNonSurrogates(self): + converter = WideStringOffsetConverter(text=u"a" + FACE_PALM + u"b") # a🤦b + self.assertEqual(converter.wideStringLength, 4) + self.assertEqual(converter.strToWideOffsets(0, 0), (0, 0)) + self.assertEqual(converter.strToWideOffsets(0, 1), (0, 1)) + self.assertEqual(converter.strToWideOffsets(0, 2), (0, 3)) + self.assertEqual(converter.strToWideOffsets(0, 3), (0, 4)) + self.assertEqual(converter.strToWideOffsets(1, 1), (1, 1)) + self.assertEqual(converter.strToWideOffsets(1, 2), (1, 3)) + self.assertEqual(converter.strToWideOffsets(1, 3), (1, 4)) + self.assertEqual(converter.strToWideOffsets(2, 2), (3, 3)) + self.assertEqual(converter.strToWideOffsets(2, 3), (3, 4)) + self.assertEqual(converter.strToWideOffsets(3, 3), (4, 4)) + + def test_mixedSurrogatePairsNonSurrogatesAndSingleSurrogates(self): + """ + Tests surrogate pairs, non surrogates as well as + single surrogate characters (i.e. incomplete pairs) + """ + converter = WideStringOffsetConverter(text=u"a" + u"\ud83e" + FACE_PALM + u"\udd26" + u"b") + self.assertEqual(converter.wideStringLength, 6) + self.assertEqual(converter.strToWideOffsets(0, 0), (0, 0)) + self.assertEqual(converter.strToWideOffsets(0, 1), (0, 1)) + self.assertEqual(converter.strToWideOffsets(0, 2), (0, 2)) + self.assertEqual(converter.strToWideOffsets(0, 3), (0, 4)) + self.assertEqual(converter.strToWideOffsets(0, 4), (0, 5)) + self.assertEqual(converter.strToWideOffsets(0, 5), (0, 6)) + self.assertEqual(converter.strToWideOffsets(1, 1), (1, 1)) + self.assertEqual(converter.strToWideOffsets(1, 2), (1, 2)) + self.assertEqual(converter.strToWideOffsets(1, 3), (1, 4)) + self.assertEqual(converter.strToWideOffsets(1, 4), (1, 5)) + self.assertEqual(converter.strToWideOffsets(1, 5), (1, 6)) + self.assertEqual(converter.strToWideOffsets(2, 2), (2, 2)) + self.assertEqual(converter.strToWideOffsets(2, 3), (2, 4)) + self.assertEqual(converter.strToWideOffsets(2, 4), (2, 5)) + self.assertEqual(converter.strToWideOffsets(2, 5), (2, 6)) + self.assertEqual(converter.strToWideOffsets(3, 3), (4, 4)) + self.assertEqual(converter.strToWideOffsets(3, 4), (4, 5)) + self.assertEqual(converter.strToWideOffsets(3, 5), (4, 6)) + self.assertEqual(converter.strToWideOffsets(4, 4), (5, 5)) + self.assertEqual(converter.strToWideOffsets(4, 5), (5, 6)) + self.assertEqual(converter.strToWideOffsets(5, 5), (6, 6)) + +class TestWideToStrOffsets(unittest.TestCase): + """ + Tests that ensure that offsets in a wide string are properly converted to str offsets. + Every string offset for 32-bit unicode characters (e.g. emoji) take two offsets in a wide string representation. + """ + + def test_nonSurrogate(self): + converter = WideStringOffsetConverter(text="abc") + self.assertEqual(converter.strLength, 3) + self.assertEqual(converter.wideToStrOffsets(0, 0), (0, 0)) + self.assertEqual(converter.wideToStrOffsets(0, 1), (0, 1)) + self.assertEqual(converter.wideToStrOffsets(0, 2), (0, 2)) + self.assertEqual(converter.wideToStrOffsets(0, 3), (0, 3)) + self.assertEqual(converter.wideToStrOffsets(1, 1), (1, 1)) + self.assertEqual(converter.wideToStrOffsets(1, 2), (1, 2)) + self.assertEqual(converter.wideToStrOffsets(1, 3), (1, 3)) + self.assertEqual(converter.wideToStrOffsets(2, 2), (2, 2)) + self.assertEqual(converter.wideToStrOffsets(2, 3), (2, 3)) + self.assertEqual(converter.wideToStrOffsets(3, 3), (3, 3)) + + def test_surrogatePairs(self): + converter = WideStringOffsetConverter(text=FACE_PALM + SMILE + THUMBS_UP) + self.assertEqual(converter.strLength, 3) + self.assertEqual(converter.wideToStrOffsets(0, 0), (0, 0)) + self.assertEqual(converter.wideToStrOffsets(0, 1), (0, 1)) + self.assertEqual(converter.wideToStrOffsets(0, 2), (0, 1)) + self.assertEqual(converter.wideToStrOffsets(0, 3), (0, 2)) + self.assertEqual(converter.wideToStrOffsets(0, 4), (0, 2)) + self.assertEqual(converter.wideToStrOffsets(0, 5), (0, 3)) + self.assertEqual(converter.wideToStrOffsets(0, 6), (0, 3)) + self.assertEqual(converter.wideToStrOffsets(1, 1), (0, 0)) + self.assertEqual(converter.wideToStrOffsets(1, 2), (0, 1)) + self.assertEqual(converter.wideToStrOffsets(1, 3), (0, 2)) + self.assertEqual(converter.wideToStrOffsets(1, 4), (0, 2)) + self.assertEqual(converter.wideToStrOffsets(1, 5), (0, 3)) + self.assertEqual(converter.wideToStrOffsets(1, 6), (0, 3)) + self.assertEqual(converter.wideToStrOffsets(2, 2), (1, 1)) + self.assertEqual(converter.wideToStrOffsets(2, 3), (1, 2)) + self.assertEqual(converter.wideToStrOffsets(2, 4), (1, 2)) + self.assertEqual(converter.wideToStrOffsets(2, 5), (1, 3)) + self.assertEqual(converter.wideToStrOffsets(2, 6), (1, 3)) + self.assertEqual(converter.wideToStrOffsets(3, 3), (1, 1)) + self.assertEqual(converter.wideToStrOffsets(3, 4), (1, 2)) + self.assertEqual(converter.wideToStrOffsets(3, 5), (1, 3)) + self.assertEqual(converter.wideToStrOffsets(3, 6), (1, 3)) + self.assertEqual(converter.wideToStrOffsets(4, 4), (2, 2)) + self.assertEqual(converter.wideToStrOffsets(4, 5), (2, 3)) + self.assertEqual(converter.wideToStrOffsets(4, 6), (2, 3)) + self.assertEqual(converter.wideToStrOffsets(5, 5), (2, 2)) + self.assertEqual(converter.wideToStrOffsets(5, 6), (2, 3)) + self.assertEqual(converter.wideToStrOffsets(6, 6), (3, 3)) + + def test_mixedSurrogatePairsAndNonSurrogates(self): + converter = WideStringOffsetConverter(text=u"a" + FACE_PALM + u"b") # a🤦b + self.assertEqual(converter.strLength, 3) + self.assertEqual(converter.wideToStrOffsets(0, 0), (0, 0)) + self.assertEqual(converter.wideToStrOffsets(0, 1), (0, 1)) + self.assertEqual(converter.wideToStrOffsets(0, 2), (0, 2)) + self.assertEqual(converter.wideToStrOffsets(0, 3), (0, 2)) + self.assertEqual(converter.wideToStrOffsets(0, 4), (0, 3)) + self.assertEqual(converter.wideToStrOffsets(1, 1), (1, 1)) + self.assertEqual(converter.wideToStrOffsets(1, 2), (1, 2)) + self.assertEqual(converter.wideToStrOffsets(1, 3), (1, 2)) + self.assertEqual(converter.wideToStrOffsets(1, 4), (1, 3)) + self.assertEqual(converter.wideToStrOffsets(2, 2), (1, 1)) + self.assertEqual(converter.wideToStrOffsets(2, 3), (1, 2)) + self.assertEqual(converter.wideToStrOffsets(2, 4), (1, 3)) + self.assertEqual(converter.wideToStrOffsets(3, 3), (2, 2)) + self.assertEqual(converter.wideToStrOffsets(3, 4), (2, 3)) + self.assertEqual(converter.wideToStrOffsets(4, 4), (3, 3)) + + def test_mixedSurrogatePairsNonSurrogatesAndSingleSurrogates(self): + """ + Tests surrogate pairs, non surrogates as well as + single surrogate characters (i.e. incomplete pairs) + """ + converter = WideStringOffsetConverter(text=u"a" + u"\ud83e" + FACE_PALM + u"\udd26" + u"b") + self.assertEqual(converter.strLength, 5) + self.assertEqual(converter.wideToStrOffsets(0, 0), (0, 0)) + self.assertEqual(converter.wideToStrOffsets(0, 1), (0, 1)) + self.assertEqual(converter.wideToStrOffsets(0, 2), (0, 2)) + self.assertEqual(converter.wideToStrOffsets(0, 3), (0, 3)) + self.assertEqual(converter.wideToStrOffsets(0, 4), (0, 3)) + self.assertEqual(converter.wideToStrOffsets(0, 5), (0, 4)) + self.assertEqual(converter.wideToStrOffsets(0, 6), (0, 5)) + self.assertEqual(converter.wideToStrOffsets(1, 1), (1, 1)) + self.assertEqual(converter.wideToStrOffsets(1, 2), (1, 2)) + self.assertEqual(converter.wideToStrOffsets(1, 3), (1, 3)) + self.assertEqual(converter.wideToStrOffsets(1, 4), (1, 3)) + self.assertEqual(converter.wideToStrOffsets(1, 5), (1, 4)) + self.assertEqual(converter.wideToStrOffsets(1, 6), (1, 5)) + self.assertEqual(converter.wideToStrOffsets(2, 2), (2, 2)) + self.assertEqual(converter.wideToStrOffsets(2, 3), (2, 3)) + self.assertEqual(converter.wideToStrOffsets(2, 4), (2, 3)) + self.assertEqual(converter.wideToStrOffsets(2, 5), (2, 4)) + self.assertEqual(converter.wideToStrOffsets(2, 6), (2, 5)) + self.assertEqual(converter.wideToStrOffsets(3, 3), (2, 2)) + self.assertEqual(converter.wideToStrOffsets(3, 4), (2, 3)) + self.assertEqual(converter.wideToStrOffsets(3, 5), (2, 4)) + self.assertEqual(converter.wideToStrOffsets(3, 6), (2, 5)) + self.assertEqual(converter.wideToStrOffsets(4, 4), (3, 3)) + self.assertEqual(converter.wideToStrOffsets(4, 5), (3, 4)) + self.assertEqual(converter.wideToStrOffsets(4, 6), (3, 5)) + self.assertEqual(converter.wideToStrOffsets(5, 5), (4, 4)) + self.assertEqual(converter.wideToStrOffsets(5, 6), (4, 5)) + self.assertEqual(converter.wideToStrOffsets(6, 6), (5, 5)) + +class TestEdgeCases(unittest.TestCase): + """ + Tests for edge cases, such as offsets out of range of a string, + or end offsets less than start offsets. + """ + + def test_wideToStrOffsets(self): + converter = WideStringOffsetConverter(text="abc") + self.assertEqual(converter.strLength, 3) + self.assertEqual( + converter.wideToStrOffsets(-1, 0, raiseOnError=False), + (0, 0)) + self.assertEqual( + converter.wideToStrOffsets(0, 4, raiseOnError=False), + (0, 3)) + self.assertRaises(IndexError, converter.wideToStrOffsets, -1, 0, raiseOnError=True) + self.assertRaises(IndexError, converter.wideToStrOffsets, 0, 4, raiseOnError=True) + self.assertRaises(ValueError, converter.wideToStrOffsets, 1, 0) + + def test_strToWideOffsets(self): + converter = WideStringOffsetConverter(text="abc") + self.assertEqual(converter.wideStringLength, 3) + self.assertEqual( + converter.strToWideOffsets(-1, 0, raiseOnError=False), + (0, 0)) + self.assertEqual( + converter.strToWideOffsets(0, 4, raiseOnError=False), + (0, 3)) + self.assertRaises(IndexError, converter.strToWideOffsets, -1, 0, raiseOnError=True) + self.assertRaises(IndexError, converter.strToWideOffsets, 0, 4, raiseOnError=True) + self.assertRaises(ValueError, converter.strToWideOffsets, 1, 0) diff --git a/tests/unit/textProvider.py b/tests/unit/textProvider.py index 77e691c48cf..ae3c7f578dc 100644 --- a/tests/unit/textProvider.py +++ b/tests/unit/textProvider.py @@ -2,7 +2,7 @@ #A part of NonVisual Desktop Access (NVDA) #This file is covered by the GNU General Public License. #See the file COPYING for more details. -#Copyright (C) 2017 NV Access Limited +#Copyright (C) 2017-2019 NV Access Limited """Fake text provider implementation for testing of code which uses TextInfos. See the L{BasicTextProvider} class. @@ -11,10 +11,19 @@ from NVDAObjects import NVDAObject, NVDAObjectTextInfo import textInfos from textInfos.offsets import Offsets +import textUtils class BasicTextInfo(NVDAObjectTextInfo): # NVDAHelper is not initialized, so we can't use Uniscribe. useUniscribe = False + # Most of our code use UTF-16 as internal encoding. + # Mimic this behavior, so we can also implicitly test textUtils module code + encoding = textUtils.WCHAR_ENCODING + + def _getStoryLength(self): + # NVDAObjectTextInfo will just return the str length of the story text,. + # As we are using UTF-16 as the internal encoding for this TextInfo, this is incorrect. + return textUtils.WideStringOffsetConverter(self._getStoryText()).wideStringLength def _get_offsets(self): return (self._startOffset, self._endOffset) @@ -48,13 +57,13 @@ class BasicTextProvider(NVDAObject): def __init__(self, text=None, selection=(0, 0)): """ @param text: The text to provide via TextInfos. - @type text: basestring + @type text: str @param selection: The start and end offsets of the initial selection; same start and end is caret with no selection. @type selection: tuple of (int, int) """ super(BasicTextProvider, self).__init__() - self.basicText = unicode(text) + self.basicText = text self.selectionOffsets = selection def makeTextInfo(self, position): diff --git a/user_docs/en/changes.t2t b/user_docs/en/changes.t2t index 30df8f93074..6cf28b58343 100644 --- a/user_docs/en/changes.t2t +++ b/user_docs/en/changes.t2t @@ -5,6 +5,10 @@ What's New in NVDA = threshold release = +== Bug Fixes == +- Emoji and other 32 bit unicode characters now take less space on a braille display when they are shown as hexadecimal values. (#6695) + + == Changes for Developers == - Updated pySerial to version 3.4 - the validate module is now only available from configobj. Code should now do from configobj import validate rather than import validate.