├── addon
├── utilities
│ ├── win32Ex
│ │ ├── __init__.py
│ │ ├── win32api.pyd
│ │ ├── pywintypes311.dll
│ │ ├── win32security.pyd
│ │ └── license.txt
│ ├── pycawEx
│ │ ├── __init__.py
│ │ └── pycaw
│ │ │ ├── __init__.py
│ │ │ ├── api
│ │ │ ├── __init__.py
│ │ │ ├── audioclient
│ │ │ │ └── depend.py
│ │ │ ├── endpointvolume
│ │ │ │ └── depend.py
│ │ │ └── mmdeviceapi
│ │ │ │ └── depend
│ │ │ │ ├── __init__.py
│ │ │ │ └── structures.py
│ │ │ ├── constants.py
│ │ │ └── pycaw.py
│ ├── pydubEx
│ │ ├── __init__.py
│ │ ├── logging_utils.py
│ │ ├── exceptions.py
│ │ └── playback.py
│ ├── diff.zip
│ ├── msgfmt.exe
│ ├── xgettext.exe
│ ├── psutilEx
│ │ ├── python3.dll
│ │ └── _psutil_windows.pyd
│ └── markdownEx
│ │ └── markdown
│ │ ├── extensions
│ │ ├── nl2br.py
│ │ ├── legacy_em.py
│ │ ├── extra.py
│ │ ├── sane_lists.py
│ │ ├── meta.py
│ │ ├── legacy_attrs.py
│ │ └── wikilinks.py
│ │ ├── __meta__.py
│ │ ├── __init__.py
│ │ └── preprocessors.py
├── globalPlugins
│ └── NVDAExtensionGlobalPlugin
│ │ ├── scripts
│ │ └── __init__.py
│ │ ├── textAnalysis
│ │ ├── __init_.py
│ │ └── symbols.py
│ │ ├── tools
│ │ ├── manifest-translated.ini.tpl
│ │ ├── manifest.ini.tpl
│ │ ├── generate.py
│ │ ├── buildVars.py.tpl
│ │ └── gettextTools.py
│ │ ├── activeWindowsListReport
│ │ └── __init__.py
│ │ ├── computerTools
│ │ ├── waves
│ │ │ ├── white_noise_10s.wav
│ │ │ └── white_noise_3s.wav
│ │ ├── tonesPatches.py
│ │ ├── bluetoothAudio.py
│ │ ├── __init__.py
│ │ ├── beep.py
│ │ ├── messageDialogs.py
│ │ ├── audioUtils.py
│ │ ├── waves.py
│ │ └── pycawUtils.py
│ │ ├── utils
│ │ ├── secure.py
│ │ ├── nvdaInfos.py
│ │ ├── py3Compatibility.py
│ │ ├── NVDAStrings.py
│ │ ├── runInThread.py
│ │ ├── numlock.py
│ │ ├── keyboard.py
│ │ └── textInfo.py
│ │ ├── updateHandler
│ │ ├── NVDAStrings.py
│ │ ├── __init__.py
│ │ └── state.py
│ │ ├── browseModeEx
│ │ ├── NVDAObjectsUIA.py
│ │ ├── NVDAObjectsUIAChromium.py
│ │ ├── UIAParagraph.py
│ │ ├── __init__.py
│ │ └── NVDAObjectsIAccessible.py
│ │ ├── speechHistory
│ │ ├── extensions.py
│ │ ├── speechHistoryPatches.py
│ │ └── __init__.py
│ │ ├── speech
│ │ ├── commands.py
│ │ └── sayError.py
│ │ ├── extendedNetUIHWND
│ │ └── __init__.py
│ │ ├── clipboardCommandAnnouncement
│ │ ├── settingsDialogsPatche.py
│ │ └── clipboard.py
│ │ ├── __init__.py
│ │ ├── userInputGestures
│ │ └── inputGesturesExPatches.py
│ │ ├── currentFolder
│ │ └── __init__.py
│ │ ├── commandKeysSelectiveAnnouncementAndRemanence
│ │ └── patchs.py
│ │ └── winExplorer
│ │ └── __init__.py
├── newSymbols
│ ├── symbols-fr.dic
│ ├── symbols-tr.dic
│ ├── symbols-en.dic
│ ├── symbols-da.dic
│ ├── symbols-pt.dic
│ └── symbols-es.dic
├── doc
│ ├── en
│ │ ├── diff.zip
│ │ ├── addon_informations.t2tconf
│ │ └── to translators.txt
│ ├── fr
│ │ ├── diff.zip
│ │ └── addon_informations.t2tconf
│ ├── ar
│ │ ├── addon_informations.t2tconf
│ │ ├── addonUserManual.t2t
│ │ └── addon_keys.t2tconf
│ ├── ru
│ │ └── addon_informations.t2tconf
│ ├── sr
│ │ ├── addon_informations.t2tconf
│ │ └── changes.t2t
│ ├── uk
│ │ └── addon_informations.t2tconf
│ ├── da
│ │ └── addon_informations.t2tconf
│ ├── pt
│ │ └── addon_informations.t2tconf
│ ├── pt_BR
│ │ └── addon_informations.t2tconf
│ ├── es
│ │ └── addon_informations.t2tconf
│ ├── addon_userManual.t2tconf
│ ├── addon_global.t2tconf
│ ├── addon_build.t2tconf
│ ├── style_t2t.css
│ ├── style.css
│ └── styles.css
├── sounds
│ ├── ringin.wav
│ └── textAnalyzerAlerts
│ │ ├── error.wav
│ │ ├── uhoh.wav
│ │ ├── nvda-error.wav
│ │ ├── textError.wav
│ │ ├── Bicycle Horn.wav
│ │ ├── Windows Error.wav
│ │ ├── Windows Error-raga.wav
│ │ └── WindowsError-afternoon.wav
├── locale
│ ├── ar
│ │ ├── gestures-comp.ini
│ │ ├── howToTranslate.txt
│ │ ├── keyboard.ini
│ │ ├── textAnalysis.ini
│ │ └── symbolCategories.dic
│ ├── fr
│ │ ├── gestures-comp.ini
│ │ ├── keyboard.ini
│ │ └── textAnalysis.ini
│ ├── da
│ │ ├── keyboard.ini
│ │ └── symbolCategories.dic
│ ├── vi
│ │ ├── keyboard.ini
│ │ └── symbolCategories.dic
│ ├── sr
│ │ └── keyboard.ini
│ ├── tr
│ │ ├── keyboard.ini
│ │ ├── textAnalysis.ini
│ │ └── symbolCategories.dic
│ ├── ru
│ │ └── keyboard.ini
│ ├── es
│ │ ├── keyboard.ini
│ │ └── textAnalysis.ini
│ ├── cs
│ │ ├── textAnalysis.ini
│ │ ├── keyboard.ini
│ │ └── symbolCategories.dic
│ ├── en
│ │ ├── textAnalysis.ini
│ │ ├── keyboard.ini
│ │ ├── symbolCategories.dic
│ │ └── manifest.ini
│ ├── sk
│ │ ├── textAnalysis.ini
│ │ ├── keyboard.ini
│ │ └── symbolCategories.dic
│ ├── pt_BR
│ │ └── keyboard.ini
│ └── pt
│ │ └── keyboard.ini
├── used dependancies.txt
├── onInstall.py
└── howToTranslate.txt
├── .gitignore
├── makePotFile.bat
├── msgfmt.exe
├── xgettext.exe
├── manifest-translated.ini.tpl
├── clean.bat
├── updateRepo.bat
├── makeAddon.bat
├── manifest.ini.tpl
├── .gitattributes
├── appveyor.yml
├── howToTranslate.txt
├── style.css
└── site_scons
└── site_tools
└── gettexttool
└── __init__.py
/addon/utilities/win32Ex/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/addon/utilities/pycawEx/__init__.py:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/addon/utilities/pycawEx/pycaw/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/addon/utilities/pycawEx/pycaw/api/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/scripts/__init__.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.mo
2 | *.pyc
3 | *.pyo
4 | *.nvda-addon
5 | .sconsign.dblite
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/textAnalysis/__init_.py:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/addon/utilities/pydubEx/__init__.py:
--------------------------------------------------------------------------------
1 | from .audio_segment import AudioSegment
--------------------------------------------------------------------------------
/addon/newSymbols/symbols-fr.dic:
--------------------------------------------------------------------------------
1 | symbols:
2 | \v Tabulation verticale char never # \v
3 |
--------------------------------------------------------------------------------
/makePotFile.bat:
--------------------------------------------------------------------------------
1 | @echo off
2 | call scons pot
3 | del *.pyc
4 | del .sconsign.dblite
5 |
--------------------------------------------------------------------------------
/msgfmt.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/msgfmt.exe
--------------------------------------------------------------------------------
/xgettext.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/xgettext.exe
--------------------------------------------------------------------------------
/manifest-translated.ini.tpl:
--------------------------------------------------------------------------------
1 | summary = "{addon_summary}"
2 | description = """{addon_description}"""
3 |
--------------------------------------------------------------------------------
/addon/doc/en/diff.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/doc/en/diff.zip
--------------------------------------------------------------------------------
/addon/doc/fr/diff.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/doc/fr/diff.zip
--------------------------------------------------------------------------------
/addon/doc/ar/addon_informations.t2tconf:
--------------------------------------------------------------------------------
1 | % add-on summary
2 | %!PostProc (html): ADDON_SUMMARY وظائف إضافية لبرنامج nvda
--------------------------------------------------------------------------------
/addon/sounds/ringin.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/sounds/ringin.wav
--------------------------------------------------------------------------------
/addon/doc/en/addon_informations.t2tconf:
--------------------------------------------------------------------------------
1 | % add-on summary
2 | %!PostProc (html): ADDON_SUMMARY NVDA global commands extension
--------------------------------------------------------------------------------
/addon/doc/ru/addon_informations.t2tconf:
--------------------------------------------------------------------------------
1 | % add-on summary
2 | %!PostProc (html): ADDON_SUMMARY NVDA global commands extension
--------------------------------------------------------------------------------
/addon/doc/sr/addon_informations.t2tconf:
--------------------------------------------------------------------------------
1 | % add-on summary
2 | %!PostProc (html): ADDON_SUMMARY NVDA global commands extension
--------------------------------------------------------------------------------
/addon/utilities/diff.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/utilities/diff.zip
--------------------------------------------------------------------------------
/addon/utilities/msgfmt.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/utilities/msgfmt.exe
--------------------------------------------------------------------------------
/addon/doc/uk/addon_informations.t2tconf:
--------------------------------------------------------------------------------
1 | % add-on summary
2 | %!PostProc (html): ADDON_SUMMARY Глобальне розширення команд NVDA
--------------------------------------------------------------------------------
/addon/utilities/xgettext.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/utilities/xgettext.exe
--------------------------------------------------------------------------------
/addon/doc/da/addon_informations.t2tconf:
--------------------------------------------------------------------------------
1 | % add-on summary
2 | %!PostProc (html): ADDON_SUMMARY Udvidelse med globale NVDA-kommandoer
--------------------------------------------------------------------------------
/addon/doc/fr/addon_informations.t2tconf:
--------------------------------------------------------------------------------
1 | % add-on summary
2 | %!PostProc (html): ADDON_SUMMARY Extension des commandes de base de NVDA
--------------------------------------------------------------------------------
/addon/doc/pt/addon_informations.t2tconf:
--------------------------------------------------------------------------------
1 | % add-on summary
2 | %!PostProc (html): ADDON_SUMMARY Complemento Extensão de comandos do NVDA
--------------------------------------------------------------------------------
/addon/doc/pt_BR/addon_informations.t2tconf:
--------------------------------------------------------------------------------
1 | % add-on summary
2 | %!PostProc (html): ADDON_SUMMARY Extensão de comandos globais do NVDA
3 |
--------------------------------------------------------------------------------
/addon/locale/ar/gestures-comp.ini:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/locale/ar/gestures-comp.ini
--------------------------------------------------------------------------------
/addon/locale/fr/gestures-comp.ini:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/locale/fr/gestures-comp.ini
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/tools/manifest-translated.ini.tpl:
--------------------------------------------------------------------------------
1 | summary = "{summary}"
2 | description = """{description}"""
3 |
--------------------------------------------------------------------------------
/addon/locale/ar/howToTranslate.txt:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/locale/ar/howToTranslate.txt
--------------------------------------------------------------------------------
/addon/utilities/psutilEx/python3.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/utilities/psutilEx/python3.dll
--------------------------------------------------------------------------------
/addon/utilities/win32Ex/win32api.pyd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/utilities/win32Ex/win32api.pyd
--------------------------------------------------------------------------------
/addon/doc/es/addon_informations.t2tconf:
--------------------------------------------------------------------------------
1 | % add-on summary
2 | %!PostProc (html): ADDON_SUMMARY Complemento Extensión de las órdenes básicas de NVDA
--------------------------------------------------------------------------------
/addon/newSymbols/symbols-tr.dic:
--------------------------------------------------------------------------------
1 | symbols:
2 | ‹ tek üçgen tırnak aç
3 | › tek üçgen tırnak kapa
4 | ℅ dikkat
5 | \v Dikey sekme char never # \v
6 |
--------------------------------------------------------------------------------
/addon/sounds/textAnalyzerAlerts/error.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/sounds/textAnalyzerAlerts/error.wav
--------------------------------------------------------------------------------
/addon/sounds/textAnalyzerAlerts/uhoh.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/sounds/textAnalyzerAlerts/uhoh.wav
--------------------------------------------------------------------------------
/addon/utilities/win32Ex/pywintypes311.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/utilities/win32Ex/pywintypes311.dll
--------------------------------------------------------------------------------
/addon/utilities/win32Ex/win32security.pyd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/utilities/win32Ex/win32security.pyd
--------------------------------------------------------------------------------
/addon/doc/addon_userManual.t2tconf:
--------------------------------------------------------------------------------
1 | % NOTHING TO TRANSLATE
2 | % -----
3 | %!includeconf: addon_global.t2tconf
4 | %!Options: --toc
5 | %!style:..\style_t2t.css
6 |
--------------------------------------------------------------------------------
/addon/newSymbols/symbols-en.dic:
--------------------------------------------------------------------------------
1 | symbols:
2 | ‹ Left Single Angle Quote
3 | › Right Single Angle Quote
4 | ℅ Care Of
5 | \v Vertical tabulation char never # \v
6 |
--------------------------------------------------------------------------------
/addon/sounds/textAnalyzerAlerts/nvda-error.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/sounds/textAnalyzerAlerts/nvda-error.wav
--------------------------------------------------------------------------------
/addon/sounds/textAnalyzerAlerts/textError.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/sounds/textAnalyzerAlerts/textError.wav
--------------------------------------------------------------------------------
/addon/utilities/psutilEx/_psutil_windows.pyd:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/utilities/psutilEx/_psutil_windows.pyd
--------------------------------------------------------------------------------
/addon/sounds/textAnalyzerAlerts/Bicycle Horn.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/sounds/textAnalyzerAlerts/Bicycle Horn.wav
--------------------------------------------------------------------------------
/addon/sounds/textAnalyzerAlerts/Windows Error.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/sounds/textAnalyzerAlerts/Windows Error.wav
--------------------------------------------------------------------------------
/addon/sounds/textAnalyzerAlerts/Windows Error-raga.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/sounds/textAnalyzerAlerts/Windows Error-raga.wav
--------------------------------------------------------------------------------
/addon/sounds/textAnalyzerAlerts/WindowsError-afternoon.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/sounds/textAnalyzerAlerts/WindowsError-afternoon.wav
--------------------------------------------------------------------------------
/clean.bat:
--------------------------------------------------------------------------------
1 | echo off
2 | call scons -c -s
3 | del /s /q *.pyc
4 | del /s /q .sconsign.dblite
5 | del *.pot
6 | rd /s /q __pycache__
7 | rd /s /q .\site_scons\site_tools\gettexttool\__pycache__
8 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/activeWindowsListReport/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/globalPlugins/NVDAExtensionGlobalPlugin/activeWindowsListReport/__init__.py
--------------------------------------------------------------------------------
/addon/doc/en/to translators.txt:
--------------------------------------------------------------------------------
1 | Files to translate:
2 | addon_informations.t2tconf
3 | addon_keys.t2tconf
4 | addonUserManual.t2t
5 | changes.t2t
6 |
7 | The diff.zip contains file changes between this version and previous stable version.
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/computerTools/waves/white_noise_10s.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/globalPlugins/NVDAExtensionGlobalPlugin/computerTools/waves/white_noise_10s.wav
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/computerTools/waves/white_noise_3s.wav:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/paulber19/NVDAExtensionGlobalPlugin/HEAD/addon/globalPlugins/NVDAExtensionGlobalPlugin/computerTools/waves/white_noise_3s.wav
--------------------------------------------------------------------------------
/addon/newSymbols/symbols-da.dic:
--------------------------------------------------------------------------------
1 | symbols:
2 | # Daniel Gartmann June 23 2022: Not yet found official Danish translations, so open to change
3 | ‹ Venstre enkelt vinklet anførselstegn
4 | › Højre enkelt vinklet anførselstegn
5 | ℅ Attention
6 | \v Lodret tabulator char never # \v
7 |
--------------------------------------------------------------------------------
/updateRepo.bat:
--------------------------------------------------------------------------------
1 | ;@echo off
2 | if exist .\addon\buildVars.py (
3 | copy .\addon\buildVars.py .
4 | )
5 | if exist .\addon\doc\en\readme.md (
6 | copy .\addon\doc\en\readme.md .
7 | if exist .\addon\doc\style_md.css (
8 | copy .\addon\doc\style_md.css .
9 | )
10 | )
11 |
--------------------------------------------------------------------------------
/makeAddon.bat:
--------------------------------------------------------------------------------
1 | ;@echo off
2 | if exist .\addon\buildVars.py (
3 | copy .\addon\buildVars.py .
4 | )
5 |
6 | call scons -s
7 | ren *.nvda-addon *.nvda-addonTMP
8 | call scons -c
9 | ren *.nvda-addonTMP *.nvda-addon
10 | del /s /q *.pyc > NUL
11 | del .sconsign.dblite> NUL
12 | rd /s /q __pycache__
13 | rd /s /q .\site_scons\site_tools\gettexttool\__pycache__
--------------------------------------------------------------------------------
/manifest.ini.tpl:
--------------------------------------------------------------------------------
1 | name = {addon_name}
2 | summary = "{addon_summary}"
3 | version = {addon_version}
4 | description = """{addon_description}"""
5 | author = "{addon_author}"
6 | url = "{addon_url}"
7 | docFileName = {addon_docFileName}
8 | minimumNVDAVersion = {addon_minimumNVDAVersion}
9 | lastTestedNVDAVersion = {addon_lastTestedNVDAVersion}
10 | updateChannel = {addon_updateChannel}
11 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | # Set default behaviour, in case users don't have core.autocrlf set.
2 | * text=auto
3 |
4 | # Try to ensure that po files in the repo does not include
5 | # source code line numbers.
6 | # Every person expected to commit po files should change their personal config file as described here:
7 | # https://mail.gnome.org/archives/kupfer-list/2010-June/msg00002.html
8 | *.po filter=cleanpo
9 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/utils/secure.py:
--------------------------------------------------------------------------------
1 | # NVDAExtensionGlobalPlugin/utils/secure.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2022 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 | import globalVars
8 |
9 |
10 | def inSecureMode():
11 | return globalVars.appArgs.secure
12 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/tools/manifest.ini.tpl:
--------------------------------------------------------------------------------
1 | name = {addon_name}
2 | summary = "{addon_summary}"
3 | version = {addon_version}
4 | description = """{addon_description}"""
5 | author = "{addon_author}"
6 | url = "{addon_url}"
7 | docFileName = {addon_docFileName}
8 | minimumNVDAVersion = {addon_minimumNVDAVersion}
9 | lastTestedNVDAVersion = {addon_lastTestedNVDAVersion}
10 | updateChannel = {addon_updateChannel}
11 |
--------------------------------------------------------------------------------
/addon/utilities/pycawEx/pycaw/api/audioclient/depend.py:
--------------------------------------------------------------------------------
1 | from ctypes import Structure
2 | from ctypes.wintypes import WORD
3 |
4 |
5 | class WAVEFORMATEX(Structure):
6 | _fields_ = [
7 | ("wFormatTag", WORD),
8 | ("nChannels", WORD),
9 | ("nSamplesPerSec", WORD),
10 | ("nAvgBytesPerSec", WORD),
11 | ("nBlockAlign", WORD),
12 | ("wBitsPerSample", WORD),
13 | ("cbSize", WORD),
14 | ]
15 |
--------------------------------------------------------------------------------
/addon/utilities/pydubEx/logging_utils.py:
--------------------------------------------------------------------------------
1 | """
2 |
3 | """
4 | import logging
5 |
6 | converter_logger = logging.getLogger("pydub.converter")
7 |
8 | def log_conversion(conversion_command):
9 | converter_logger.debug("subprocess.call(%s)", repr(conversion_command))
10 |
11 | def log_subprocess_output(output):
12 | if output:
13 | for line in output.rstrip().splitlines():
14 | converter_logger.debug('subprocess output: %s', line.rstrip())
15 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/updateHandler/NVDAStrings.py:
--------------------------------------------------------------------------------
1 | # NVDAStrings.py
2 | # a common part of all of my addons.
3 |
4 | # Copyright (C) 2019 paulber19
5 | # This file is covered by the GNU General Public License.
6 |
7 |
8 | def NVDAString(s):
9 | """ A simple function to bypass the addon translation system,
10 | so it can take advantage from the NVDA translations directly.
11 | Based on implementation made by Alberto Buffolino
12 | https://github.com/nvaccess/nvda/issues/4652 """
13 |
14 | return _(s)
15 |
--------------------------------------------------------------------------------
/addon/utilities/pycawEx/pycaw/api/endpointvolume/depend.py:
--------------------------------------------------------------------------------
1 | from ctypes import POINTER, Structure, c_float
2 | from ctypes.wintypes import BOOL, UINT
3 |
4 | from comtypes import GUID
5 |
6 |
7 | class AUDIO_VOLUME_NOTIFICATION_DATA(Structure):
8 | _fields_ = [
9 | ("guidEventContext", GUID),
10 | ("bMuted", BOOL),
11 | ("fMasterVolume", c_float),
12 | ("nChannels", UINT),
13 | ("afChannelVolumes", c_float * 8),
14 | ]
15 |
16 |
17 | PAUDIO_VOLUME_NOTIFICATION_DATA = POINTER(AUDIO_VOLUME_NOTIFICATION_DATA)
18 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/utils/nvdaInfos.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin/utils/nvdaInfos.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2025 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 | try:
8 | # for nvda versions < 2026.1
9 | from versionInfo import version_year, version_major
10 | except ImportError:
11 | # for NVDA versions >= 2026.1
12 | from buildVersion import version_year, version_major
13 |
14 | NVDAVersion = [version_year, version_major]
15 |
--------------------------------------------------------------------------------
/addon/utilities/pydubEx/exceptions.py:
--------------------------------------------------------------------------------
1 | class PydubException(Exception):
2 | """
3 | Base class for any Pydub exception
4 | """
5 |
6 |
7 | class TooManyMissingFrames(PydubException):
8 | pass
9 |
10 |
11 | class InvalidDuration(PydubException):
12 | pass
13 |
14 |
15 | class InvalidTag(PydubException):
16 | pass
17 |
18 |
19 | class InvalidID3TagVersion(PydubException):
20 | pass
21 |
22 |
23 | class CouldntDecodeError(PydubException):
24 | pass
25 |
26 |
27 | class CouldntEncodeError(PydubException):
28 | pass
29 |
30 |
31 | class MissingAudioParameter(PydubException):
32 | pass
33 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/utils/py3Compatibility.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\utils\py3Compatibility.py
2 | # a part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright 2019 - 2025 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 | import addonHandler
8 | import os
9 |
10 |
11 | def getCommonUtilitiesPath():
12 | curAddonPath = getAddonPath()
13 | return os.path.join(curAddonPath, "utilities")
14 |
15 |
16 | def getAddonPath(addon=None):
17 | if addon is None:
18 | addon = addonHandler.getCodeAddon()
19 | return addon.path
20 |
--------------------------------------------------------------------------------
/addon/doc/sr/changes.t2t:
--------------------------------------------------------------------------------
1 | ADDON_SUMMARY - istorija promena
2 | Autor: ADDON_AUTHOR_NAME
3 |
4 |
5 | %!includeconf: ../addon_global.t2tconf
6 | %!includeconf: addon_informations.t2tconf
7 | URL: [ADDON_REPOSITORY ADDON_REPOSITORY]
8 |
9 |
10 | Preuzimanje:
11 | - [Trenutna verzija: ADDON_CUR_VERSION ADDON_DOWNLOAD_SERVER1]
12 | - [Prethodna verzija: ADDON_PREV_VERSION ADDON_DOWNLOAD_PREVIOUS]
13 | - [Verzije u razvoju ADDON_DEV_URL]
14 |
15 |
16 | + v9.7 (04/01/2021) +
17 | - Nastavak funkcije za slanje svih zvučnih obaveštenja kao poruke na brajevom redu.
18 |
19 |
20 | + Starije verzije +
21 | Starije verzije nisu prevedene na Srpski.
22 | Molimo pogledajte Francusku ili Englesku dokumentaciju dodatka.
--------------------------------------------------------------------------------
/addon/used dependancies.txt:
--------------------------------------------------------------------------------
1 | The following dependencies are embedded in the extension:
2 | - python markdown 3.7: Copyright 2007-2023 The Python Markdown Project (v. 1.7 and later). License: BSD.
3 | - pydub 0.25.1: Copyright © 2011 James Robert, http://jiaaro.co. License (MIT License).
4 | - part of wpywin32 306: Copyright (c) 1994-2008, Mark Hammond
5 | - msgfmt and xgettext of GNU Gettext tools : https://gnuwin32.sourceforge.net/downlinks/gettext.php
6 | - psutil 5.9.6: Copyright (c) 2009, Giampaolo Rodola'. All rights reserved.
7 | - pycaw v20240210 Copyright (c) 2016 AndreMiras. License (MIT)
8 | -txt2tags 2.5: Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 Aurelio Jargas, Copyright 2018, 2019 Takuya Nishimoto
9 |
--------------------------------------------------------------------------------
/addon/locale/ar/keyboard.ini:
--------------------------------------------------------------------------------
1 | #هذا الملف يجب أن يكون بتنسيق utf-8 بدون BOM.
2 | [KeyboardKeys]
3 | # هذا القسم يحدد أحرف من مربع حوار "نطق اسماء المفاتيح".
4 | # كن حذرا: يجب أن يكون نفس إسم الحرف الذي يعلن عنه في مساعدة nvda+1.
5 | #على سبيل المثال لوحة مفاتيح سطح المكتب بالعربية هي :
6 | # row 1: ` 1 2 3 4 5 6 7 8 9 0 - =
7 | # row 2:ض ص ث ق ف غ ع ه خ ح ج د
8 | # row 3: ش س ي ب ل ا ت ن م ك ط
9 | # row 4: ئ ء ؤ ر لا ى ة و ز ظ
10 | # تعريف ترتيب المفاتيح في مربع الحوار.
11 | keys = "أبتثجحخدذرزسشصضطظعغفقكلمنهوي"
12 | [editionKeyCommands]
13 | [[default]]
14 |
15 | # هذا القسم يحدد نسخة أوامر لوحة المفاتيح في نظام ويندوز
16 | copy = control+c
17 | cut = control+x
18 | paste = control+v
19 | undo = control+z
20 | selectAll = control+a
--------------------------------------------------------------------------------
/addon/newSymbols/symbols-pt.dic:
--------------------------------------------------------------------------------
1 | symbols:
2 | ‹ abrir aspas simples
3 | › fechar aspas simples
4 | ℅ à Atenção de
5 | \v Guia vertical char never # \v
6 | # Adding by raifer, letras Gregas
7 | α alfa
8 | Α alfa
9 | β beta
10 | Β beta
11 | γ gama
12 | Γ gama
13 | δ delta
14 | Δ delta
15 | ε epsilon
16 | Ε epsilon
17 | ζ zeta
18 | Ζ zeta
19 | η eta
20 | Η eta
21 | θ téta
22 | Θ téta
23 | ι iota
24 | Ι iota
25 | κ kapa
26 | Κ kapa
27 | λ lambda
28 | Λ lambda
29 | μ mu
30 | Μ mu
31 | ν nu
32 | Ν nu
33 | ξ xi
34 | Ξ xi
35 | ο omicron
36 | Ο omicron
37 | π pi
38 | Π pi
39 | ρ ró
40 | Ρ ró
41 | σ sigma
42 | ς sigma final
43 | Σ sigma
44 | τ tau
45 | Τ tau
46 | υ upsilon
47 | Υ upsilon
48 | φ fi
49 | Φ fi
50 | χ xi
51 | Χ xi
52 | ψ psi
53 | Ψ psi
54 | ω ómega
55 | Ω ómega
56 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/utils/NVDAStrings.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\utils\NVDAStrings.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2017 - 2024 Paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 |
8 | def NVDAString(s):
9 | """ A simple function to bypass the addon translation system,
10 | so it can take advantage from the NVDA translations directly.
11 | Based on implementation made by Alberto Buffolino
12 | https://github.com/nvaccess/nvda/issues/4652 """
13 | return _(s)
14 |
15 |
16 | def NVDAString_pgettext(c, s):
17 | return pgettext(c, s)
18 |
19 |
20 | def NVDAString_ngettext(s, p, c):
21 | return ngettext(s, p, c) # noqa:F82
22 |
--------------------------------------------------------------------------------
/addon/newSymbols/symbols-es.dic:
--------------------------------------------------------------------------------
1 | symbols:
2 | ‹ Abre Comillas Simple
3 | › Cerrar Comillas Simple
4 | ℅ Atención A
5 | \v Tabulación vertical char never # \v
6 | # Adding by raifer, letras Griegas
7 | α alfa
8 | Α alfa
9 | β beta
10 | Β beta
11 | γ gamma
12 | Γ gamma
13 | δ delta
14 | Δ delta
15 | ε épsilon
16 | Ε épsilon
17 | ζ dseta
18 | Ζ dseta
19 | η eta
20 | Η eta
21 | θ zeta
22 | Θ zeta
23 | ι iota
24 | Ι iota
25 | κ kappa
26 | Κ kappa
27 | λ lambda
28 | Λ lambda
29 | μ mi
30 | Μ mi
31 | ν ni
32 | Ν ni
33 | ξ xi
34 | Ξ xi
35 | ο ómicron
36 | Ο ómicron
37 | π pi
38 | Π pi
39 | ρ rho
40 | Ρ rho
41 | σ sigma
42 | ς sigma Final
43 | Σ sigma
44 | τ tau
45 | Τ tau
46 | υ ípsilon
47 | Υ ípsilon
48 | φ fi
49 | Φ fi
50 | χ ji
51 | Χ ji
52 | ψ psi
53 | Ψ psi
54 | ω omega
55 | Ω omega
56 | # End of adding
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/browseModeEx/NVDAObjectsUIA.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\browseModeEx\NVDAObjectsUIA.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2016 - 2023 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 | from NVDAObjects.UIA.spartanEdge import EdgeHTMLRoot, EdgeHTMLTreeInterceptor
8 | from .browseModeUIAEx import UIABrowseModeDocumentEx, EdgeElementsListDialog
9 |
10 |
11 | class EdgeHTMLTreeInterceptorEx (
12 | UIABrowseModeDocumentEx, EdgeHTMLTreeInterceptor):
13 | def _get_ElementsListDialog(self):
14 | return EdgeElementsListDialog
15 |
16 |
17 | class EdgeHTMLRootEx(EdgeHTMLRoot):
18 | treeInterceptorClass = EdgeHTMLTreeInterceptorEx
19 |
--------------------------------------------------------------------------------
/addon/locale/ar/textAnalysis.ini:
--------------------------------------------------------------------------------
1 | [SymbolToSymetric]
2 | # this section defines the symbols and symetric symbols used by the mismatch analysis functionality.
3 | # parenthese
4 | ( = )
5 | #"bracket"
6 | "[" = ]
7 | # "brace"
8 | { = }
9 | #quote
10 | “ = ”
11 | # chevron
12 | ‹ = ›
13 | #
14 | « = »
15 | [Punctuations]
16 | # defines all punctuations to be used in analysis.
17 | "All" = ()[]{},:.;!?“‹«”›»"'-
18 | # defines punctuations which must be preceded by a space.
19 | "NeedSpaceBefore" = ([{“‹«
20 | # defines punctuations which must be followed by a space.
21 | "NeedSpaceAfter" = )]}?!,.:;”›»
22 | # defines punctuations which must not be preceded by space.
23 | "NoSpaceBefore" = )]}.:;,”›»-
24 | # defines punctuations which must not be followed by a space.
25 | "NoSpaceAfter" = ([{“‹«-
26 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/browseModeEx/NVDAObjectsUIAChromium.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\browseModeEx\NVDAObjectsUIAChromium.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2021 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 |
8 | from NVDAObjects.UIA.chromium import ChromiumUIADocument, ChromiumUIATreeInterceptor
9 | from .browseModeUIAEx import UIABrowseModeDocumentEx, EdgeElementsListDialog
10 |
11 |
12 | class ChromiumUIATreeInterceptorEx(
13 | UIABrowseModeDocumentEx, ChromiumUIATreeInterceptor):
14 | def _get_ElementsListDialog(self):
15 | return EdgeElementsListDialog
16 |
17 |
18 | class ChromiumUIADocumentEx(ChromiumUIADocument):
19 | treeInterceptorClass = ChromiumUIATreeInterceptorEx
20 |
--------------------------------------------------------------------------------
/addon/locale/da/keyboard.ini:
--------------------------------------------------------------------------------
1 | # this file must be recorded in utf-8 without BOM.
2 | [KeyboardKeys]
3 | # this section defines the characters of keyboard keys to be used in key command selective announcement dialog and can be used in a gesture.
4 | # becarefull: it must be the character said by NVDA in input help on.
5 | # for exemple, the keys of a desktop US keyboard are:
6 | # row 1: ` 1 2 3 4 5 6 7 8 9 0 - =
7 | # row 2:q w e r t y u i o p [ ]
8 | # row 3: a s d f g h j k l ; ' \
9 | # row 4: \ z x c v b n m , . /
10 | # defines the order of the keys in the dialog.
11 | keys = "abcdefghijklmnopqrstuvwxyz0123456789`-=[];'\,./"
12 | [editionKeyCommands]
13 | [[default]]
14 | # this section defines the edition keyboard commands of Windows system
15 | copy = control+c
16 | cut = control+x
17 | paste = control+v
18 | undo = control+z
19 | selectAll = control+a
--------------------------------------------------------------------------------
/addon/locale/vi/keyboard.ini:
--------------------------------------------------------------------------------
1 | # this file must be recorded in utf-8 without BOM.
2 | [KeyboardKeys]
3 | # this section defines the characters of keyboard keys to be used in key command selective announcement dialog and can be used in a gesture.
4 | # becarefull: it must be the character said by NVDA in input help on.
5 | # for exemple, the keys of a desktop US keyboard are:
6 | # row 1: ` 1 2 3 4 5 6 7 8 9 0 - =
7 | # row 2:q w e r t y u i o p [ ]
8 | # row 3: a s d f g h j k l ; ' \
9 | # row 4: \ z x c v b n m , . /
10 | # defines the order of the keys in the dialog.
11 | keys = "abcdefghijklmnopqrstuvwxyz0123456789`-=[];'\,./"
12 | [editionKeyCommands]
13 | [[default]]
14 | # this section defines the edition keyboard commands of Windows system
15 | copy = control+c
16 | cut = control+x
17 | paste = control+v
18 | undo = control+z
19 | selectAll = control+a
--------------------------------------------------------------------------------
/addon/locale/sr/keyboard.ini:
--------------------------------------------------------------------------------
1 | # this file must be recorded in utf-8 without BOM.
2 | [KeyboardKeys]
3 | # this section defines the characters of keyboard keys to be used in key command selective announcement dialog and can be used in a gesture.
4 | # becarefull: it must be the character said by NVDA in input help on.
5 | # for exemple, the keys of a desktop US keyboard are:
6 | # row 1: ` 1 2 3 4 5 6 7 8 9 0 - =
7 | # row 2:q w e r t y u i o p [ ]
8 | # row 3: a s d f g h j k l ; ' \
9 | # row 4: \ z x c v b n m , . /
10 | # defines the order of the keys in the dialog.
11 | keys = "abcdefghijklmnopqrstuvwxyz0123456789`-=[];'\,./čćšđž"
12 | [editionKeyCommands]
13 | [[default]]
14 | # this section defines the edition keyboard commands of Windows system
15 | copy = control+c
16 | cut = control+x
17 | paste = control+v
18 | undo = control+z
19 | selectAll = control+a
--------------------------------------------------------------------------------
/addon/locale/tr/keyboard.ini:
--------------------------------------------------------------------------------
1 | [KeyboardKeys]
2 | # cette section définit les caractères des touches des clavier de bureau utilisés dans le dialogue "Annonce sélective des touches de commandes" et qui peuvent être placés dans les gestes de commandes.
3 | # attention: ce doit être le caractère dit par NVDA en aide clavier activé.
4 | #par exemple pour un clavier de bureau français:
5 | # row 1:² 1 2 3 4 5 6 7 8 9 0 ° +
6 | # row 2: a z e r t y u i o p ^ $
7 | # row 3: q s d f g h j k l m ù *
8 | # row 4: < w x c v b n , ; : !
9 | # définit l'ordre des touches dans le dialogue.
10 | keys = abcdefghijklmnopqrstuvwxyz0123456789*-ş,<öç.
11 |
12 |
13 | [editionKeyCommands]
14 | [[default]]
15 | # cette section définit les commandes clavier d'édition de Windows
16 | copy = control+c
17 | cut = control+x
18 | paste = control+v
19 | undo = control+z
20 | selectAll = control+a
21 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/speechHistory/extensions.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\speechHistory\extensions.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2024 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 | """
8 | Extension points for prevent new speech
9 | """
10 |
11 | from extensionPoints import Action
12 | from ..utils.nvdaInfos import NVDAVersion
13 | if NVDAVersion >= [2024, 2]:
14 | # we use NVDA pre_speech speech extensionPoint
15 | from speech.extensions import pre_speech
16 | my_pre_speech = pre_speech
17 | else:
18 | my_pre_speech = Action()
19 | """
20 | Notifies when code attempts to speak text.
21 | @param speechSequence: the sequence of text and L{SpeechCommand} objects to speak
22 | @type speechSequence: speech.SpeechSequence
23 | """
24 |
--------------------------------------------------------------------------------
/addon/locale/fr/keyboard.ini:
--------------------------------------------------------------------------------
1 | [KeyboardKeys]
2 | # cette section définit les caractères des touches des clavier de bureau utilisés dans le dialogue "Annonce sélective des touches de commandes" et qui peuvent être placés dans les gestes de commandes.
3 | # attention: ce doit être le caractère dit par NVDA en aide clavier activé.
4 | #par exemple pour un clavier de bureau français:
5 | # row 1:² 1 2 3 4 5 6 7 8 9 0 ° +
6 | # row 2: a z e r t y u i o p ^ $
7 | # row 3: q s d f g h j k l m ù *
8 | # row 4: < w x c v b n , ; : !
9 | # définit l'ordre des touches dans le dialogue.
10 | keys = abcdefghijklmnopqrstuvwxyz0123456789²)=^$ù*<,;:!
11 |
12 |
13 | [editionKeyCommands]
14 | [[default]]
15 | # cette section définit les commandes clavier d'édition de Windows
16 | copy = control+c
17 | cut = control+x
18 | paste = control+v
19 | undo = control+z
20 | selectAll = control+a
21 |
--------------------------------------------------------------------------------
/addon/locale/ru/keyboard.ini:
--------------------------------------------------------------------------------
1 | [KeyboardKeys]
2 | # cette section définit les caractères des touches des clavier de bureau utilisés dans le dialogue "Annonce sélective des touches de commandes" et qui peuvent être placés dans les gestes de commandes.
3 | # attention: ce doit être le caractère dit par NVDA en aide clavier activé.
4 | #par exemple pour un clavier de bureau français:
5 | # row 1:² 1 2 3 4 5 6 7 8 9 0 ° +
6 | # row 2: a z e r t y u i o p ^ $
7 | # row 3: q s d f g h j k l m ù *
8 | # row 4: < w x c v b n , ; : !
9 | # définit l'ordre des touches dans le dialogue.
10 | keys = abcdefghijklmnopqrstuvwxyz0123456789²)=^$ù*<,;:!
11 |
12 |
13 | [editionKeyCommands]
14 | [[default]]
15 | # cette section définit les commandes clavier d'édition de Windows
16 | copy = control+c
17 | cut = control+x
18 | paste = control+v
19 | undo = control+z
20 | selectAll = control+a
21 |
--------------------------------------------------------------------------------
/addon/locale/es/keyboard.ini:
--------------------------------------------------------------------------------
1 | [KeyboardKeys]
2 | # esta sección define los caracteres de las teclas del teclado de escritorio utilizado en el diálogo "Anuncio selectivo de teclas de órden" y que se puede colocar en los gestos de entrada.
3 | # atención: este debe ser el carácter dicho por NVDA en el modo de ayuda de entrada activado.
4 | #por ejemplo para un teclado de escritorio español internacional:
5 | # row 1 :º 1 2 3 4 5 6 7 8 9 0 ' ¡
6 | # row 2: q w e r t y u i o p ` +
7 | # row 3: a s d f g h j k l ñ ´ ç
8 | # row 4: < z x c v b n m , . -
9 | # define el orden de las teclas en el diálogo.
10 | keys = abcdefghijklmnopqrstuvwxyz0123456789º'¡`+<ñ´ç,.-
11 |
12 | [editionKeyCommands]
13 | [[default]]
14 | # esta sección se define los comandos de teclado (Windows edición
15 | copy = control+c
16 | cut = control+x
17 | paste = control+v
18 | undo = control+z
19 | selectAll = control+a
--------------------------------------------------------------------------------
/addon/locale/es/textAnalysis.ini:
--------------------------------------------------------------------------------
1 | # to define the decimal symbol separator (3,414)
2 | decimalSymbol = ,
3 | # to define the digit grouping symbol separator (1.212.333)
4 | digitGroupingSymbol = .
5 | [SymbolToSymetric]
6 | # parenthese
7 | ( = )
8 | #"bracket"
9 | "[" = ]
10 | # "brace"
11 | { = }
12 | #quote
13 | “ = ”
14 | # chevron
15 | ‹ = ›
16 | #
17 | « = »
18 | ¡ = !
19 | ¿ = ?
20 |
21 | [Punctuations]
22 | # defines all punctuations to be used in analysis.
23 | "All" = ()[]{},:.;¡!¿?“‹«”›»"'-
24 | # defines punctuations which must be preceded by a space.
25 | "NeedSpaceBefore" = ([{¡¿“‹«
26 | # defines punctuations which must be followed by a space.
27 | "NeedSpaceAfter" = )]}?!,.:;”›»
28 | # defines punctuations which must not be preceded by space.
29 | "NoSpaceBefore" = )]}?!.:;,”›»-
30 | # defines punctuations which must not be followed by a space.
31 | "NoSpaceAfter" = ([{¡¿“‹«-
32 |
--------------------------------------------------------------------------------
/appveyor.yml:
--------------------------------------------------------------------------------
1 | version: '{branch}-{build}'
2 | environment:
3 | PY_PYTHON: 2.7-32
4 | install:
5 | - cmd: >-
6 | python -m pip install wheel
7 |
8 | py -m pip install scons
9 |
10 | py -m pip install markdown
11 | build_script:
12 | - cmd: scons
13 |
14 | artifacts:
15 | - path: '*.nvda-addon'
16 | name: addon
17 | type: WebDeployPackage
18 |
19 | before_deploy:
20 | - ps: $env:REPO_NAME = $env:APPVEYOR_REPO_NAME.Substring($env:APPVEYOR_REPO_NAME.IndexOf('/') + 1)
21 |
22 | deploy:
23 | - provider: GitHub
24 | tag: $(APPVEYOR_REPO_TAG_NAME)
25 | release: Release $(APPVEYOR_REPO_TAG_NAME)
26 | description: This is the release $(APPVEYOR_REPO_TAG_NAME) of the $(REPO_NAME) addon for the NVDA screen reader built and uploaded to GitHub using Appveyor.
27 |
28 | auth_token:
29 | secure: Shqo5asiICk+0C1xjAfYUpTNdg3odsy2+Ycz0dMtbN2NaeAV+B8dxZn5Ad9pXnp
30 | artifact: addon
31 | on:
32 | appveyor_repo_tag: true
--------------------------------------------------------------------------------
/addon/onInstall.py:
--------------------------------------------------------------------------------
1 | # -*- coding: UTF-8 -*-
2 | # onInstall.py
3 | # A part of NVDAExtensionGlobalPlugin add-on
4 | # Copyright (C) 2016 - 2024 paulber19
5 | # This file is covered by the GNU General Public License.
6 | # See the file COPYING for more details.
7 |
8 | import addonHandler
9 | import gui
10 | import winUser
11 |
12 | addonHandler.initTranslation()
13 |
14 |
15 | def checkWindowListAddonInstalled():
16 | h = winUser.getForegroundWindow()
17 | addonCheckList = [
18 | "fakeClipboardAnouncement",
19 | "listDesFenetres",
20 | "ListeIconesZoneNotification",
21 | "DitDossierOuvrirEnregistrer"]
22 | for addon in addonHandler.getRunningAddons():
23 | if addon.manifest["name"] in addonCheckList:
24 | # Translators: message of message box
25 | msg = _("""Attention, you must uninstall "%s" add-on because it is now included in this add-on""") # noqa:E501
26 | gui.messageBox(msg % addon.manifest["name"])
27 | break
28 | winUser.setForegroundWindow(h)
29 |
--------------------------------------------------------------------------------
/addon/locale/fr/textAnalysis.ini:
--------------------------------------------------------------------------------
1 | # to define the decimal symbol separator (3,414)
2 | decimalSymbol = ,
3 | # to define the digit grouping symbol separator (1.212.333)
4 | digitGroupingSymbol = .
5 | [SymbolToSymetric]
6 | # this section defines the symbols and symetric symbols used by the mismatch analysis functionality.
7 | # parenthese
8 | ( = )
9 | #"bracket"
10 | "[" = ]
11 | # "brace"
12 | { = }
13 | #quote
14 | “ = ”
15 | # chevron
16 | ‹ = ›
17 | #
18 | « = »
19 | [Punctuations]
20 | # defines all punctuations to be used in analysis.
21 | "All" = ()[]{},:.;!?“‹«”›»"'-
22 | # defines punctuations which must be preceded by a space.
23 | "NeedSpaceBefore" = ([{?!:;“‹«
24 | # defines punctuations which must be followed by a space.
25 | "NeedSpaceAfter" = )]}?!,.:;”›»
26 | # defines punctuations which must not be preceded by space.
27 | "NoSpaceBefore" = )]}.,”›»
28 | # defines punctuations which must not be followed by a space.
29 | "NoSpaceAfter" = ([{“‹«
30 |
--------------------------------------------------------------------------------
/addon/locale/tr/textAnalysis.ini:
--------------------------------------------------------------------------------
1 | # to define the decimal symbol separator (3,414)
2 | decimalSymbol = ,
3 | # to define the digit grouping symbol separator (1.212.333)
4 | digitGroupingSymbol = .
5 | [SymbolToSymetric]
6 | # this section defines the symbols and symetric symbols used by the mismatch analysis functionality.
7 | # parenthese
8 | ( = )
9 | #"bracket"
10 | "[" = ]
11 | # "brace"
12 | { = }
13 | #quote
14 | “ = ”
15 | # chevron
16 | ‹ = ›
17 | #
18 | « = »
19 | [Punctuations]
20 | # defines all punctuations to be used in analysis.
21 | "All" = ()[]{},:.;!?“‹«”›»"'-—
22 | # defines punctuations which must be preceded by a space.
23 | "NeedSpaceBefore" = ([{“‹«
24 | # defines punctuations which must be followed by a space.
25 | "NeedSpaceAfter" = )]}?!,.:;”›»
26 | # defines punctuations which must not be preceded by space.
27 | "NoSpaceBefore" = )]}?!.:;,”›»—
28 | # defines punctuations which must not be followed by a space.
29 | "NoSpaceAfter" = ([{“‹«—
30 |
--------------------------------------------------------------------------------
/addon/locale/cs/textAnalysis.ini:
--------------------------------------------------------------------------------
1 | # to define the decimal symbol separator (3,414)
2 | decimalSymbol = .
3 | # to define the digit grouping symbol separator (1.212.333)
4 | digitGroupingSymbol = ,
5 | [SymbolToSymetric]
6 | # this section defines the symbols and symetric symbols used by the mismatch analysis functionality.
7 | # parenthese
8 | ( = )
9 | #"bracket"
10 | "[" = ]
11 | # "brace"
12 | { = }
13 | #quote
14 | “ = ”
15 | # chevron
16 | ‹ = ›
17 | #
18 | « = »
19 | [Punctuations]
20 | # defines all punctuations to be used in analysis.
21 | "All" = ()[]{},:.;!?“‹«”›»"'-—
22 | # defines punctuations which must be preceded by a space.
23 | "NeedSpaceBefore" = ([{“‹«-
24 | # defines punctuations which must be followed by a space.
25 | "NeedSpaceAfter" = )]}?!,.:;”›»-
26 | # defines punctuations which must not be preceded by space.
27 | "NoSpaceBefore" = )]}?!.:;,”›»—
28 | # defines punctuations which must not be followed by a space.
29 | "NoSpaceAfter" = ([{“‹«—
30 |
--------------------------------------------------------------------------------
/addon/locale/en/textAnalysis.ini:
--------------------------------------------------------------------------------
1 | # to define the decimal symbol separator (3,414)
2 | decimalSymbol = .
3 | # to define the digit grouping symbol separator (1.212.333)
4 | digitGroupingSymbol = ,
5 | [SymbolToSymetric]
6 | # this section defines the symbols and symetric symbols used by the mismatch analysis functionality.
7 | # parenthese
8 | ( = )
9 | #"bracket"
10 | "[" = ]
11 | # "brace"
12 | { = }
13 | #quote
14 | “ = ”
15 | # chevron
16 | ‹ = ›
17 | #
18 | « = »
19 | [Punctuations]
20 | # defines all punctuations to be used in analysis.
21 | "All" = ()[]{},:.;!?“‹«”›»"'-—
22 | # defines punctuations which must be preceded by a space.
23 | "NeedSpaceBefore" = ([{“‹«-
24 | # defines punctuations which must be followed by a space.
25 | "NeedSpaceAfter" = )]}?!,.:;”›»-
26 | # defines punctuations which must not be preceded by space.
27 | "NoSpaceBefore" = )]}?!.:;,”›»—
28 | # defines punctuations which must not be followed by a space.
29 | "NoSpaceAfter" = ([{“‹«—
30 |
--------------------------------------------------------------------------------
/addon/locale/sk/textAnalysis.ini:
--------------------------------------------------------------------------------
1 | # to define the decimal symbol separator (3,414)
2 | decimalSymbol = .
3 | # to define the digit grouping symbol separator (1.212.333)
4 | digitGroupingSymbol = ,
5 | [SymbolToSymetric]
6 | # this section defines the symbols and symetric symbols used by the mismatch analysis functionality.
7 | # parenthese
8 | ( = )
9 | #"bracket"
10 | "[" = ]
11 | # "brace"
12 | { = }
13 | #quote
14 | “ = ”
15 | # chevron
16 | ‹ = ›
17 | #
18 | « = »
19 | [Punctuations]
20 | # defines all punctuations to be used in analysis.
21 | "All" = ()[]{},:.;!?“‹«”›»"'-—
22 | # defines punctuations which must be preceded by a space.
23 | "NeedSpaceBefore" = ([{“‹«-
24 | # defines punctuations which must be followed by a space.
25 | "NeedSpaceAfter" = )]}?!,.:;”›»-
26 | # defines punctuations which must not be preceded by space.
27 | "NoSpaceBefore" = )]}?!.:;,”›»—
28 | # defines punctuations which must not be followed by a space.
29 | "NoSpaceAfter" = ([{“‹«—
30 |
--------------------------------------------------------------------------------
/addon/doc/addon_global.t2tconf:
--------------------------------------------------------------------------------
1 | % NOTHING TO TRANSLATE
2 | % -----
3 | %!Target: html
4 | %!Encoding: UTF-8
5 | % Remove the Table of Contents heading from the toc.
6 | %!PostProc(html): '^.*\
\.*\.*$' ''
7 | % h1 in html should really be the document title only.
8 | % Therefore, change h1 through h5 in the output to h2 through h6.
9 | %!PostProc(html): ^(.*)
$ \1
10 | %!PostProc(html): ^(.*)
$ \1
11 | %!PostProc(html): ^(.*)
$ \1
12 | %!PostProc(html): ^(.*)
$ \1
13 | %!PostProc(html): ^(.*)
$ \1
14 | % Some of our files contain the UTF-8 BOM.
15 | % txt2tags doesn't care about encodings internally,
16 | % so it will just include the BOM at the start of the title.
17 | % Therefore, strip the BOM from the title.
18 | %!PostProc(html): \<(TITLE|H1)\>\xef\xbb\xbf <\1>
19 |
20 | %!PostProc (html): ADDON_AUTHOR_NAME paulber19 (paulber19@laposte.net)
21 | %!PreProc (html): ADDON_AUTHOR_URL paulber19@laposte.net
22 | %!includeconf: addon_build.t2tconf
--------------------------------------------------------------------------------
/addon/locale/pt_BR/keyboard.ini:
--------------------------------------------------------------------------------
1 | [KeyboardKeys]
2 | # Esta seção define os caracteres das teclas do teclado a serem usados no diálogo de anúncio seletivo de comandos por tecla.
3 | # Tenha cuidado: deve ser o caractere dito pelo NVDA quando a ajuda de entrada está ativada.
4 | # Por exemplo, as teclas de um teclado US (desktop) são:
5 | # linha 1: ` 1 2 3 4 5 6 7 8 9 0 - =
6 | # linha 2: q w e r t y u i o p [ ]
7 | # linha 3: a s d f g h j k l ; ' \
8 | # linha 4: z x c v b n m , . /
9 | # Define a ordem das teclas no diálogo.
10 | keys = `1234567890-=qwertyuiop[]asdfghjkl;'\\zxcvbnm,./
11 |
12 | [editionKeyCommands]
13 | [[default]]
14 | # Esta seção define os comandos de edição padrão do sistema Windows.
15 | copy = control+c
16 | cut = control+x
17 | paste = control+v
18 | undo = control+z
19 | selectAll = control+a
20 |
21 | [[notepad]]
22 | # Esta seção define os comandos de edição do aplicativo Bloco de Notas, quando diferentes dos padrões do sistema.
23 | selectAll = control+a
24 |
25 | [[thunderbird]]
26 | # Esta seção define os comandos de edição do aplicativo Thunderbird, quando diferentes dos padrões do sistema.
27 | selectAll = control+a
28 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/speech/commands.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\speech\commands.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2024 paulber19
4 | # This file is covered by the GNU General Public License.
5 |
6 | import addonHandler
7 | # from logHandler import log
8 | import time
9 | import speech.commands
10 |
11 | addonHandler.initTranslation()
12 |
13 |
14 | class BeepWithPauseCommand(speech.commands.BaseCallbackCommand):
15 | """Produce a beep followed by a pause."""
16 |
17 | def __init__(self, hz, length, left=50, right=50):
18 | self.hz = hz
19 | self.length = length
20 | self.left = left
21 | self.right = right
22 |
23 | def run(self):
24 | import tones
25 |
26 | tones.beep(
27 | self.hz,
28 | self.length,
29 | left=self.left,
30 | right=self.right,
31 | isSpeechBeepCommand=True,
32 | )
33 | time.sleep(2 * self.length / 1000)
34 |
35 | def __repr__(self):
36 | return "BeepCommand({hz}, {length}, left={left}, right={right})".format(
37 | hz=self.hz,
38 | length=self.length,
39 | left=self.left,
40 | right=self.right,
41 | )
42 |
--------------------------------------------------------------------------------
/addon/locale/cs/keyboard.ini:
--------------------------------------------------------------------------------
1 | # this file must be recorded in utf-8 without BOM.
2 | [KeyboardKeys]
3 | # this section defines the characters of keyboard keys to be used in key command selective announcement dialog and can be used in a gesture.
4 | # becarefull: it must be the character said by NVDA in input help on.
5 | # for exemple, the keys of a desktop US keyboard are:
6 | # row 1: ` 1 2 3 4 5 6 7 8 9 0 - =
7 | # row 2:q w e r t y u i o p [ ]
8 | # row 3: a s d f g h j k l ; ' \
9 | # row 4: \ z x c v b n m , . /
10 | # defines the order of the keys in the dialog.
11 | keys = "abcdefghijklmnopqrstuvwxyz0123456789`-=[];'\,./"
12 | [editionKeyCommands]
13 | [[default]]
14 | # this section defines the edition keyboard commands of Windows system
15 | copy = control+c
16 | cut = control+x
17 | paste = control+v
18 | undo = control+z
19 | selectAll = control+a
20 | # this section defines the edition keyboard for specific application
21 | # for example and for notepad.exe:
22 | # [[notepad]]
23 | # this section defines only the edition keyboard commands of notepad application which different from windows commands
24 | # selectAll = control+q
25 |
--------------------------------------------------------------------------------
/addon/locale/en/keyboard.ini:
--------------------------------------------------------------------------------
1 | # this file must be recorded in utf-8 without BOM.
2 | [KeyboardKeys]
3 | # this section defines the characters of keyboard keys to be used in key command selective announcement dialog and can be used in a gesture.
4 | # becarefull: it must be the character said by NVDA in input help on.
5 | # for exemple, the keys of a desktop US keyboard are:
6 | # row 1: ` 1 2 3 4 5 6 7 8 9 0 - =
7 | # row 2:q w e r t y u i o p [ ]
8 | # row 3: a s d f g h j k l ; ' \
9 | # row 4: \ z x c v b n m , . /
10 | # defines the order of the keys in the dialog.
11 | keys = "abcdefghijklmnopqrstuvwxyz0123456789`-=[];'\,./"
12 | [editionKeyCommands]
13 | [[default]]
14 | # this section defines the edition keyboard commands of Windows system
15 | copy = control+c
16 | cut = control+x
17 | paste = control+v
18 | undo = control+z
19 | selectAll = control+a
20 | # this section defines the edition keyboard for specific application
21 | # for example and for notepad.exe:
22 | # [[notepad]]
23 | # this section defines only the edition keyboard commands of notepad application which different from windows commands
24 | # selectAll = control+q
25 |
--------------------------------------------------------------------------------
/addon/locale/sk/keyboard.ini:
--------------------------------------------------------------------------------
1 | # this file must be recorded in utf-8 without BOM.
2 | [KeyboardKeys]
3 | # this section defines the characters of keyboard keys to be used in key command selective announcement dialog and can be used in a gesture.
4 | # becarefull: it must be the character said by NVDA in input help on.
5 | # for exemple, the keys of a desktop US keyboard are:
6 | # row 1: ` 1 2 3 4 5 6 7 8 9 0 - =
7 | # row 2:q w e r t y u i o p [ ]
8 | # row 3: a s d f g h j k l ; ' \
9 | # row 4: \ z x c v b n m , . /
10 | # defines the order of the keys in the dialog.
11 | keys = "abcdefghijklmnopqrstuvwxyz0123456789`-=[];'\,./"
12 | [editionKeyCommands]
13 | [[default]]
14 | # this section defines the edition keyboard commands of Windows system
15 | copy = control+c
16 | cut = control+x
17 | paste = control+v
18 | undo = control+z
19 | selectAll = control+a
20 | # this section defines the edition keyboard for specific application
21 | # for example and for notepad.exe:
22 | # [[notepad]]
23 | # this section defines only the edition keyboard commands of notepad application which different from windows commands
24 | # selectAll = control+q
25 |
--------------------------------------------------------------------------------
/addon/locale/pt/keyboard.ini:
--------------------------------------------------------------------------------
1 | [KeyboardKeys]
2 | # this section defines the characters of keyboard keys to be used in key command selective announcement dialog and can be used in a gesture.
3 | # becarefull: it must be the character said by NVDA in input help on.
4 | # for exemple, the keys of a desktop US keyboard are:
5 | # row 1: ` 1 2 3 4 5 6 7 8 9 0 - =
6 | # row 2:q w e r t y u i o p [ ]
7 | # row 3: a s d f g h j k l ; ' \
8 | # row 4: \ z x c v b n m , . /
9 | # defines the order of the keys in the dialog.
10 | keys = abcdefghijklmnopqrstuvwxyz0123456789«+´<,.-~
11 |
12 | [editionKeyCommands]
13 | [[default]]
14 | # this section defines the edition keyboard commands of Windows system
15 | copy = control+c
16 | cut = control+x
17 | paste = control+v
18 | undo = control+z
19 | selectAll = control+t
20 | [[notepad]]
21 | # this section defines only the edition keyboard commands of notePad application which different from windows commands
22 | selectAll = control+a
23 | [[thunderbird]]
24 | # this section defines only the edition keyboard commands of Thunderbird application which different from windows commands
25 | selectAll = control+a
--------------------------------------------------------------------------------
/addon/utilities/pycawEx/pycaw/constants.py:
--------------------------------------------------------------------------------
1 | from enum import Enum, IntEnum
2 |
3 | from comtypes import GUID
4 |
5 | IID_Empty = GUID("{00000000-0000-0000-0000-000000000000}")
6 |
7 | CLSID_MMDeviceEnumerator = GUID("{BCDE0395-E52F-467C-8E3D-C4579291692E}")
8 |
9 |
10 | class ERole(Enum):
11 | eConsole = 0
12 | eMultimedia = 1
13 | eCommunications = 2
14 | ERole_enum_count = 3
15 |
16 |
17 | class EDataFlow(Enum):
18 | eRender = 0
19 | eCapture = 1
20 | eAll = 2
21 | EDataFlow_enum_count = 3
22 |
23 |
24 | class DEVICE_STATE(Enum):
25 | ACTIVE = 0x00000001
26 | DISABLED = 0x00000002
27 | NOTPRESENT = 0x00000004
28 | UNPLUGGED = 0x00000008
29 | MASK_ALL = 0x0000000F
30 |
31 |
32 | class AudioDeviceState(Enum):
33 | Active = 0x1
34 | Disabled = 0x2
35 | NotPresent = 0x4
36 | Unplugged = 0x8
37 |
38 |
39 | class STGM(Enum):
40 | STGM_READ = 0x00000000
41 |
42 |
43 | class AUDCLNT_SHAREMODE(Enum):
44 | AUDCLNT_SHAREMODE_SHARED = 0x00000001
45 | AUDCLNT_SHAREMODE_EXCLUSIVE = 0x00000002
46 |
47 |
48 | class AudioSessionState(IntEnum):
49 | # IntEnum to make instances comparable.
50 | Inactive = 0
51 | Active = 1
52 | Expired = 2
53 |
--------------------------------------------------------------------------------
/addon/utilities/markdownEx/markdown/extensions/nl2br.py:
--------------------------------------------------------------------------------
1 | # `NL2BR` Extension
2 | # ===============
3 |
4 | # A Python-Markdown extension to treat newlines as hard breaks; like
5 | # GitHub-flavored Markdown does.
6 |
7 | # See https://Python-Markdown.github.io/extensions/nl2br
8 | # for documentation.
9 |
10 | # Original code Copyright 2011 [Brian Neal](https://deathofagremmie.com/)
11 |
12 | # All changes Copyright 2011-2014 The Python Markdown Project
13 |
14 | # License: [BSD](https://opensource.org/licenses/bsd-license.php)
15 |
16 | """
17 | A Python-Markdown extension to treat newlines as hard breaks; like
18 | GitHub-flavored Markdown does.
19 |
20 | See the [documentation](https://Python-Markdown.github.io/extensions/nl2br)
21 | for details.
22 | """
23 |
24 | from __future__ import annotations
25 |
26 | from . import Extension
27 | from ..inlinepatterns import SubstituteTagInlineProcessor
28 |
29 | BR_RE = r'\n'
30 |
31 |
32 | class Nl2BrExtension(Extension):
33 |
34 | def extendMarkdown(self, md):
35 | """ Add a `SubstituteTagInlineProcessor` to Markdown. """
36 | br_tag = SubstituteTagInlineProcessor(BR_RE, 'br')
37 | md.inlinePatterns.register(br_tag, 'nl', 5)
38 |
39 |
40 | def makeExtension(**kwargs): # pragma: no cover
41 | return Nl2BrExtension(**kwargs)
42 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/computerTools/tonesPatches.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\computerTools\tonesPatches.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2024-2025 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 |
8 | from logHandler import log
9 | import tones
10 | from .beep import myBeep
11 |
12 | # global variable to save nvda patched method
13 | _NVDATonesBeep = None
14 |
15 |
16 | def initialize():
17 | from .audioUtils import isWasapiUsed
18 | if isWasapiUsed():
19 | return
20 | # patche tones.beep
21 | global _NVDATonesBeep
22 | if _NVDATonesBeep is not None:
23 | return
24 | _NVDATonesBeep = tones.beep
25 | if tones.beep.__module__ != "tones":
26 | log.warning(
27 | "Incompatibility: tones.beep method has also been patched probably by another add-on: %s. "
28 | "There is a risk of malfunction" % tones.beep.__module__)
29 | tones.beep = myBeep
30 | log.debug(
31 | "To allow NVDA tones volume adjustment, tones.beep function has been patched by %s function of %s module"
32 | % (tones.beep .__name__, tones.beep .__module__))
33 |
34 |
35 | def terminate():
36 | global _NVDATonesBeep
37 | if _NVDATonesBeep is not None:
38 | tones.beep = _NVDATonesBeep
39 | _NVDATonesBeep = None
40 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/extendedNetUIHWND/__init__.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\ComplexSymbols\__init__
2 | # A part of NvDAextensionGlobalPlugin
3 | # Copyright (C) 2016 - 2022 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 | import NVDAObjects
8 | import config
9 |
10 |
11 | class ExtendedNetUIHWND (NVDAObjects.NVDAObject):
12 | def event_focusEntered(self):
13 | oldPresentationReportObjectDescriptions = config.conf["presentation"]["reportObjectDescriptions"]
14 | config.conf["presentation"]["reportObjectDescriptions"] = False
15 | super(ExtendedNetUIHWND, self).event_focusEntered()
16 | config.conf["presentation"]["reportObjectDescriptions"] = oldPresentationReportObjectDescriptions
17 |
18 | def event_gainFocus(self):
19 | oldPresentationReportObjectDescriptions = config.conf["presentation"]["reportObjectDescriptions"]
20 | config.conf["presentation"]["reportObjectDescriptions"] = False
21 | super(ExtendedNetUIHWND, self).event_gainFocus()
22 | config.conf["presentation"]["reportObjectDescriptions"] = oldPresentationReportObjectDescriptions
23 |
24 |
25 | def chooseNVDAObjectOverlayClasses(obj, clsList):
26 | if (
27 | hasattr(obj, "windowClassName")
28 | and obj.windowClassName == "NetUIHWND"
29 | ):
30 | clsList.insert(0, ExtendedNetUIHWND)
31 |
--------------------------------------------------------------------------------
/addon/doc/addon_build.t2tconf:
--------------------------------------------------------------------------------
1 | % NOTHING TO TRANSLATE
2 | % -----
3 | % download
4 | %%!PreProc:ADDON_DOWNLOAD_SERVER1 https://github.com/paulber007/AllMyNVDAAddons/raw/master/wordAccessEnhancement/ADDON_NAME-ADDON_VERSION.nvda-addon
5 | %%!PreProc:ADDON_DOWNLOAD_PREVIOUS https://github.com/paulber007/AllMyNVDAAddons/raw/master/wordAccessEnhancement/ADDON_NAME-ADDON_VERSION.nvda-addon
6 | %!PreProc:ADDON_DOWNLOAD_SERVER1 AllMyNVDAAddons_REPOSITORY_URL/raw/master/ADDON_NAME/ADDON_NAME-ADDON_CUR_VERSION.nvda-addon
7 | %!PreProc:ADDON_DOWNLOAD_PREVIOUS AllMyNVDAAddons_REPOSITORY_URL/raw/master/ADDON_NAME/ADDON_NAME-ADDON_PREV_VERSION.nvda-addon
8 | %!PreProc: ADDON_DEV_URL AllMyNVDAAddons_REPOSITORY_URL/tree/master/ADDON_NAME/dev
9 | %!PostProc: AllMyNVDAAddons_REPOSITORY_URL https://github.com/paulber007/AllMyNVDAAddons
10 | % addon repository
11 | %!PreProc: ADDON_REPOSITORY PAULBER19_REPOSITORY_URL/ADDON_REPOSITORY_NAME.git
12 | %!PostProc: PAULBER19_REPOSITORY_URL https://github.com/paulber19
13 | % specific add-on informations
14 | %!PostProc: ADDON_NAME NVDAExtensionGlobalPlugin
15 | %!PostProc: ADDON_REPOSITORY_NAME NVDAExtensionGlobalPlugin
16 | % current stable version
17 | %!PostProc (html):ADDON_CUR_VERSION 14.1
18 | %!PostProc (html):MINIMUM_NVDA_VERSION 2024.1
19 | %!PostProc (html):LAST_TESTED_NVDA_VERSION 2025.3
20 | %previous stable version
21 | %!PostProc (html):ADDON_PREV_VERSION 14.0.6
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/computerTools/bluetoothAudio.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\computerTools\bluetoothAudio.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2023-2024 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 |
8 | import nvwave
9 | import os
10 | import struct
11 | import wave
12 |
13 |
14 | # part of this code comes from the BluetoothAudio addon for NVDA
15 | # Copyright (C) 2018 Tony Malykh
16 |
17 |
18 | def generateBeepBuf(whiteNoiseVolume):
19 | path = os.path.abspath(__file__)
20 | dirPath = os.path.dirname(path)
21 | fileName = os.path.join(dirPath, "waves", "white_noise_10s.wav")
22 | f = wave.open(fileName, "r")
23 | if f is None:
24 | raise RuntimeError()
25 | buf = f.readframes(f.getnframes())
26 | bufSize = len(buf)
27 | n = bufSize // 2
28 | unpacked = struct.unpack(f"<{n}h", buf)
29 | unpacked = list(unpacked)
30 | for i in range(n):
31 | unpacked[i] = int(unpacked[i] * whiteNoiseVolume / 1000)
32 | packed = struct.pack(f"<{n}h", *unpacked)
33 | return packed, f.getframerate()
34 |
35 |
36 | def playWhiteNoise(deviceName):
37 | buf, framerate = generateBeepBuf(1)
38 | player = nvwave.WavePlayer(
39 | channels=2, samplesPerSec=framerate, bitsPerSample=16, outputDevice=deviceName, wantDucking=False)
40 | player.feed(buf)
41 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/browseModeEx/UIAParagraph.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\browseModeEx\UIAParagraph.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2018 - 2023 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 | import browseMode
8 | import textInfos
9 | from UIAHandler import UIA_StyleIdAttributeId, StyleId_Normal
10 | from UIAHandler.utils import getUIATextAttributeValueFromRange
11 |
12 |
13 | def UIAParagraphQuicknavIterator(document, position, direction="next"):
14 | if position:
15 | curPosition = position
16 | else:
17 | curPosition = document.makeTextInfo(
18 | textInfos.POSITION_LAST if direction == "previous"
19 | else textInfos.POSITION_FIRST)
20 | stop = False
21 | firstLoop = True
22 | while not stop:
23 | tempInfo = curPosition.copy()
24 | tempInfo.expand(textInfos.UNIT_CHARACTER)
25 | styleIDValue = getUIATextAttributeValueFromRange(
26 | tempInfo._rangeObj, UIA_StyleIdAttributeId)
27 | if styleIDValue == StyleId_Normal:
28 | if not firstLoop or not position:
29 | tempInfo.expand(textInfos.UNIT_PARAGRAPH)
30 | yield browseMode.TextInfoQuickNavItem("paragraph", document, tempInfo)
31 | stop = (curPosition.move(
32 | textInfos.UNIT_PARAGRAPH,
33 | 1 if direction == "next" else -1) == 0)
34 | firstLoop = False
35 |
--------------------------------------------------------------------------------
/addon/doc/style_t2t.css:
--------------------------------------------------------------------------------
1 | @charset "utf-8";
2 | body {
3 | margin : 0 5% 0 5%;
4 | font-family : Verdana, Arial, Helvetica, Sans-serif;
5 | font-size: 0.9em;
6 | background-color : #dce4ed;
7 | }
8 | h1 {
9 | margin-bottom:1.65em;
10 | text-align: center;
11 | font-size: 1.9em;
12 | color : #cc0000;
13 | text-decoration : underline;}
14 | h2 {
15 | margin : 1.4em 0 1.4em 0;
16 | text-align: left;
17 | font-weight: bold;
18 | font-size: 1.15em;
19 | text-indent:20px;
20 | padding-top:0.3em;
21 | padding-bottom:0.3em;
22 | background-color : #cccccc;
23 | color : #0c419a;}
24 |
25 | h3 {
26 | font-family: Verdana,Arial,Helvetica,sans-serif;
27 | font-size: 1.05em;
28 | font-weight: bold;
29 | text-align: left;
30 | color: #000066;
31 | margin-left: 40px;
32 | }
33 |
34 | h4 {
35 | list-style-type: none;
36 | font-size: 1em;
37 | list-style-position: outside;
38 | font-family: Verdana,Arial,Helvetica,sans-serif;
39 | text-indent: 100px;
40 | margin-top: 1em;
41 | margin-bottom: 1em;
42 | }
43 |
44 | dt {
45 | font-weight : bold;
46 | float : left;
47 | width: 10%;
48 | clear: left
49 | }
50 | dd {
51 | margin : 0 0 0.4em 0;
52 | float : left;
53 | width: 90%;
54 | display: block;
55 | }
56 | p { clear : both;
57 | font-size: 0.9em;
58 | }
59 | li {font-size: 0.9em;}
60 | a { text-decoration : none;
61 | font-weight : bold;
62 | }
63 | :active {
64 | text-decoration : none;
65 | }
66 | a:focus, a:hover {color: red}
67 | :link {color: rgb(110,110,110)}
68 |
--------------------------------------------------------------------------------
/addon/utilities/pycawEx/pycaw/pycaw.py:
--------------------------------------------------------------------------------
1 | """
2 | Python wrapper around the Core Audio Windows API.
3 | """
4 |
5 | # import here all newly split up modules,
6 | # to keep backwards compatibility
7 |
8 | # flake8: noqa
9 | # yes, the imports are unused
10 |
11 | from pycaw.api.audioclient import IAudioClient, ISimpleAudioVolume
12 | from pycaw.api.audioclient.depend import WAVEFORMATEX
13 | from pycaw.api.audiopolicy import (
14 | IAudioSessionControl,
15 | IAudioSessionControl2,
16 | IAudioSessionEnumerator,
17 | IAudioSessionEvents,
18 | IAudioSessionManager,
19 | IAudioSessionManager2,
20 | IAudioSessionNotification,
21 | IAudioVolumeDuckNotification,
22 | )
23 | from pycaw.api.endpointvolume import (
24 | IAudioEndpointVolume,
25 | IAudioEndpointVolumeCallback,
26 | IAudioMeterInformation,
27 | )
28 | from pycaw.api.endpointvolume.depend import (
29 | AUDIO_VOLUME_NOTIFICATION_DATA,
30 | PAUDIO_VOLUME_NOTIFICATION_DATA,
31 | )
32 | from pycaw.api.mmdeviceapi import (
33 | IMMDevice,
34 | IMMDeviceCollection,
35 | IMMDeviceEnumerator,
36 | IMMEndpoint,
37 | IMMNotificationClient,
38 | )
39 | from pycaw.api.mmdeviceapi.depend import IPropertyStore
40 | from pycaw.api.mmdeviceapi.depend.structures import (
41 | PROPERTYKEY,
42 | PROPVARIANT,
43 | PROPVARIANT_UNION,
44 | )
45 | from pycaw.constants import (
46 | AUDCLNT_SHAREMODE,
47 | DEVICE_STATE,
48 | STGM,
49 | AudioDeviceState,
50 | EDataFlow,
51 | ERole,
52 | )
53 | from pycaw.utils import AudioDevice, AudioSession, AudioUtilities
54 |
--------------------------------------------------------------------------------
/howToTranslate.txt:
--------------------------------------------------------------------------------
1 | 1 - Create the "xx" folder of localization for the language in the "doc" and "locale" folders.
2 | 2 - Translation of the source code:
3 | You can use the "nvda.pot" catalog file which is located in the "locale/en" folder.
4 | Place the "nvda.po" and" nvda.mo" files in the "locale/xx/LC_MESSAGES" folder (to create).
5 |
6 | 3Creation of locale manifest.ini
7 | From main manifest.ini, translate "summary" and "description" variables and put these variables in an manifest.ini file (utf-8 coding).
8 | place this file in "locale/xx" folder.
9 |
10 | 4 - Translation of the documentation of the module:
11 | This documentation is if french language.
12 | - translate the "addon_informations.t2tconf", "addon_keys.t2tconf", "addonUserManual.t2t", "change.t2t" files. These files are located in "doc\fr" folder.
13 | - Place the translated files into the "doc/xx" folder,
14 | Translate the "readme.md" file located in "doc\en" folder and place it into "doc/xx" folder,
15 | - convert to html these files by using the add-on developpement tools dialog of the module("NVDA+j" followed by "t").
16 |
17 |
18 | 5- Adapte the "keyboard.ini" to your keyboard and "symbolCategories.dic" files of "locale/en" folder (encoding in utf-8).
19 | Place thise files in the "locale/xx" folder.
20 | Map these files depending on the language.
21 |
22 | 6 - Adapte the "symbols-en.dic"file of the "newSymbols"folder.and name the translated file "symbols-xx.dic".
23 | Add symbols which are added in the file "locale/xx/symbolCategories.dic" and not supported vocally by NVDA for your language.
--------------------------------------------------------------------------------
/addon/utilities/pycawEx/pycaw/api/mmdeviceapi/depend/__init__.py:
--------------------------------------------------------------------------------
1 | from ctypes import HRESULT, POINTER
2 | from ctypes.wintypes import DWORD
3 |
4 | from comtypes import COMMETHOD, GUID, IUnknown
5 |
6 | from .structures import PROPERTYKEY, PROPVARIANT
7 |
8 |
9 | class IPropertyStore(IUnknown):
10 | _iid_ = GUID("{886d8eeb-8cf2-4446-8d02-cdba1dbdcf99}")
11 | _methods_ = (
12 | # HRESULT GetCount([out] DWORD *cProps);
13 | COMMETHOD([], HRESULT, "GetCount", (["out"], POINTER(DWORD), "cProps")),
14 | # HRESULT GetAt(
15 | # [in] DWORD iProp,
16 | # [out] PROPERTYKEY *pkey);
17 | COMMETHOD(
18 | [],
19 | HRESULT,
20 | "GetAt",
21 | (["in"], DWORD, "iProp"),
22 | (["out"], POINTER(PROPERTYKEY), "pkey"),
23 | ),
24 | # HRESULT GetValue(
25 | # [in] REFPROPERTYKEY key,
26 | # [out] PROPVARIANT *pv);
27 | COMMETHOD(
28 | [],
29 | HRESULT,
30 | "GetValue",
31 | (["in"], POINTER(PROPERTYKEY), "key"),
32 | (["out"], POINTER(PROPVARIANT), "pv"),
33 | ),
34 | # HRESULT SetValue(
35 | # [in] REFPROPERTYKEY key,
36 | # [in] REFPROPVARIANT propvar
37 | # );
38 | COMMETHOD(
39 | [],
40 | HRESULT,
41 | "SetValue",
42 | (["in"], POINTER(PROPERTYKEY), "key"),
43 | (["in"], POINTER(PROPVARIANT), "propvar"),
44 | ),
45 | # HRESULT Commit();
46 | COMMETHOD([], HRESULT, "Commit"),
47 | )
48 |
--------------------------------------------------------------------------------
/style.css:
--------------------------------------------------------------------------------
1 | @charset "utf-8";
2 | body {
3 | margin : 0 5% 0 5%;
4 | font-family : Verdana, Arial, Helvetica, Sans-serif;
5 | font-size: 0.9em;
6 | background-color : #dce4ed;
7 | counter-reset: h1
8 | }
9 |
10 | h1 {
11 | margin-bottom:1.65em;
12 | text-align: center;
13 | font-size: 1.9em;
14 | color : #cc0000;
15 | text-decoration : underline;
16 | counter-reset: h2
17 | }
18 |
19 | h2 {
20 | margin : 1.4em 0 1.4em 0;
21 | text-align: left;
22 | font-weight: bold;
23 | font-size: 1.15em;
24 | text-indent:20px;
25 | padding-top:0.15em;
26 | padding-bottom:0.3em;
27 | background-color : #cccccc;
28 | color : #0c419a;
29 | counter-reset: h3
30 | }
31 |
32 | h3 {
33 | font-size: 0.95em;
34 | text-indent:70px;
35 | color : #0c419a;
36 | counter-reset: h4
37 | }
38 |
39 |
40 | h2:before {
41 | counter-increment: h2;
42 | content: counter(h2) ". "
43 | }
44 |
45 | h3:before {
46 | counter-increment: h3;
47 | content: counter(h2) "." counter(h3) ". "
48 | }
49 |
50 | h4:before {
51 | counter-increment: h4;
52 | content: counter(h2) "." counter(h3) "." counter(h4) ". "
53 | }
54 |
55 | dt {
56 | font-weight : bold;
57 | float : left;
58 | width: 10%;
59 | clear: left
60 | }
61 | dd {
62 | margin : 0 0 0.4em 0;
63 | float : left;
64 | width: 90%;
65 | display: block;
66 | }
67 | p {
68 | clear : both;
69 | font-size: 0.9em;
70 | }
71 | li {
72 | font-size: 0.9em;
73 | }
74 | a {
75 | text-decoration : none;
76 | font-weight : bold;
77 | }
78 | :active {
79 | text-decoration : none;
80 | }
81 | a:focus, a:hover {color: red)}
82 | :link {color: rgb(110,110,110)}
--------------------------------------------------------------------------------
/addon/doc/style.css:
--------------------------------------------------------------------------------
1 | @charset "utf-8";
2 | body {
3 | margin : 0 5% 0 5%;
4 | font-family : Verdana, Arial, Helvetica, Sans-serif;
5 | font-size: 0.9em;
6 | background-color : #dce4ed;
7 | counter-reset: h1
8 | }
9 |
10 | h1 {
11 | margin-bottom:1.65em;
12 | text-align: center;
13 | font-size: 1.9em;
14 | color : #cc0000;
15 | text-decoration : underline;
16 | counter-reset: h2
17 | }
18 |
19 | h2 {
20 | margin : 1.4em 0 1.4em 0;
21 | text-align: left;
22 | font-weight: bold;
23 | font-size: 1.15em;
24 | text-indent:20px;
25 | padding-top:0.15em;
26 | padding-bottom:0.3em;
27 | background-color : #cccccc;
28 | color : #0c419a;
29 | counter-reset: h3
30 | }
31 |
32 | h3 {
33 | font-size: 0.95em;
34 | text-indent:70px;
35 | color : #0c419a;
36 | counter-reset: h4
37 | }
38 |
39 |
40 | h2:before {
41 | counter-increment: h2;
42 | content: counter(h2) ". "
43 | }
44 |
45 | h3:before {
46 | counter-increment: h3;
47 | content: counter(h2) "." counter(h3) ". "
48 | }
49 |
50 | h4:before {
51 | counter-increment: h4;
52 | content: counter(h2) "." counter(h3) "." counter(h4) ". "
53 | }
54 |
55 | dt {
56 | font-weight : bold;
57 | float : left;
58 | width: 10%;
59 | clear: left
60 | }
61 | dd {
62 | margin : 0 0 0.4em 0;
63 | float : left;
64 | width: 90%;
65 | display: block;
66 | }
67 | p {
68 | clear : both;
69 | font-size: 0.9em;
70 | }
71 | li {
72 | font-size: 0.9em;
73 | }
74 | a {
75 | text-decoration : none;
76 | font-weight : bold;
77 | }
78 | :active {
79 | text-decoration : none;
80 | }
81 | a:focus, a:hover {color: red)}
82 | :link {color: rgb(110,110,110)}
--------------------------------------------------------------------------------
/addon/utilities/win32Ex/license.txt:
--------------------------------------------------------------------------------
1 | Unless stated in the specfic source file, this work is
2 | Copyright (c) 1994-2008, Mark Hammond
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions
7 | are met:
8 |
9 | Redistributions of source code must retain the above copyright notice,
10 | this list of conditions and the following disclaimer.
11 |
12 | Redistributions in binary form must reproduce the above copyright
13 | notice, this list of conditions and the following disclaimer in
14 | the documentation and/or other materials provided with the distribution.
15 |
16 | Neither name of Mark Hammond nor the name of contributors may be used
17 | to endorse or promote products derived from this software without
18 | specific prior written permission.
19 |
20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
21 | IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 | PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
24 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 |
--------------------------------------------------------------------------------
/addon/utilities/pycawEx/pycaw/api/mmdeviceapi/depend/structures.py:
--------------------------------------------------------------------------------
1 | from ctypes import Structure, Union, byref, windll
2 | from ctypes.wintypes import DWORD, LONG, LPWSTR, ULARGE_INTEGER, VARIANT_BOOL, WORD
3 |
4 | from comtypes import GUID
5 | from comtypes.automation import VARTYPE, VT_BOOL, VT_CLSID, VT_LPWSTR, VT_UI4
6 |
7 |
8 | class PROPVARIANT_UNION(Union):
9 | _fields_ = [
10 | ("lVal", LONG),
11 | ("uhVal", ULARGE_INTEGER),
12 | ("boolVal", VARIANT_BOOL),
13 | ("pwszVal", LPWSTR),
14 | ("puuid", GUID),
15 | ]
16 |
17 |
18 | class PROPVARIANT(Structure):
19 | _fields_ = [
20 | ("vt", VARTYPE),
21 | ("reserved1", WORD),
22 | ("reserved2", WORD),
23 | ("reserved3", WORD),
24 | ("union", PROPVARIANT_UNION),
25 | ]
26 |
27 | def GetValue(self):
28 | vt = self.vt
29 | if vt == VT_BOOL:
30 | return self.union.boolVal != 0
31 | elif vt == VT_LPWSTR:
32 | # return Marshal.PtrToStringUni(union.pwszVal)
33 | return self.union.pwszVal
34 | elif vt == VT_UI4:
35 | return self.union.lVal
36 | elif vt == VT_CLSID:
37 | # TODO
38 | # return (Guid)Marshal.PtrToStructure(union.puuid, typeof(Guid))
39 | return
40 | else:
41 | return "%s:?" % (vt)
42 |
43 | def clear(self):
44 | windll.ole32.PropVariantClear(byref(self))
45 |
46 |
47 | class PROPERTYKEY(Structure):
48 | _fields_ = [
49 | ("fmtid", GUID),
50 | ("pid", DWORD),
51 | ]
52 |
53 | def __str__(self):
54 | return "%s %s" % (self.fmtid, self.pid)
55 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/computerTools/__init__.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\computerTools\__init__.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2024 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 | from logHandler import log
8 |
9 |
10 | def initialize():
11 | log.debug("computerTools initialization")
12 | # for tonalities volume changes
13 | from ..settings import toggleAllowNVDATonesVolumeAdjustmentAdvancedOption
14 | if toggleAllowNVDATonesVolumeAdjustmentAdvancedOption(False):
15 | from . import tonesPatches
16 | tonesPatches.initialize()
17 | from . import temporaryOutputDevicePatches
18 | temporaryOutputDevicePatches.patche()
19 | from . import audioCore
20 | audioCore.initialize()
21 | """
22 | try:
23 | # for nvda version > 2024.2
24 | splitAudioMode = config.conf["audio"]["soundSplitState"]
25 | except Exception:
26 | splitAudioMode = 0
27 | from ..settings import getInstallFeatureOption
28 | from ..settings.addonConfig import (
29 | C_DoNotInstall,
30 | FCT_SplitAudio
31 | )
32 | # if getInstallFeatureOption(FCT_SplitAudio) != C_DoNotInstall and splitAudioMode:
33 | # from .messageDialogs import SplitAudioWarningDialog
34 | # from gui.message import displayDialogAsModal
35 | # wx.CallAfter(displayDialogAsModal, SplitAudioWarningDialog(None))
36 | """
37 |
38 |
39 | def terminate():
40 | from . import audioCore
41 | audioCore.terminate()
42 | from . import tonesPatches
43 | tonesPatches.terminate()
44 | from . import temporaryOutputDevicePatches
45 | temporaryOutputDevicePatches.patche(install=False)
46 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/browseModeEx/__init__.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\browseModeEx\__init__.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2016 - 2023 paulber19
4 | # This file is covered by the GNU General Public License.
5 |
6 |
7 | import NVDAObjects.UIA.spartanEdge as EDGE
8 | import NVDAObjects.IAccessible.MSHTML
9 | import NVDAObjects.IAccessible.mozilla
10 | import NVDAObjects.IAccessible.chromium
11 | import NVDAObjects.UIA.chromium
12 |
13 |
14 | def chooseNVDAObjectOverlayClasses(obj, clsList):
15 | if EDGE.EdgeHTMLRoot in clsList:
16 | from .NVDAObjectsUIA import EdgeHTMLRootEx
17 | clsList[clsList.index(EDGE.EdgeHTMLRoot)] = EdgeHTMLRootEx
18 | return
19 | if NVDAObjects.IAccessible.MSHTML.MSHTML in clsList:
20 | from . import NVDAObjectsIAccessible
21 | clsList[clsList.index(NVDAObjects.IAccessible.MSHTML.MSHTML)] = NVDAObjectsIAccessible.NVDAObjectMSHTMLEx
22 | return
23 | if NVDAObjects.IAccessible.mozilla.Document in clsList:
24 | from . import NVDAObjectsIAccessible
25 | clsList[clsList.index(
26 | NVDAObjects.IAccessible.mozilla.Document)] = NVDAObjectsIAccessible.NVDAObjectMozillaDocumentEx
27 | return
28 | if NVDAObjects.IAccessible.chromium.Document in clsList:
29 | from . import NVDAObjectsIAccessible
30 | clsList[clsList.index(NVDAObjects.IAccessible.chromium.Document)] = NVDAObjectsIAccessible.ChromiumDocument
31 | return
32 | if NVDAObjects.UIA.chromium.ChromiumUIADocument in clsList:
33 | from . import NVDAObjectsUIAChromium
34 | newCls = NVDAObjectsUIAChromium.ChromiumUIADocumentEx
35 | clsList[clsList.index(NVDAObjects.UIA.chromium.ChromiumUIADocument)] = newCls
36 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/tools/generate.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\tools\generate.py
2 | # a part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2016 - 2021 Paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 | import addonHandler
8 | import codecs
9 | import os
10 |
11 | import gettext
12 | addonHandler.initTranslation()
13 |
14 |
15 | def generateManifest(dest, addonInfo, template):
16 | _ = ""
17 | manifest = template.format(**addonInfo)
18 | with codecs.open(dest, "w", "utf-8") as f:
19 | f.write(manifest)
20 |
21 |
22 | def getTranslationsInstance(addon, language, domain='nvda'):
23 | localedir = os.path.join(addon.path, "locale")
24 | return gettext.translation(
25 | domain, localedir=localedir, languages=[language], fallback=True)
26 |
27 |
28 | def getVariablesBetweenBrass(stringToFormat):
29 | vars = []
30 | for s in stringToFormat.split("{"):
31 | if "}" not in s:
32 | continue
33 | vars.append(s.split("}")[0])
34 | return vars
35 |
36 |
37 | def generateTranslatedManifest(addon, addonInfos, language, template):
38 | _ = getTranslationsInstance(addon, language).gettext
39 | vars = {}
40 | translatedVars = {}
41 | allTranslated = True
42 | for var in getVariablesBetweenBrass(template):
43 | vars[var] = addonInfos[var]
44 | translatedVars[var] = _(addonInfos[var])
45 | if translatedVars[var] == vars[var]:
46 | allTranslated = False
47 | result = template.format(**translatedVars)
48 | dest = os.path.join(addon.path, "locale", language, "manifest.ini")
49 | with codecs.open(dest, "w", "utf-8") as f:
50 | f.write(result)
51 | return allTranslated
52 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/updateHandler/__init__.py:
--------------------------------------------------------------------------------
1 | # __init__.py
2 | # common Part of all of my add-ons
3 | # Copyright 2019-2024 Paulber19
4 | # some parts of code comes from others add-ons:
5 | # add-on Updater (author Joseph Lee)
6 | # brailleExtender (author Andre-Abush )
7 |
8 | import addonHandler
9 | import globalVars
10 | import time
11 | import wx
12 | import random
13 | from . import state
14 | state.initialize()
15 | addonHandler.initTranslation()
16 |
17 | # keep current update check timer id.
18 | updateChecker = None
19 |
20 |
21 | def autoUpdateCheck(releaseToDev):
22 | from . update_check import shouldCheckForUpdate
23 | if not shouldCheckForUpdate():
24 | return
25 | # But not when NVDA itself is updating.
26 | if globalVars.appArgs.install or globalVars.appArgs.minimal:
27 | return
28 | currentTime = int(time.time())
29 | lastCheck = state.getLastCheck()
30 | interval = 0 if state.getRemindUpdate() else state.addonUpdateCheckInterval
31 | whenToCheck = lastCheck + interval
32 | if currentTime < whenToCheck:
33 | return
34 | state.setLastCheck()
35 | global updateChecker
36 | if updateChecker is not None:
37 | updateChecker.Stop()
38 | # delay before check update (between 20 and 600 secondes, step = 20 seconds)
39 | r = 20 * random.randint(1, 30)
40 | updateChecker = wx.CallLater(r * 1000, addonUpdateCheck, True, releaseToDev)
41 |
42 |
43 | def addonUpdateCheck(auto, releaseToDev):
44 | global updateChecker
45 | if updateChecker is not None:
46 | updateChecker.Stop()
47 | updateChecker = None
48 | from .update_check import CheckForAddonUpdate
49 | wx.CallAfter(
50 | CheckForAddonUpdate,
51 | updateInfosFile=None,
52 | auto=auto,
53 | releaseToDev=releaseToDev)
54 |
--------------------------------------------------------------------------------
/site_scons/site_tools/gettexttool/__init__.py:
--------------------------------------------------------------------------------
1 | """ This tool allows generation of gettext .mo compiled files, pot files from source code files
2 | and pot files for merging.
3 |
4 | Three new builders are added into the constructed environment:
5 |
6 | - gettextMoFile: generates .mo file from .pot file using msgfmt.
7 | - gettextPotFile: Generates .pot file from source code files.
8 | - gettextMergePotFile: Creates a .pot file appropriate for merging into existing .po files.
9 |
10 | To properly configure get text, define the following variables:
11 |
12 | - gettext_package_bugs_address
13 | - gettext_package_name
14 | - gettext_package_version
15 |
16 |
17 | """
18 | from SCons.Action import Action
19 |
20 | def exists(env):
21 | return True
22 |
23 | XGETTEXT_COMMON_ARGS = (
24 | "--msgid-bugs-address='$gettext_package_bugs_address' "
25 | "--package-name='$gettext_package_name' "
26 | "--package-version='$gettext_package_version' "
27 | "-c -o $TARGET $SOURCES"
28 | )
29 |
30 | def generate(env):
31 | env.SetDefault(gettext_package_bugs_address="example@example.com")
32 | env.SetDefault(gettext_package_name="")
33 | env.SetDefault(gettext_package_version="")
34 |
35 | env['BUILDERS']['gettextMoFile']=env.Builder(
36 | action=Action("msgfmt -o $TARGET $SOURCE", "Compiling translation $SOURCE"),
37 | suffix=".mo",
38 | src_suffix=".po"
39 | )
40 |
41 | env['BUILDERS']['gettextPotFile']=env.Builder(
42 | action=Action("xgettext " + XGETTEXT_COMMON_ARGS, "Generating pot file $TARGET"),
43 | suffix=".pot")
44 |
45 | env['BUILDERS']['gettextMergePotFile']=env.Builder(
46 | action=Action("xgettext " + "--omit-header --no-location " + XGETTEXT_COMMON_ARGS,
47 | "Generating pot file $TARGET"),
48 | suffix=".pot")
49 |
50 |
--------------------------------------------------------------------------------
/addon/doc/styles.css:
--------------------------------------------------------------------------------
1 | body {
2 | margin: 0 auto;
3 | max-width: 50em;
4 | font-family: "Helvetica", "Arial", sans-serif;
5 | line-height: 1.5;
6 | padding: 4em 1em;
7 | color: #333;
8 | }
9 |
10 | :lang(ar) body *, :lang(fa) body * {
11 | font-family: "Simplified Arabic", "Traditional Arabic", "Arial", sans-serif !important;
12 | }
13 |
14 | h1 {
15 | color:white;
16 | background-color: #472F5F; /* NVDA purple */
17 | }
18 |
19 | h2 {
20 | margin-top: 1em;
21 | padding-top: 1em;
22 | }
23 |
24 | h2, h3, h4, a {
25 | color: #472F5F; /* NVDA purple */
26 | }
27 |
28 | strong {
29 | color: #000;
30 | }
31 |
32 | /* tables */
33 | table, td, th {
34 | border:1px solid black;
35 | }
36 | table{
37 | border-collapse: collapse;
38 | }
39 | td, th {
40 | padding: 0.25em;
41 | }
42 | th {
43 | color: #472F5F; /* NVDA purple */
44 | }
45 |
46 | /* code / pre */
47 | code,
48 | pre {
49 | background: #f6f8fa;
50 | border-bottom: 1px solid #d8dee9;
51 | color: #33104e;
52 | }
53 |
54 | code {
55 | padding: 2px 4px;
56 | vertical-align: text-bottom;
57 | }
58 | pre {
59 | padding: 1em;
60 | border-left: 2px solid #69c;
61 | }
62 |
63 | /*
64 | Definition list
65 |
66 | Note these are not exposed correctly in NVDA: #3858
67 | */
68 | dl {
69 | display: grid;
70 | grid-template-columns: auto;
71 | }
72 |
73 | /* Term of a definition */
74 | dl > dt {
75 | grid-column-start: 1;
76 | font-style: italic;
77 | font-weight: bold;
78 | font-size: small;
79 | }
80 |
81 | /* Definition of a term */
82 | dl > dd {
83 | display: inherit;
84 | grid-column-start: 2;
85 | margin-inline-start: 1em;
86 | font-size: small;
87 | font-style: italic;
88 | }
89 |
90 | thead:has(tr > th.hideHeaderRow) {
91 | display: none;
92 | }
93 |
--------------------------------------------------------------------------------
/addon/howToTranslate.txt:
--------------------------------------------------------------------------------
1 | 1 - Create the "xx" folder of localization for the language in the "doc" and "locale" folders.
2 | 2 - Translation of the source code:
3 | You can use the "nvda.pot" catalog file which is located in the "locale/en" folder.
4 | Place the "nvda.po" and" nvda.mo" files in the "locale/xx/LC_MESSAGES" folder (to create).
5 |
6 | 3Creation of locale manifest.ini
7 | From main manifest.ini, translate "summary" and "description" variables and put these variables in an manifest.ini file (utf-8 coding).
8 | place this file in "locale/xx" folder.
9 |
10 | 4 - Translation of the documentation of the module:
11 | This documentation is if french language and automatic translation in english.
12 | - translate the "addon_informations.t2tconf", "addon_keys.t2tconf", "addonUserManual.t2t", "change.t2t" files. These files are located in "doc\fr" folder.
13 | - Place the translated files into the "doc/xx" folder,
14 | The readme.md file in "doc\en" folder should not be translated.
15 |
16 | - convert to html these files by using the add-on developpement tools dialog of the module("NVDA+j" followed by "t").
17 | In the doc\en and doc\fr folder, there is the diff.zip archive which contains the files listing the differences of the current version compared to the previous version.
18 |
19 |
20 | 5- Adapte the "keyboard.ini" to your keyboard and "symbolCategories.dic" files of "locale/en" folder (encoding in utf-8).
21 | Place thise files in the "locale/xx" folder.
22 | Map these files depending on the language.
23 |
24 | 6 - Adapte the "symbols-en.dic"file of the "newSymbols"folder.and name the translated file "symbols-xx.dic".
25 | Add symbols which are added in the file "locale/xx/symbolCategories.dic" and not supported vocally by NVDA for your language.
26 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/utils/runInThread.py:
--------------------------------------------------------------------------------
1 | # NVDAExtensionGlobalPlugin/runInThread.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2017 - 2020 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 | import addonHandler
8 | from logHandler import log
9 | import tones
10 | import threading
11 | import ui
12 | addonHandler.initTranslation()
13 |
14 |
15 | class RepeatTask(threading.Thread):
16 | _delay = None
17 | _armed = False
18 |
19 | def __init__(self, isRunning=None):
20 | if self._delay is None:
21 | log.error("Cannot create repeatTask thread because delay is none")
22 | return
23 | self.isRunning = isRunning
24 | super(RepeatTask, self).__init__()
25 | self._stopevent = threading.Event()
26 |
27 | def task(self):
28 | # must be overwritten
29 | return
30 |
31 | tones.beep(400, 200)
32 |
33 | def run(self):
34 | if self._delay is None:
35 | log.error("Cannot start repeatTask thread because not delay")
36 | return
37 | while not self._stopevent.is_set():
38 | self._stopevent.wait(self._delay)
39 | if self.isRunning is not None and not self.isRunning():
40 | # interrupted before stop
41 | # Translators: message to user to report an interuption before stop.
42 | ui.message(_("interrupted"))
43 | break
44 | self.task()
45 |
46 | def stop(self):
47 | self._stopevent.set()
48 |
49 |
50 | class RepeatBeep(RepeatTask):
51 | def __init__(self, delay=2.0, beep=(200, 200), isRunning=None):
52 | self._delay = delay
53 | self.beep = beep
54 | super(RepeatBeep, self).__init__(isRunning)
55 |
56 | def task(self):
57 | if self._stopevent.is_set():
58 | return
59 | (frequence, length) = self.beep
60 | tones.beep(frequence, length)
61 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/clipboardCommandAnnouncement/settingsDialogsPatche.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\clipboardCommandAnnouncement\settingsDialogs.py
2 | # a part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2025 Paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 | import addonHandler
8 | from gui.settingsDialogs import KeyboardSettingsPanel, NVDASettingsDialog
9 | from gui import mainFrame
10 |
11 | addonHandler.initTranslation()
12 |
13 |
14 | class MyKeyboardSettingsPanel(KeyboardSettingsPanel):
15 | def makeSettings(self, settingsSizer):
16 | super().makeSettings(settingsSizer)
17 | from ..clipboardCommandAnnouncement import canInstallSpellingAtTypingFunctionnality
18 | if canInstallSpellingAtTypingFunctionnality:
19 | self.alertForSpellingErrorsCheckBox.Enable()
20 | # Translators: label for check box
21 | self.alertForSpellingErrorsCheckBox.SetLabel(_("When typing, reports spelling errors"))
22 |
23 |
24 | try:
25 | NVDASettingsDialog.categoryClasses[NVDASettingsDialog.categoryClasses .index(KeyboardSettingsPanel)] = MyKeyboardSettingsPanel
26 | except ValueError:
27 | # when the modules are reloaded, MyKeyboardSettingsPanel has already replaced KeyboardSettingsPanel.
28 | # But we still have to put it back in place.
29 | cat = NVDASettingsDialog.categoryClasses[:]
30 | for c in cat:
31 | if c.__module__ == MyKeyboardSettingsPanel.__module__:
32 | NVDASettingsDialog.categoryClasses[NVDASettingsDialog.categoryClasses .index(c)] = MyKeyboardSettingsPanel
33 | break
34 |
35 |
36 | def myOnKeyboardSettingsCommand(*args, **kwargs):
37 | mainFrame.popupSettingsDialog(NVDASettingsDialog, MyKeyboardSettingsPanel)
38 |
39 |
40 | mainFrame.onKeyboardSettingsCommand = myOnKeyboardSettingsCommand
41 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/updateHandler/state.py:
--------------------------------------------------------------------------------
1 | # coding: utf-8
2 | # state.py
3 | # common Part of all of my add-ons
4 | # Copyright 2019 Paulber19
5 |
6 |
7 | import addonHandler
8 | from logHandler import log
9 | import os
10 | import time
11 | import pickle
12 | addonHandler.initTranslation()
13 |
14 | # delay between update checks
15 | addonUpdateCheckInterval = 86400 # one day
16 | #: Persistent state information.
17 | #: @type: dict
18 | _state = None
19 | _stateFileName = None
20 |
21 |
22 | #: The time to wait between checks.
23 | addonUpdateCheckInterval = 86400 # one day
24 |
25 |
26 | def initialize():
27 | global _state, _stateFilename
28 | addonPath = addonHandler.getCodeAddon().path
29 | _stateFilename = os.path.join(addonPath, "updateCheckState.pickle")
30 | try:
31 | # 9038: Python 3 requires binary format when working with pickles.
32 | with open(_stateFilename, "rb") as f:
33 | _state = pickle.load(f)
34 | except Exception:
35 | log.debugWarning("update state file don't exist: initialization with default values", exc_info=False)
36 | # Defaults.
37 | _state = {
38 | "lastCheck": 0,
39 | "remindUpdate": False,
40 | }
41 |
42 |
43 | def saveState():
44 | try:
45 | # #9038: Python 3 requires binary format when working with pickles.
46 | with open(_stateFilename, "wb") as f:
47 | pickle.dump(_state, f)
48 | except Exception:
49 | log.debugWarning("Error saving state", exc_info=True)
50 |
51 |
52 | def getLastCheck():
53 | return _state["lastCheck"]
54 |
55 |
56 | def setLastCheck():
57 | global _state
58 | _state["lastCheck"] = time.time()
59 | _state["remindUpdate"] = False
60 | saveState()
61 |
62 |
63 | def setRemindUpdate(on=True):
64 | global _state
65 | _state["lastCheck"] = time.time()
66 | _state["remindUpdate"] = on
67 | saveState()
68 |
69 |
70 | def getRemindUpdate():
71 | return _state["remindUpdate"]
72 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/__init__.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\__init__.py
2 | # a part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2016 - 2024 Paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 | import os
7 | from logHandler import log
8 |
9 |
10 | def shouldLoadNVDAExtensionGlobalPlugin():
11 |
12 | from .utils.nvdaInfos import NVDAVersion
13 | if NVDAVersion < [2024, 3]:
14 | import sys
15 | from .utils.py3Compatibility import getCommonUtilitiesPath
16 | sysPath = list(sys.path)
17 | psutilModulePath = None
18 | if "psutil" in sys.modules:
19 | log.warning("Potential incompatibility: psutil module is also used and loaded probably by other add-on")
20 | psutilModulePath = sys.modules["psutil"]
21 | del sys.modules["psutil"]
22 | sys.path = [sys.path[0]]
23 | commonUtilitiesPath = getCommonUtilitiesPath()
24 | psutilPath = os.path.join(commonUtilitiesPath, "psutilEx")
25 | sys.path.append(commonUtilitiesPath)
26 | sys.path.append(psutilPath)
27 | import psutilEx as psutil
28 | sys.path = sysPath
29 | del sys.modules["psutilEx"]
30 | if psutilModulePath is not None:
31 | sys.modules["psutil"] = psutilModulePath
32 | else:
33 | import psutil
34 |
35 | process = psutil.Process(os.getpid())
36 | if process.name() == "nvda.exe":
37 | return True
38 | return False
39 |
40 |
41 | if shouldLoadNVDAExtensionGlobalPlugin():
42 | from .theGlobalPlugin import NVDAExtensionGlobalPlugin
43 | else:
44 | from globalPluginHandler import GlobalPlugin as NVDAExtensionGlobalPlugin
45 |
46 |
47 | class GlobalPlugin (NVDAExtensionGlobalPlugin):
48 | # ??? this definition is necessary.
49 | # if not, the method of the NVDAExtensionGlobalPlugin class is never called.
50 | def chooseNVDAObjectOverlayClasses(self, obj, clsList):
51 | super(GlobalPlugin, self).chooseNVDAObjectOverlayClasses(obj, clsList)
52 |
--------------------------------------------------------------------------------
/addon/utilities/markdownEx/markdown/extensions/legacy_em.py:
--------------------------------------------------------------------------------
1 | # Legacy Em Extension for Python-Markdown
2 | # =======================================
3 |
4 | # This extension provides legacy behavior for _connected_words_.
5 |
6 | # Copyright 2015-2018 The Python Markdown Project
7 |
8 | # License: [BSD](https://opensource.org/licenses/bsd-license.php)
9 |
10 | """
11 | This extension provides legacy behavior for _connected_words_.
12 | """
13 |
14 | from __future__ import annotations
15 |
16 | from . import Extension
17 | from ..inlinepatterns import UnderscoreProcessor, EmStrongItem, EM_STRONG2_RE, STRONG_EM2_RE
18 | import re
19 |
20 | # _emphasis_
21 | EMPHASIS_RE = r'(_)([^_]+)\1'
22 |
23 | # __strong__
24 | STRONG_RE = r'(_{2})(.+?)\1'
25 |
26 | # __strong_em___
27 | STRONG_EM_RE = r'(_)\1(?!\1)([^_]+?)\1(?!\1)(.+?)\1{3}'
28 |
29 |
30 | class LegacyUnderscoreProcessor(UnderscoreProcessor):
31 | """Emphasis processor for handling strong and em matches inside underscores."""
32 |
33 | PATTERNS = [
34 | EmStrongItem(re.compile(EM_STRONG2_RE, re.DOTALL | re.UNICODE), 'double', 'strong,em'),
35 | EmStrongItem(re.compile(STRONG_EM2_RE, re.DOTALL | re.UNICODE), 'double', 'em,strong'),
36 | EmStrongItem(re.compile(STRONG_EM_RE, re.DOTALL | re.UNICODE), 'double2', 'strong,em'),
37 | EmStrongItem(re.compile(STRONG_RE, re.DOTALL | re.UNICODE), 'single', 'strong'),
38 | EmStrongItem(re.compile(EMPHASIS_RE, re.DOTALL | re.UNICODE), 'single', 'em')
39 | ]
40 |
41 |
42 | class LegacyEmExtension(Extension):
43 | """ Add legacy_em extension to Markdown class."""
44 |
45 | def extendMarkdown(self, md):
46 | """ Modify inline patterns. """
47 | md.inlinePatterns.register(LegacyUnderscoreProcessor(r'_'), 'em_strong2', 50)
48 |
49 |
50 | def makeExtension(**kwargs): # pragma: no cover
51 | """ Return an instance of the `LegacyEmExtension` """
52 | return LegacyEmExtension(**kwargs)
53 |
--------------------------------------------------------------------------------
/addon/utilities/markdownEx/markdown/__meta__.py:
--------------------------------------------------------------------------------
1 | # Python Markdown
2 |
3 | # A Python implementation of John Gruber's Markdown.
4 |
5 | # Documentation: https://python-markdown.github.io/
6 | # GitHub: https://github.com/Python-Markdown/markdown/
7 | # PyPI: https://pypi.org/project/Markdown/
8 |
9 | # Started by Manfred Stienstra (http://www.dwerg.net/).
10 | # Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org).
11 | # Currently maintained by Waylan Limberg (https://github.com/waylan),
12 | # Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser).
13 |
14 | # Copyright 2007-2023 The Python Markdown Project (v. 1.7 and later)
15 | # Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b)
16 | # Copyright 2004 Manfred Stienstra (the original version)
17 |
18 | # License: BSD (see LICENSE.md for details).
19 |
20 | # __version_info__ format:
21 | # (major, minor, patch, dev/alpha/beta/rc/final, #)
22 | # (1, 1, 2, 'dev', 0) => "1.1.2.dev0"
23 | # (1, 1, 2, 'alpha', 1) => "1.1.2a1"
24 | # (1, 2, 0, 'beta', 2) => "1.2b2"
25 | # (1, 2, 0, 'rc', 4) => "1.2rc4"
26 | # (1, 2, 0, 'final', 0) => "1.2"
27 |
28 | from __future__ import annotations
29 |
30 |
31 | __version_info__ = (3, 7, 0, 'final', 0)
32 |
33 |
34 | def _get_version(version_info):
35 | " Returns a PEP 440-compliant version number from `version_info`. "
36 | assert len(version_info) == 5
37 | assert version_info[3] in ('dev', 'alpha', 'beta', 'rc', 'final')
38 |
39 | parts = 2 if version_info[2] == 0 else 3
40 | v = '.'.join(map(str, version_info[:parts]))
41 |
42 | if version_info[3] == 'dev':
43 | v += '.dev' + str(version_info[4])
44 | elif version_info[3] != 'final':
45 | mapping = {'alpha': 'a', 'beta': 'b', 'rc': 'rc'}
46 | v += mapping[version_info[3]] + str(version_info[4])
47 |
48 | return v
49 |
50 |
51 | __version__ = _get_version(__version_info__)
52 |
--------------------------------------------------------------------------------
/addon/utilities/markdownEx/markdown/__init__.py:
--------------------------------------------------------------------------------
1 | # Python Markdown
2 |
3 | # A Python implementation of John Gruber's Markdown.
4 |
5 | # - Documentation: https://python-markdown.github.io/
6 | # - GitHub: https://github.com/Python-Markdown/markdown/
7 | # - PyPI: https://pypi.org/project/Markdown/
8 |
9 | # Started by Manfred Stienstra (http://www.dwerg.net/).
10 | # Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org).
11 | # Currently maintained by Waylan Limberg (https://github.com/waylan),
12 | # Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser).
13 |
14 | # - Copyright 2007-2023 The Python Markdown Project (v. 1.7 and later)
15 | # - Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b)
16 | # - Copyright 2004 Manfred Stienstra (the original version)
17 |
18 | # License: BSD (see LICENSE.md for details).
19 |
20 | """
21 | Python-Markdown provides two public functions ([`markdown.markdown`][] and [`markdown.markdownFromFile`][])
22 | both of which wrap the public class [`markdown.Markdown`][]. All submodules support these public functions
23 | and class and/or provide extension support.
24 |
25 | Modules:
26 | core: Core functionality.
27 | preprocessors: Pre-processors.
28 | blockparser: Core Markdown block parser.
29 | blockprocessors: Block processors.
30 | treeprocessors: Tree processors.
31 | inlinepatterns: Inline patterns.
32 | postprocessors: Post-processors.
33 | serializers: Serializers.
34 | util: Utility functions.
35 | htmlparser: HTML parser.
36 | test_tools: Testing utilities.
37 | extensions: Markdown extensions.
38 | """
39 |
40 | from __future__ import annotations
41 |
42 | from .core import Markdown, markdown, markdownFromFile
43 | from .__meta__ import __version__, __version_info__ # noqa
44 |
45 | # For backward compatibility as some extensions expect it...
46 | from .extensions import Extension # noqa
47 |
48 | __all__ = ['Markdown', 'markdown', 'markdownFromFile']
49 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/userInputGestures/inputGesturesExPatches.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\userInputGestures\inputGesturesExPatches.py
2 | # a part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2024 Paulber19
4 | # This file is covered by the GNU General Public License.
5 |
6 |
7 | from logHandler import log
8 | import gui
9 | import wx
10 | from ..utils.NVDAStrings import NVDAString
11 |
12 | # global variable to save NVDA patched method
13 | _NVDAGuiMainFrameOnInputGesturesCommand = None
14 |
15 |
16 | def onInputGesturesCommandEx(evt):
17 | from .inputGesturesEx import InputGesturesDialogEx
18 | gui.mainFrame._popupSettingsDialog(InputGesturesDialogEx)
19 |
20 |
21 | def patche(install=True):
22 | if not install:
23 | removePatch()
24 | return
25 | global _NVDAGuiMainFrameOnInputGesturesCommand
26 | if _NVDAGuiMainFrameOnInputGesturesCommand is not None:
27 | return
28 | _NVDAGuiMainFrameOnInputGesturesCommand = gui.mainFrame.onInputGesturesCommand
29 | gui.mainFrame.onInputGesturesCommand = onInputGesturesCommandEx
30 | log.debug(
31 | "For user input gestures functionality,"
32 | " fgui.mainFrame.onInputGesturesCommand has been patched by: %s of %s module "
33 | % (onInputGesturesCommandEx.__name__, onInputGesturesCommandEx.__module__))
34 |
35 | menus = gui.mainFrame.sysTrayIcon.preferencesMenu.GetMenuItems()
36 | item = None
37 | for menuItem in menus:
38 | if menuItem.GetItemLabel() == NVDAString("I&nput gestures..."):
39 | item = menuItem
40 | break
41 | if item is not None:
42 | gui.mainFrame.sysTrayIcon.Bind(wx.EVT_MENU, onInputGesturesCommandEx, item)
43 | log.debug(
44 | "For user input gesture functionality,"
45 | " %s of %s module is now the action for the Input gestures sub-menu " % (
46 | onInputGesturesCommandEx.__name__, onInputGesturesCommandEx.__module__))
47 |
48 |
49 | def removePatch():
50 | global _NVDAGuiMainFrameOnInputGesturesCommand
51 | if _NVDAGuiMainFrameOnInputGesturesCommand is not None:
52 | gui.mainFrame.onInputGesturesCommand = _NVDAGuiMainFrameOnInputGesturesCommand
53 | _NVDAGuiMainFrameOnInputGesturesCommand = None
54 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/browseModeEx/NVDAObjectsIAccessible.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\browseModeEx\NVDAObjectsIAccessible.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2016 - 2023 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 | from logHandler import log
8 | import config
9 | import controlTypes
10 | import NVDAObjects
11 | from .virtualBuffersEx import MSHTMLEx, Gecko_ia2_Ex, ChromeVBufEx
12 | import NVDAObjects.IAccessible.chromium
13 |
14 |
15 | class NVDAObjectMSHTMLEx(NVDAObjects.IAccessible.MSHTML.MSHTML):
16 | def _get_treeInterceptorClass(self):
17 | if (
18 | self.role in (controlTypes.Role.DOCUMENT, controlTypes.Role.APPLICATION, controlTypes.Role.DIALOG)
19 | and not self.isContentEditable):
20 | return MSHTMLEx
21 | return super(NVDAObjectMSHTMLEx, self).treeInterceptorClass
22 |
23 |
24 | class NVDAObjectMozillaDocumentEx(NVDAObjects.IAccessible.mozilla .Document):
25 | def _get_treeInterceptorClass(self):
26 | if controlTypes.State.EDITABLE not in self.states:
27 | return Gecko_ia2_Ex
28 | return super(NVDAObjectMozillaDocumentEx, self).treeInterceptorClass
29 |
30 |
31 | class ChromiumDocument(NVDAObjects.IAccessible.chromium.Document):
32 | def _get_treeInterceptorClass(self):
33 | shouldLoadVBufOnBusyFeatureFlag = bool(
34 | config.conf["virtualBuffers"]["loadChromiumVBufOnBusyState"]
35 | )
36 | vBufUnavailableStates = { # if any of these are in states, don't return ChromeVBuf
37 | controlTypes.State.EDITABLE,
38 | }
39 | if not shouldLoadVBufOnBusyFeatureFlag:
40 | log.debug(
41 | f"loadChromiumVBufOnBusyState feature flag is {shouldLoadVBufOnBusyFeatureFlag},"
42 | " vBuf WILL NOT be loaded when state of the document is busy."
43 | )
44 | vBufUnavailableStates.add(controlTypes.State.BUSY)
45 | else:
46 | log.debug(
47 | f"loadChromiumVBufOnBusyState feature flag is {shouldLoadVBufOnBusyFeatureFlag},"
48 | " vBuf WILL be loaded when state of the document is busy."
49 | )
50 | if self.states.intersection(vBufUnavailableStates):
51 | return super().treeInterceptorClass
52 | return ChromeVBufEx
53 |
--------------------------------------------------------------------------------
/addon/utilities/pydubEx/playback.py:
--------------------------------------------------------------------------------
1 | """
2 | Support for playing AudioSegments. Pyaudio will be used if it's installed,
3 | otherwise will fallback to ffplay. Pyaudio is a *much* nicer solution, but
4 | is tricky to install. See my notes on installing pyaudio in a virtualenv (on
5 | OSX 10.10): https://gist.github.com/jiaaro/9767512210a1d80a8a0d
6 | """
7 |
8 | import subprocess
9 | from tempfile import NamedTemporaryFile
10 | from .utils import get_player_name, make_chunks
11 |
12 | def _play_with_ffplay(seg):
13 | PLAYER = get_player_name()
14 | with NamedTemporaryFile("w+b", suffix=".wav") as f:
15 | seg.export(f.name, "wav")
16 | subprocess.call([PLAYER, "-nodisp", "-autoexit", "-hide_banner", f.name])
17 |
18 |
19 | def _play_with_pyaudio(seg):
20 | import pyaudio
21 |
22 | p = pyaudio.PyAudio()
23 | stream = p.open(format=p.get_format_from_width(seg.sample_width),
24 | channels=seg.channels,
25 | rate=seg.frame_rate,
26 | output=True)
27 |
28 | # Just in case there were any exceptions/interrupts, we release the resource
29 | # So as not to raise OSError: Device Unavailable should play() be used again
30 | try:
31 | # break audio into half-second chunks (to allows keyboard interrupts)
32 | for chunk in make_chunks(seg, 500):
33 | stream.write(chunk._data)
34 | finally:
35 | stream.stop_stream()
36 | stream.close()
37 |
38 | p.terminate()
39 |
40 |
41 | def _play_with_simpleaudio(seg):
42 | import simpleaudio
43 | return simpleaudio.play_buffer(
44 | seg.raw_data,
45 | num_channels=seg.channels,
46 | bytes_per_sample=seg.sample_width,
47 | sample_rate=seg.frame_rate
48 | )
49 |
50 |
51 | def play(audio_segment):
52 | try:
53 | playback = _play_with_simpleaudio(audio_segment)
54 | try:
55 | playback.wait_done()
56 | except KeyboardInterrupt:
57 | playback.stop()
58 | except ImportError:
59 | pass
60 | else:
61 | return
62 |
63 | try:
64 | _play_with_pyaudio(audio_segment)
65 | return
66 | except ImportError:
67 | pass
68 | else:
69 | return
70 |
71 | _play_with_ffplay(audio_segment)
72 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/currentFolder/__init__.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\currentFolder\__init__
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2016 - 2020 Daniel Poiraud , Paulber19
4 | # This file is covered by the GNU General Public License.
5 |
6 | import addonHandler
7 | import api
8 | import ui
9 |
10 | addonHandler.initTranslation()
11 |
12 |
13 | def findChildObjectByClassName(obj, className):
14 | for o in obj.children:
15 | if o.windowClassName == className:
16 | return o
17 | return None
18 |
19 |
20 | def getCurrentFolder():
21 | oForeground = api.getForegroundObject()
22 | # for Office 2003 and dialogbox based on XP
23 | windowText = oForeground.windowText
24 | # Translators: this is title of classic Window to manage file.
25 | if windowText in [_("Open"), _("Save"), _("Save as"), _("Find in")]:
26 | if 'bosa_sdm_' in oForeground.windowClassName:
27 | oCurrentFolder = oForeground.children[14]
28 | path = oCurrentFolder.name
29 | folder = oCurrentFolder.value
30 | return (path, folder)
31 | elif '#32770' in oForeground.windowClassName:
32 | if oForeground.children[1].windowClassName == 'ComboBox':
33 | oCurrentFolder = oForeground.children[1]
34 | path = "%s\\%s" % (oCurrentFolder.name, oCurrentFolder.value)
35 | path = oCurrentFolder.name
36 | folder = oCurrentFolder.value
37 | return (path, folder)
38 | classNames = (
39 | "WorkerW",
40 | "ReBarWindow32",
41 | "Address Band Root",
42 | "msctls_progress32",
43 | "Breadcrumb Parent",
44 | "ToolbarWindow32")
45 | o = oForeground
46 | for className in classNames:
47 | o = findChildObjectByClassName(o, className)
48 | if o is None:
49 | break
50 | if o is None:
51 | return None
52 | pathList = []
53 | for o in o.children:
54 | pathList.append(o.name)
55 | path = "\\".join(pathList[:-1])
56 | folder = pathList[-1]
57 | return (path, folder)
58 |
59 |
60 | def reportCurrentFolder(sayPath=False):
61 | # Translators: message to the user.
62 | msgFolderNotFound = _("Selected folder name not found")
63 | currentFolder = getCurrentFolder()
64 | if currentFolder is None:
65 | ui.message(msgFolderNotFound)
66 | return
67 | (path, folder) = currentFolder
68 | if not sayPath:
69 | # report folder name
70 | ui.message(_("Folder %s") % folder)
71 | else:
72 | # report full folder path
73 | ui.message("%s\\%s" % (path, folder))
74 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/utils/numlock.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\utils\numlock.py
2 | # a part of NVDAExtensionGlobal add-on
3 | # Copyright (C) 2022-2023 Paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 | import addonHandler
7 | from logHandler import log
8 | import wx
9 | import ui
10 | import winUser
11 | from ..settings.nvdaConfig import _NVDAConfigManager, ANL_NoChange, ANL_Off, ANL_On
12 | addonHandler.initTranslation()
13 |
14 |
15 | def manageNumlockActivation():
16 | log.debug("manageNumlockActivation")
17 | from keyboardHandler import KeyboardInputGesture
18 | activateNumlockOption = _NVDAConfigManager.getActivateNumlockOption()
19 | curNumlockState = winUser.getKeyState(winUser.VK_NUMLOCK)
20 | if activateNumlockOption != ANL_NoChange:
21 | if (
22 | (curNumlockState and (activateNumlockOption == ANL_Off))
23 | or (not curNumlockState and (activateNumlockOption == ANL_On))
24 | ):
25 | gesture = KeyboardInputGesture.fromName("numLock")
26 | gesture.send()
27 | wx.CallLater(200, gesture.reportExtra)
28 |
29 |
30 | def reportActivatedLockState(previousNumlockState, previousCapslockState):
31 | log.debug("reportActivatedLockState")
32 | numlockActivation = False
33 | capslockActivation = False
34 | from ..settings import (
35 | toggleReportNumlockStateAtStartAdvancedOption, toggleReportCapslockStateAtStartAdvancedOption)
36 | if toggleReportNumlockStateAtStartAdvancedOption(False):
37 | numlockState = winUser.getKeyState(winUser.VK_NUMLOCK)
38 | numlockActivation = numlockState and numlockState == previousNumlockState
39 | if toggleReportCapslockStateAtStartAdvancedOption(False):
40 | capslockState = winUser.getKeyState(winUser.VK_CAPITAL)
41 | capslockActivation = capslockState and capslockState == previousCapslockState
42 | if not numlockActivation and not capslockActivation:
43 | return
44 | msg = None
45 | if numlockActivation and capslockActivation:
46 | # Translators: message to user to warn the enabled capital and numeric lock states
47 | msg = _("Warning: Numeric lock and capital locks are enabled")
48 | elif numlockActivation:
49 | # Translators: message to user to warn the enabled numeric lock state
50 | msg = _("Warning: Numeric lock is enabled")
51 | else:
52 | # Translators: message to user to warn the enabled capital state
53 | msg = _("Warning: capslock is enabled")
54 | if msg:
55 | ui.message(msg)
56 |
--------------------------------------------------------------------------------
/addon/utilities/markdownEx/markdown/extensions/extra.py:
--------------------------------------------------------------------------------
1 | # Python-Markdown Extra Extension
2 | # ===============================
3 |
4 | # A compilation of various Python-Markdown extensions that imitates
5 | # [PHP Markdown Extra](http://michelf.com/projects/php-markdown/extra/).
6 |
7 | # See https://Python-Markdown.github.io/extensions/extra
8 | # for documentation.
9 |
10 | # Copyright The Python Markdown Project
11 |
12 | # License: [BSD](https://opensource.org/licenses/bsd-license.php)
13 |
14 | """
15 | A compilation of various Python-Markdown extensions that imitates
16 | [PHP Markdown Extra](http://michelf.com/projects/php-markdown/extra/).
17 |
18 | Note that each of the individual extensions still need to be available
19 | on your `PYTHONPATH`. This extension simply wraps them all up as a
20 | convenience so that only one extension needs to be listed when
21 | initiating Markdown. See the documentation for each individual
22 | extension for specifics about that extension.
23 |
24 | There may be additional extensions that are distributed with
25 | Python-Markdown that are not included here in Extra. Those extensions
26 | are not part of PHP Markdown Extra, and therefore, not part of
27 | Python-Markdown Extra. If you really would like Extra to include
28 | additional extensions, we suggest creating your own clone of Extra
29 | under a different name. You could also edit the `extensions` global
30 | variable defined below, but be aware that such changes may be lost
31 | when you upgrade to any future version of Python-Markdown.
32 |
33 | See the [documentation](https://Python-Markdown.github.io/extensions/extra)
34 | for details.
35 | """
36 |
37 | from __future__ import annotations
38 |
39 | from . import Extension
40 |
41 | extensions = [
42 | 'fenced_code',
43 | 'footnotes',
44 | 'attr_list',
45 | 'def_list',
46 | 'tables',
47 | 'abbr',
48 | 'md_in_html'
49 | ]
50 | """ The list of included extensions. """
51 |
52 |
53 | class ExtraExtension(Extension):
54 | """ Add various extensions to Markdown class."""
55 |
56 | def __init__(self, **kwargs):
57 | """ `config` is a dumb holder which gets passed to the actual extension later. """
58 | self.config = kwargs
59 |
60 | def extendMarkdown(self, md):
61 | """ Register extension instances. """
62 | md.registerExtensions(extensions, self.config)
63 |
64 |
65 | def makeExtension(**kwargs): # pragma: no cover
66 | return ExtraExtension(**kwargs)
67 |
--------------------------------------------------------------------------------
/addon/utilities/markdownEx/markdown/extensions/sane_lists.py:
--------------------------------------------------------------------------------
1 | # Sane List Extension for Python-Markdown
2 | # =======================================
3 |
4 | # Modify the behavior of Lists in Python-Markdown to act in a sane manor.
5 |
6 | # See https://Python-Markdown.github.io/extensions/sane_lists
7 | # for documentation.
8 |
9 | # Original code Copyright 2011 [Waylan Limberg](http://achinghead.com)
10 |
11 | # All changes Copyright 2011-2014 The Python Markdown Project
12 |
13 | # License: [BSD](https://opensource.org/licenses/bsd-license.php)
14 |
15 | """
16 | Modify the behavior of Lists in Python-Markdown to act in a sane manor.
17 |
18 | See [documentation](https://Python-Markdown.github.io/extensions/sane_lists)
19 | for details.
20 | """
21 |
22 | from __future__ import annotations
23 |
24 | from . import Extension
25 | from ..blockprocessors import OListProcessor, UListProcessor
26 | import re
27 | from typing import TYPE_CHECKING
28 |
29 | if TYPE_CHECKING: # pragma: no cover
30 | from .. import blockparser
31 |
32 |
33 | class SaneOListProcessor(OListProcessor):
34 | """ Override `SIBLING_TAGS` to not include `ul` and set `LAZY_OL` to `False`. """
35 |
36 | SIBLING_TAGS = ['ol']
37 | """ Exclude `ul` from list of siblings. """
38 | LAZY_OL = False
39 | """ Disable lazy list behavior. """
40 |
41 | def __init__(self, parser: blockparser.BlockParser):
42 | super().__init__(parser)
43 | self.CHILD_RE = re.compile(r'^[ ]{0,%d}((\d+\.))[ ]+(.*)' %
44 | (self.tab_length - 1))
45 |
46 |
47 | class SaneUListProcessor(UListProcessor):
48 | """ Override `SIBLING_TAGS` to not include `ol`. """
49 |
50 | SIBLING_TAGS = ['ul']
51 | """ Exclude `ol` from list of siblings. """
52 |
53 | def __init__(self, parser: blockparser.BlockParser):
54 | super().__init__(parser)
55 | self.CHILD_RE = re.compile(r'^[ ]{0,%d}(([*+-]))[ ]+(.*)' %
56 | (self.tab_length - 1))
57 |
58 |
59 | class SaneListExtension(Extension):
60 | """ Add sane lists to Markdown. """
61 |
62 | def extendMarkdown(self, md):
63 | """ Override existing Processors. """
64 | md.parser.blockprocessors.register(SaneOListProcessor(md.parser), 'olist', 40)
65 | md.parser.blockprocessors.register(SaneUListProcessor(md.parser), 'ulist', 30)
66 |
67 |
68 | def makeExtension(**kwargs): # pragma: no cover
69 | return SaneListExtension(**kwargs)
70 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/utils/keyboard.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\utils\/keyboard.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2016- 2023 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 | import addonHandler
8 | from logHandler import log
9 | import os.path
10 | from configobj import ConfigObj
11 | from configobj.validate import Validator
12 | from io import StringIO
13 |
14 | _configSpec = """
15 | [KeyboardKeys]
16 | keys = string(default="")
17 | [editionKeyCommands]
18 | [default]
19 | copy = string(default = "kb:control+c")
20 | cut = string(default = "kb:control+x")
21 | paste = string( default = "kb:control+v")
22 | undo = string( default = "kb:control+z")
23 | selectAll = string( default = "kb:control+a")
24 | """
25 |
26 |
27 | def getKeyboardKeysIniFilePath():
28 | from languageHandler import getLanguage
29 | lang = getLanguage()
30 | langs = [lang, ]
31 | addonFolderPath = addonHandler.getCodeAddon().path
32 | if '_' in lang:
33 | langs.append(lang.split("_")[0])
34 | langs.append("en")
35 | for lang in langs:
36 | langDir = os.path.join(addonFolderPath, "locale", lang)
37 | if os.path.exists(langDir):
38 | file = os.path.join(langDir, "keyboard.ini")
39 | if os.path.isfile(file):
40 | log.debugWarning("keyboard.ini file loaded from locale\\%s folder" % lang)
41 | return file
42 | log.error("keyboard.ini file not found")
43 | return ""
44 |
45 |
46 | def getKeyboardKeys():
47 | keys = getKeyboardIniConfig()["KeyboardKeys"]["keys"]
48 | return list(keys)
49 |
50 |
51 | def getEditionKeyCommands(obj=None):
52 | conf = getKeyboardIniConfig()["editionKeyCommands"].copy()
53 | d = conf["default"].copy()
54 | if obj is None:
55 | return d
56 | appName = obj.appModule.appName
57 | if appName in conf:
58 | d.update(conf[appName])
59 | return d
60 |
61 |
62 | def getKeyboardIniConfig():
63 | global _conf
64 | if _conf is not None:
65 | return _conf
66 | path = getKeyboardKeysIniFilePath()
67 | conf = ConfigObj(
68 | path,
69 | configspec=StringIO(_configSpec),
70 | encoding="utf-8",
71 | list_values=False)
72 | conf.newlines = "\r\n"
73 | val = Validator()
74 | ret = conf.validate(val, preserve_errors=True, copy=True)
75 | if not ret:
76 | log.warning("KeyboardKeys configuration file is invalid: %s", ret)
77 | _conf = conf
78 | return conf
79 |
80 |
81 | # singleton
82 | _conf = None
83 |
--------------------------------------------------------------------------------
/addon/doc/ar/addonUserManual.t2t:
--------------------------------------------------------------------------------
1 | ADDON_SUMMARY - دليل المستخدم
2 | المؤلف: ADDON_AUTHOR_NAME
3 |
4 |
5 | %!includeconf: ../addon_userManual.t2tconf
6 | %!includeconf: addon_informations.t2tconf
7 | %!includeconf: addon_keys.t2tconf
8 | عنوان URL: [ADDON_REPOSITORY ADDON_REPOSITORY]
9 |
10 |
11 | تحميل:
12 | - [إصدار ثابت ADDON_CUR_VERSION ADDON_DOWNLOAD_SERVER1]
13 | - [إصدار التطوير ADDON_DEV_URL]
14 |
15 |
16 | التوافق:
17 | - Nminimum المدعومة من إصدار NVDA: MINIMUM_NVDA_VERSION
18 | - آخر إصدار تم اختباره من NVDA: LAST_TESTED_NVDA_VERSION
19 |
20 |
21 | Traductor (s): ترجمة آلية من اللغة الفرنسية
22 | = سومير = [toc]
23 | %%toc
24 |
25 |
26 | + مقدمة +
27 | ++ عام ++
28 | عذرًا ، لكن هذا الدليل غير متوفر باللغة الإنجليزية اليوم.
29 | الدليل الأصلي مكتوب بالفرنسية ([دليل فرنسي ../fr/addonUserManual.html]) ولم تتم ترجمته حتى يومنا هذا.
30 |
31 |
32 |
33 | ++ التحديث ++
34 | يتم تحديث الإضافة بشكل افتراضي تلقائيًا بعد وقت قصير من بدء NVDA (بين 20 و 600 ثانية) وبحد أقصى مرة واحدة يوميًا.
35 | من الممكن تعطيل هذا التحديث بإلغاء تحديد الخيار "البحث التلقائي عن التحديثات" لفئة "تحديث" في إعدادات الوظيفة الإضافية.
36 | يمكن أن يكون إصدار الوظيفة الإضافية:
37 | - نسخة مستقرة: رقم نسختها هو "1.0" على سبيل المثال.
38 | - إما إصدار تطوير: رقم الإصدار من النوع "1.0-dev1" أو "1.0-rc1" أو "1.0-beta2".
39 |
40 |
41 | بشكل افتراضي ، يتم تحديث الإصدار الثابت بإصدار ثابت أحدث (رقم إصدار أعلى).
42 | ولكن من الممكن تحديث الإصدار الثابت الذي يعمل بإصدار مطور من الإصدار الثابت التالي. ما عليك سوى تحديد الخيار "تحديث أيضًا تحديث الإصدار الثابت لإصدارات التطوير" الموجود في فئة "تحديث" لإعدادات الوظائف الإضافية.
43 |
44 | يتم تحديث نسخة التطوير:
45 | - بإصدار تطوير أحدث ،
46 | - بنسخته المستقرة ،
47 | - أو باستخدام أحدث إصدار ثابت إذا لم يتم تحديد الخيار السابق.
48 |
49 |
50 | يتيح لك الزر "بحث عن تحديث" الموجود في إعدادات الوظيفة الإضافية ، عنصر القائمة "تحديث" ، البحث على الفور عن تحديث.
51 |
52 |
53 | يتيح لك زر "عرض المحفوظات" ، الموجود في نفس الفئة ، عرض محفوظات الإصدار الحالي في المتصفح.
54 |
55 | في حالة التحديث التلقائي وفي حالة اكتشاف إصدار جديد ، يتم عرض مربع الحوار "تحديث" ليقترح ما يلي:
56 | - إما التثبيت الفوري للإصدار الجديد ،
57 | - أو تأجيل التحديث إلى وقت لاحق. في هذه الحالة ، سيتم إعادة البحث بعد ساعة واحدة على الأقل.
58 |
59 |
60 | في حالة التحديث لإصدار مستقر ، يوفر زر "ما الجديد" إمكانية فتح محفوظات الوظيفة الإضافية في المتصفح وبالتالي القدرة على معرفة الميزات الجديدة للإصدار المقترح.
61 |
62 |
63 | ++ تاريخية ++
64 | محفوظات إصدار هذه الوظيفة الإضافية موجودة في الملف: ["Changes.html" Changes.html]
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/speech/sayError.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\speech\sayError.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2024 paulber19
4 | # This file is covered by the GNU General Public License.
5 |
6 | import addonHandler
7 | # from logHandler import log
8 | import api
9 | import os
10 | import globalVars
11 | import speech
12 | import config
13 | from .commands import BeepWithPauseCommand
14 |
15 | addonHandler.initTranslation()
16 |
17 |
18 | class SayErrorProfileTrigger(config.ProfileTrigger):
19 | spec = "sayError"
20 |
21 |
22 | def getErrorSoundSpeechSequence(error=None):
23 | from speech.commands import WaveFileCommand
24 | fileName = os.path.join(globalVars.appDir, "waves", "textError.wav")
25 | seq = [
26 | speech.commands.EndUtteranceCommand(),
27 | WaveFileCommand(fileName),
28 | speech.commands.EndUtteranceCommand()
29 | ]
30 | if error is not None:
31 | seq.extend([
32 | error,
33 | speech.commands.EndUtteranceCommand(),
34 | ])
35 | return seq
36 |
37 |
38 | def getErrorBeepSpeechSequence(error=None):
39 | seq = [
40 | speech.commands.EndUtteranceCommand(),
41 | BeepWithPauseCommand(150, 50),
42 | speech.commands.EndUtteranceCommand(),
43 | BeepWithPauseCommand(150, 50),
44 | speech.commands.EndUtteranceCommand(),
45 | ]
46 | if error is not None and error != "" and not error.isspace():
47 | seq.extend([
48 | error,
49 | speech.commands.EndUtteranceCommand(),
50 | ])
51 | return seq
52 |
53 |
54 | def getErrorVoiceSpeechSequence(error=None):
55 | if error is None:
56 | return []
57 | t1 = SayErrorProfileTrigger()
58 | return [
59 | speech.commands.ConfigProfileTriggerCommand(t1, True),
60 | error,
61 | speech.commands.ConfigProfileTriggerCommand(t1, False),
62 | ]
63 |
64 |
65 | def getErrorSpeechSequence(error=None, reading=False):
66 | from ..settings import _addonConfigManager
67 | if _addonConfigManager.reportingSpellingErrorsByErrorReporting(reading=reading):
68 | return getErrorVoiceSpeechSequence(error)
69 | elif _addonConfigManager.reportingSpellingErrorsByBeep(reading=reading):
70 | return getErrorBeepSpeechSequence(error)
71 | elif _addonConfigManager.reportingSpellingErrorsBySound(reading=reading):
72 | return getErrorSoundSpeechSequence(error)
73 | elif error is not None:
74 | return [error]
75 | return None
76 |
77 |
78 | def initialize():
79 | # Translators: name of say error profile
80 | name = _("Spelling errors' announcement")
81 | name = api.filterFileName(name)
82 | config.conf.triggersToProfiles["sayError"] = name
83 | fn = config.conf._getProfileFn(name)
84 | if os.path.isfile(fn):
85 | # the profile already exists
86 | return
87 | config.conf.createProfile(name)
88 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/computerTools/beep.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\computerTools\tonesEx.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2023-2024 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 |
8 | from logHandler import log
9 | import tones
10 | import time
11 | import nvwave
12 | from ctypes import create_string_buffer
13 | from ..utils.nvdaInfos import NVDAVersion
14 |
15 | # temporary wave player
16 | _player = None
17 |
18 |
19 | def getPlayer(outputDevice):
20 | global _player
21 | if outputDevice is None:
22 | return tones.player
23 | try:
24 | _player = nvwave.WavePlayer(
25 | channels=2,
26 | samplesPerSec=int(tones.SAMPLE_RATE),
27 | bitsPerSample=16,
28 | outputDevice=outputDevice,
29 | wantDucking=False
30 | )
31 | except Exception:
32 | log.warning("Failed to initialize audio for tones", exc_info=True)
33 | _player = None
34 | return _player
35 |
36 |
37 | def myBeep(
38 | hz: float,
39 | length: int,
40 | left: int = None,
41 | right: int = None,
42 | isSpeechBeepCommand: bool = False,
43 | device=None
44 | ):
45 | """Plays a tone at the given hz, length, and stereo balance.
46 | @param hz: pitch in hz of the tone
47 | @param length: length of the tone in ms
48 | @param left: volume of the left channel (0 to 100)
49 | @param right: volume of the right channel (0 to 100)
50 | @param isSpeechBeepCommand: whether this beep is created as part of a speech sequence
51 | @device: audio output device
52 | """
53 | from ..settings import _addonConfigManager
54 | tonalitiesVolumeLevel = _addonConfigManager.getTonalitiesVolumeLevel()
55 | if left is None:
56 | left = tonalitiesVolumeLevel
57 | if right is None:
58 | right = tonalitiesVolumeLevel
59 | log.io("Beep at pitch %s, for %s ms, left volume %s, right volume %s" % (hz, length, left, right))
60 |
61 | if not tones.decide_beep.decide(
62 | hz=hz,
63 | length=length,
64 | left=left,
65 | right=right,
66 | isSpeechBeepCommand=isSpeechBeepCommand
67 | ):
68 | log.debug(
69 | "Beep canceled by handler registered to decide_beep extension point"
70 | )
71 | return
72 |
73 | global _player
74 | _player = getPlayer(device)
75 | if not _player:
76 | return
77 | from NVDAHelper import generateBeep
78 | bufSize = generateBeep(None, hz, length, left, right)
79 | buf = create_string_buffer(bufSize)
80 | generateBeep(buf, hz, length, left, right)
81 | _player.stop()
82 | _player.feed(buf.raw)
83 |
84 |
85 | def playTonesOnDevice(outputDevice):
86 | outputDeviceName, outputDeviceId = outputDevice
87 | log.debug("playTonesOnDevice: %s" % outputDeviceName)
88 | device = outputDeviceName if NVDAVersion < [2025, 1] else outputDeviceId
89 | myBeep(hz=250, length=100, device=device)
90 | time.sleep(0.3)
91 | myBeep(hz=350, length=100, device=device)
92 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/computerTools/messageDialogs.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\computerTools\messageDialogs.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2025 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 | import addonHandler
8 | import wx
9 | from gui.guiHelper import (
10 | BoxSizerHelper,
11 | BORDER_FOR_DIALOGS,
12 | ButtonHelper,
13 | SPACE_BETWEEN_VERTICAL_DIALOG_ITEMS,
14 | )
15 | import windowUtils
16 | from ..utils import makeAddonWindowTitle, getHelpObj
17 | from ..gui import contextHelpEx
18 |
19 | addonHandler.initTranslation()
20 |
21 |
22 | class SplitAudioWarningDialog(
23 | contextHelpEx.ContextHelpMixinEx,
24 | wx.Dialog, # wxPython does not seem to call base class initializer, put last in MRO
25 | ):
26 | """A dialog warning the user about the risks of incompatibility with NVDA split audio."""
27 | # help in the user manual.
28 | helpObj = getHelpObj("hdr34")
29 |
30 | def __init__(self, parent: wx.Window):
31 | # Translators: The warning of a dialog
32 | dialogTitle = makeAddonWindowTitle(_("Warning"))
33 | super().__init__(parent, title=dialogTitle)
34 | mainSizer = wx.BoxSizer(wx.VERTICAL)
35 | sHelper = BoxSizerHelper(self, orientation=wx.VERTICAL)
36 | # Translators: Warning that is displayed at add-on start when nvda split audio is not in desactivated state
37 | _warningText = _(
38 | "The NVDA Split audio mode being in disabled mode,"
39 | " it may be in contradiction with the Split audio functionality of the add-on.")
40 | sText = sHelper.addItem(wx.StaticText(self, label=_warningText))
41 | # the wx.Window must be constructed before we can get the handle.
42 | self.scaleFactor = windowUtils.getWindowScalingFactor(self.GetHandle())
43 | sText.Wrap(
44 | # 600 was fairly arbitrarily chosen by a visual user to look acceptable on their machine.
45 | self.scaleFactor * 600,
46 | )
47 |
48 | sHelper.sizer.AddSpacer(SPACE_BETWEEN_VERTICAL_DIALOG_ITEMS)
49 | self.dontShowAgainCheckbox = sHelper.addItem(
50 | wx.CheckBox(
51 | self,
52 | label=_(
53 | # Translators: The label of a checkbox in the split audio warning dialog
54 | "&Don't show this message again",
55 | ),
56 | ),
57 | )
58 |
59 | bHelper = sHelper.addDialogDismissButtons(ButtonHelper(wx.HORIZONTAL))
60 | # Translators: The label of a button in a dialog
61 | okButton = bHelper.addButton(self, wx.ID_OK, label=pgettext("addonStore", "&OK"))
62 | okButton.Bind(wx.EVT_BUTTON, self.onOkButton)
63 |
64 | mainSizer.Add(sHelper.sizer, border=BORDER_FOR_DIALOGS, flag=wx.ALL)
65 | self.Sizer = mainSizer
66 | mainSizer.Fit(self)
67 | self.CentreOnScreen()
68 |
69 | def onOkButton(self, evt: wx.CommandEvent):
70 | # addonDataManager.storeSettings.showWarning = not self.dontShowAgainCheckbox.GetValue()
71 | self.EndModal(wx.ID_OK)
72 |
--------------------------------------------------------------------------------
/addon/utilities/markdownEx/markdown/extensions/meta.py:
--------------------------------------------------------------------------------
1 | # Meta Data Extension for Python-Markdown
2 | # =======================================
3 |
4 | # This extension adds Meta Data handling to markdown.
5 |
6 | # See https://Python-Markdown.github.io/extensions/meta_data
7 | # for documentation.
8 |
9 | # Original code Copyright 2007-2008 [Waylan Limberg](http://achinghead.com).
10 |
11 | # All changes Copyright 2008-2014 The Python Markdown Project
12 |
13 | # License: [BSD](https://opensource.org/licenses/bsd-license.php)
14 |
15 | """
16 | This extension adds Meta Data handling to markdown.
17 |
18 | See the [documentation](https://Python-Markdown.github.io/extensions/meta_data)
19 | for details.
20 | """
21 |
22 | from __future__ import annotations
23 |
24 | from . import Extension
25 | from ..preprocessors import Preprocessor
26 | import re
27 | import logging
28 | from typing import Any
29 |
30 | log = logging.getLogger('MARKDOWN')
31 |
32 | # Global Vars
33 | META_RE = re.compile(r'^[ ]{0,3}(?P[A-Za-z0-9_-]+):\s*(?P.*)')
34 | META_MORE_RE = re.compile(r'^[ ]{4,}(?P.*)')
35 | BEGIN_RE = re.compile(r'^-{3}(\s.*)?')
36 | END_RE = re.compile(r'^(-{3}|\.{3})(\s.*)?')
37 |
38 |
39 | class MetaExtension (Extension):
40 | """ Meta-Data extension for Python-Markdown. """
41 |
42 | def extendMarkdown(self, md):
43 | """ Add `MetaPreprocessor` to Markdown instance. """
44 | md.registerExtension(self)
45 | self.md = md
46 | md.preprocessors.register(MetaPreprocessor(md), 'meta', 27)
47 |
48 | def reset(self) -> None:
49 | self.md.Meta = {}
50 |
51 |
52 | class MetaPreprocessor(Preprocessor):
53 | """ Get Meta-Data. """
54 |
55 | def run(self, lines: list[str]) -> list[str]:
56 | """ Parse Meta-Data and store in Markdown.Meta. """
57 | meta: dict[str, Any] = {}
58 | key = None
59 | if lines and BEGIN_RE.match(lines[0]):
60 | lines.pop(0)
61 | while lines:
62 | line = lines.pop(0)
63 | m1 = META_RE.match(line)
64 | if line.strip() == '' or END_RE.match(line):
65 | break # blank line or end of YAML header - done
66 | if m1:
67 | key = m1.group('key').lower().strip()
68 | value = m1.group('value').strip()
69 | try:
70 | meta[key].append(value)
71 | except KeyError:
72 | meta[key] = [value]
73 | else:
74 | m2 = META_MORE_RE.match(line)
75 | if m2 and key:
76 | # Add another line to existing key
77 | meta[key].append(m2.group('value').strip())
78 | else:
79 | lines.insert(0, line)
80 | break # no meta data - done
81 | self.md.Meta = meta
82 | return lines
83 |
84 |
85 | def makeExtension(**kwargs): # pragma: no cover
86 | return MetaExtension(**kwargs)
87 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/computerTools/audioUtils.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\computerTools\audioUtils.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2025 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 | from logHandler import log
8 | import config
9 | from ..utils.NVDAStrings import NVDAString
10 | from ..utils.nvdaInfos import NVDAVersion
11 |
12 |
13 | def isWasapiUsed():
14 | # nvda 2025.1 and above use Wasapi
15 | if NVDAVersion >= [2025, 1]:
16 | return True
17 |
18 | # wasapi can be used since nvda 2023.2
19 | # by checking the advanced option: use wasapi for audio output
20 | try:
21 | from nvwave import WasapiWavePlayer, WavePlayer
22 | if WavePlayer == WasapiWavePlayer:
23 | return True
24 | except Exception:
25 | pass
26 | return False
27 |
28 |
29 | def getOutputDevice():
30 | try:
31 | # for nvda version >= 2025.1
32 | return config.conf["audio"]["outputDevice"]
33 | except KeyError:
34 | # for nvda version < 2025.1
35 | return config.conf["speech"]["outputDevice"]
36 |
37 |
38 | def getOutputDeviceName(outputDevice):
39 | log.debug("getDeviceName: %s" % outputDevice)
40 | # for nvda >= 2025.1, outputDevice is stored in "audio" section instead of "speech" section
41 | # and it is stored by its id instead its name
42 | # else outputDevice is the output device name
43 | if "outputDevice" not in config.conf["audio"]:
44 | return outputDevice
45 | # for nvda version >= 2025.1
46 | deviceIds, deviceNames = get_outputDevices()
47 | try:
48 | outputDeviceName = deviceNames[deviceIds.index(outputDevice)]
49 | except ValueError:
50 | # We assume it is the default device
51 | outputDeviceName = deviceNames[0]
52 | if outputDeviceName is None:
53 | # Translators: name for default (Microsoft Sound Mapper) audio output device.
54 | outputDeviceName = NVDAString("Microsoft Sound Mapper")
55 | return outputDeviceName
56 |
57 |
58 | def setOutputDevice(device):
59 | if "outputDevice" in config.conf["audio"]:
60 | # for nvda version >= 2025.1
61 | config.conf["audio"]["outputDevice"] = device
62 | else:
63 | # for nvda version < 2025.1
64 | config.conf["speech"]["outputDevice"] = device
65 |
66 |
67 | def get_outputDevices():
68 | if NVDAVersion < [2025, 1]:
69 | from nvwave import _getOutputDevices
70 | devices = [(ID, name) for ID, name in _getOutputDevices()]
71 | deviceIds = [ID for ID, name in devices]
72 | deviceNames = [name for id, name in devices]
73 | # #11349: On Windows 10 20H1 and 20H2, Microsoft Sound Mapper returns an empty string.
74 | if deviceNames[0] in ("", "Microsoft Sound Mapper"):
75 | # Translators: name for default (Microsoft Sound Mapper) audio output device.
76 | deviceNames[0] = NVDAString("Microsoft Sound Mapper")
77 | else:
78 | from utils import mmdevice
79 | deviceIds, deviceNames = zip(*mmdevice.getOutputDevices(includeDefault=True))
80 | return deviceIds, deviceNames
81 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/tools/buildVars.py.tpl:
--------------------------------------------------------------------------------
1 | # -*- coding: UTF-8 -*-
2 |
3 | # Build customizations
4 | # Change this file instead of sconstruct or manifest files, whenever possible.
5 |
6 |
7 | # Since some strings in "addon_info" are translatable,
8 | # we need to include them in the .po files.
9 | # Gettext recognizes only strings given as parameters to the "_" function.
10 | # To avoid initializing translations in this module we simply roll our own "fake" "_" function
11 | # which returns whatever is given to it as an argument.
12 | def _(arg):
13 | return arg
14 |
15 | # Add-on information variables
16 | {addonInfoStart}
17 | # add-on Name/identifier, internal for NVDA
18 | "addon_name": "{name}",
19 | # Add-on summary, usually the user visible name of the addon.
20 | # Translators: Summary for this add-on to be shown
21 | # on installation and add-on information.
22 | "addon_summary": _("{summary}"),
23 | # Add-on description
24 | # Translators: Long description to be shown for this add-on
25 | # on add-on information from add-ons manager
26 | "addon_description": _("""{description}"""),
27 | # version
28 | "addon_version": "{version}",
29 | # Author(s)
30 | "addon_author": u"{author}",
31 | # URL for the add-on documentation support
32 | "addon_url": "{url}",
33 | # URL for the add-on repository where the source code can be found
34 | "addon_sourceURL": None,
35 | # Documentation file name
36 | "addon_docFileName": "{docFileName}",
37 | # Minimum NVDA version supported (e.g. "2018.3")
38 | "addon_minimumNVDAVersion": "{minimumNVDAVersion}",
39 | # Last NVDA version supported/tested
40 | # (e.g. "2018.4", ideally more recent than minimum version)
41 | "addon_lastTestedNVDAVersion": "{lastTestedNVDAVersion}",
42 | # Add-on update channel (default is stable or None)
43 | "addon_updateChannel": "{updateChannel}",
44 | # Add-on license such as GPL 2
45 | "addon_license": None,
46 | # URL for the license document the ad-on is licensed under
47 | "addon_licenseURL": None,
48 | {addonInfoEnd}
49 |
50 | # Define the python files that are the sources of your add-on.
51 | # You can use glob expressions here, they will be expanded.
52 | pythonSources = []
53 |
54 | # Files that contain strings for translation. Usually your python sources
55 | i18nSources = pythonSources
56 |
57 | # Files that will be ignored when building the nvda-addon file
58 | # Paths are relative to the addon directory,
59 | # not to the root directory of your addon sources.
60 | excludedFiles = []
61 |
62 | # If your add-on is written in a language other than english,
63 | # modify this variable.
64 | # For example:
65 | # set baseLanguage to "es" if your add-on is primarily written in spanish.
66 | baseLanguage = "en"
67 |
68 | # Markdown extensions for add-on documentation
69 | # Most add-ons do not require additional Markdown extensions.
70 | # If you need to add support for markup such as tables, fill out the below list.
71 | # Extensions string must be of the form "markdown.extensions.extensionName"
72 | # e.g. "markdown.extensions.tables" to add tables.
73 | markdownExtensions = []
74 |
--------------------------------------------------------------------------------
/addon/utilities/markdownEx/markdown/extensions/legacy_attrs.py:
--------------------------------------------------------------------------------
1 | # Python Markdown
2 |
3 | # A Python implementation of John Gruber's Markdown.
4 |
5 | # Documentation: https://python-markdown.github.io/
6 | # GitHub: https://github.com/Python-Markdown/markdown/
7 | # PyPI: https://pypi.org/project/Markdown/
8 |
9 | # Started by Manfred Stienstra (http://www.dwerg.net/).
10 | # Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org).
11 | # Currently maintained by Waylan Limberg (https://github.com/waylan),
12 | # Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser).
13 |
14 | # Copyright 2007-2023 The Python Markdown Project (v. 1.7 and later)
15 | # Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b)
16 | # Copyright 2004 Manfred Stienstra (the original version)
17 |
18 | # License: BSD (see LICENSE.md for details).
19 |
20 | """
21 | An extension to Python Markdown which implements legacy attributes.
22 |
23 | Prior to Python-Markdown version 3.0, the Markdown class had an `enable_attributes`
24 | keyword which was on by default and provided for attributes to be defined for elements
25 | using the format `{@key=value}`. This extension is provided as a replacement for
26 | backward compatibility. New documents should be authored using `attr_lists`. However,
27 | numerous documents exist which have been using the old attribute format for many
28 | years. This extension can be used to continue to render those documents correctly.
29 | """
30 |
31 | from __future__ import annotations
32 |
33 | import re
34 | from markdown.treeprocessors import Treeprocessor, isString
35 | from markdown.extensions import Extension
36 | from typing import TYPE_CHECKING
37 |
38 | if TYPE_CHECKING: # pragma: no cover
39 | import xml.etree.ElementTree as etree
40 |
41 |
42 | ATTR_RE = re.compile(r'\{@([^\}]*)=([^\}]*)}') # {@id=123}
43 |
44 |
45 | class LegacyAttrs(Treeprocessor):
46 | def run(self, doc: etree.Element) -> None:
47 | """Find and set values of attributes ({@key=value}). """
48 | for el in doc.iter():
49 | alt = el.get('alt', None)
50 | if alt is not None:
51 | el.set('alt', self.handleAttributes(el, alt))
52 | if el.text and isString(el.text):
53 | el.text = self.handleAttributes(el, el.text)
54 | if el.tail and isString(el.tail):
55 | el.tail = self.handleAttributes(el, el.tail)
56 |
57 | def handleAttributes(self, el: etree.Element, txt: str) -> str:
58 | """ Set attributes and return text without definitions. """
59 | def attributeCallback(match: re.Match[str]):
60 | el.set(match.group(1), match.group(2).replace('\n', ' '))
61 | return ATTR_RE.sub(attributeCallback, txt)
62 |
63 |
64 | class LegacyAttrExtension(Extension):
65 | def extendMarkdown(self, md):
66 | """ Add `LegacyAttrs` to Markdown instance. """
67 | md.treeprocessors.register(LegacyAttrs(md), 'legacyattrs', 15)
68 |
69 |
70 | def makeExtension(**kwargs): # pragma: no cover
71 | return LegacyAttrExtension(**kwargs)
72 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/clipboardCommandAnnouncement/clipboard.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\clipboardCommandAnnouncement\clipboard.py
2 | # a part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2022 Paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 | # some parts of code were inspired from the code of Clipboard_monitor.py module of clipSpeak add-on
8 | # written By Damien Lindley, created: 20th April 2017
9 |
10 | from winUser import user32
11 | from logHandler import log
12 |
13 |
14 | class ClipboardManager(object):
15 |
16 | def __init__(self):
17 | log.debug("Initialising clipboard manager.")
18 | self.sequenceNumber = user32.GetClipboardSequenceNumber()
19 | log.debug("clipboard manager init: current sequence number = %s" % self.sequenceNumber)
20 |
21 | def getClipboardDatas(self):
22 | log.debug("getting clipboard data...")
23 | data = {}
24 | log.debug("Opening the clipboard for enumeration.")
25 | try:
26 | user32.OpenClipboard(None)
27 | except Exception:
28 | log.debug("Clipboard failed to open. Cannot enumerate.")
29 | return data
30 | format = 0
31 | while True:
32 | try:
33 | format = user32.EnumClipboardFormats(format)
34 | log.debug("Retrieving clipboard format: %d" % format)
35 | if format == 0:
36 | break
37 | pos = str(format)
38 | log.debug("Retrieving data for format %s" % pos)
39 | data[pos] = user32.GetClipboardData(format)
40 | log.debug("Data retrieved: %r" % data[pos])
41 | except Exception:
42 | log.debug("Cannot retrieve data.")
43 | break
44 | log.debug("Closing clipboard.")
45 | user32.CloseClipboard()
46 | return data
47 |
48 | def changed(self):
49 | log.debug("Checking for clipboard changes.")
50 | sequenceNumber = user32.GetClipboardSequenceNumber()
51 | if sequenceNumber == self.sequenceNumber:
52 | log.debug("No changes detected.")
53 | return False
54 | log.debug("Clipboard data has changed. Updating sequence number: %s" % sequenceNumber)
55 | self.sequenceNumber = sequenceNumber
56 | return True
57 |
58 | @property
59 | def isEmpty(self):
60 | log.debug("check if clipboard is empty")
61 | log.debug("Opening the clipboard for enumeration.")
62 | try:
63 | user32.OpenClipboard(None)
64 | except Exception:
65 | log.debug("Clipboard failed to open. Cannot check")
66 | return False
67 | format = 0
68 | try:
69 | format = user32.EnumClipboardFormats(format)
70 | except Exception:
71 | log.debug("Cannot enumerate.")
72 | format = 1
73 | log.debug("Closing clipboard.")
74 | user32.CloseClipboard()
75 | return format == 0
76 |
77 | def clear(self):
78 | log.debug("Opening the clipboard for clearing.")
79 | try:
80 | user32.OpenClipboard(None)
81 | except Exception:
82 | log.debug("Clipboard failed to open. Cannot clear.")
83 | return False
84 | res = user32.EmptyClipboard()
85 | if not res:
86 | log.debug("Clipboard failed to clear. Cannot clear.")
87 | user32.CloseClipboard()
88 | log.debug("clipboard is cleared")
89 | return res
90 |
--------------------------------------------------------------------------------
/addon/locale/tr/symbolCategories.dic:
--------------------------------------------------------------------------------
1 | #the symbols and their description are divided in category and each category is defined by a section beginning with the category name enclosed between brackets.
2 | # Each line of a section define a symbol with its description:
3 | #- the symbol (one caracter)
4 | #- the "Tab" separator
5 | #- the symbol description
6 |
7 | [Küçük harf aksanlı ünlüler]
8 | á vurgulu küçük a
9 | é vurgulu küçük e
10 | í vurgulu küçük i
11 | ó vurgulu küçük o
12 | ú vurgulu küçük u
13 | ý vurgulu küçük y
14 | à aksanlı küçük a
15 | è aksanlı küçük e
16 | ì aksanlı küçük i
17 | ò aksanlı küçük o
18 | ù aksanlı küçük u
19 | â ince küçük a
20 | ê ince küçük e
21 | î ince küçük i
22 | ô ince küçük o
23 | û ince küçük u
24 | ã tildeli küçük a
25 | ñ tildeli küçük n
26 | õ tildeli küçük o
27 | ä çift noktalı küçük a
28 | ë çift noktalı küçük e
29 | ï çift noktalı küçük i
30 | ö ö
31 | ü ü
32 |
33 | [Büyük aksanlı ünlüler]
34 | Á vurgulu büyük a
35 | É vurgulu büyük e
36 | Í vurgulu büyük i
37 | Ó vurgulu büyük o
38 | Ú vurgulu büyük u
39 | Ý vurgulu büyük y
40 | À aksanlı büyük a
41 | È aksanlı büyük e
42 | Ì aksanlı büyük i
43 | Ò aksanlı büyük o
44 | Ù aksanlı büyük u
45 | Â ince büyük a
46 | Ê ince büyük e
47 | Î ince büyük i
48 | Ô ince büyük o
49 | Û ince büyük u
50 | Ã tildeli büyük a
51 | Ñ tildeli büyük n
52 | Õ tildeli büyük o
53 | Ä çift noktalı büyük a
54 | Ë çift noktalı büyük e
55 | Ï çift noktalı büyük i
56 | Ö Ö
57 | Ü Ü
58 |
59 | [parasal semboller]
60 | € Avro para birimi
61 | $ Dolar işareti
62 | ¢ sent işareti
63 | £ İngiliz Sterlini
64 | ¥ Japon Yeni
65 | ƒ Hollanda Florini
66 | ₺ türk lirası
67 | ¤ Genel para birimi sembolü
68 |
69 | [Matematik sembolleri]
70 | ÷ bölüm işareti
71 | × çarpma işareti
72 | ± Artı/eksi
73 | ¹ üssü 1
74 | ² üssü 2
75 | ³ üssü 3
76 | ⁿ üssü N
77 | ° derece sembolü
78 | µ Mikro
79 | ‰ binde işareti
80 | ‰ milyonda
81 | ¼ kesir 1/4
82 | ½ kesir 1/2
83 | ¾ kesir 3/4
84 | ⅛ kesir Sekizde Bir
85 | ⅜ kesir sekizde üç
86 | ⅞ kesir sekizde yedi
87 | ¬ mantıkda değil
88 | ≠ eşit değil
89 | ≤ eşit veya küçük
90 | ≥ eşit veya büyük
91 | ∞ sonsuz
92 | ∫ İntegral İşareti
93 | ∂ Kısmi türev İşareti
94 | ∆ artım işareti
95 | ∏ çarpım işareti
96 | ∑ toplam işareti
97 | √ Kare Kök İşareti
98 | ∟ dik açı işareti
99 | ∩ kesişim işareti
100 | ƒ İşlev İşareti
101 |
102 | [noktalama işaretleri]
103 | … üç nokta
104 | ince tire
105 | • madde imi
106 | ∙ madde imi işleci
107 | ‣ üçgen madde imi
108 | ¦ kırık çizgi
109 | boşluksuz aralık
110 | § bölüm sembolü
111 | ¶ Paragraf Sembolü (Yastık)
112 | † kama işareti
113 | ‡ çift kama işareti
114 | “ çift tırnak aç
115 | ” çift tırnak kapa
116 | ‚ tek alt tırnak
117 | „ çift alt tırnak
118 | ‹ tek üçgen tırnak aç
119 | › tek üçgen tırnak kapa
120 | « çift kancalı parantez aç
121 | » çift kancalı parantez kapa
122 | ince tire
123 | – orta tire
124 | — uzun tire
125 | ℅ koruma işareti
126 | ― yatay çizgi
127 | ‾ üst çizgi
128 | ‼ çift ünlem
129 | ♦ siyah karo
130 | & ve
131 |
132 | [Diğer semboller]
133 | © Telif hakkı sembolü
134 | ® kayıtlı sembolü
135 | ™ Marka
136 | Æ büyük A-E
137 | æ A-E
138 | Œ büyük O-E
139 | œ O-E
140 | Ø büyük iskandinav O
141 | ø iskandinav O slash
142 | º Eril Sıra Sayısı
143 | ª dişil sıra sayısı
144 | ¡ ters ünlem
145 | ¿ ters soru
146 | ¯ makron
147 | Å Büyük A, halka (angström)
148 | å Küçük a, halka
149 | Þ Büyük Thorn, İzlandaca
150 | þ Küçük Thorn, İzlandaca
151 | Ð Büyük Eth, İzlandaca
152 | ð Küçük Eth, İzlandaca
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/commandKeysSelectiveAnnouncementAndRemanence/patchs.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\commandKeysSelectiveAnnouncementAndRemanence\commandKeysSelectiveAnnouncementAndRemanencePatches.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2024 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 | from logHandler import log
8 | import inputCore
9 | from inputCore import NoInputGestureAction
10 | from ..settings import isInstall
11 | from ..settings import addonConfig
12 | from keyboardHandler import KeyboardInputGesture
13 |
14 |
15 | # global variables to save NVDA patched variables and methods
16 | _NVDAInputCoreManager = None
17 | _NVDAInputCoreManagerExecuteGesture = None
18 |
19 |
20 | def myExecuteGesture(gesture):
21 | log.debug("MyExecuteGesture: %s,%s" % (gesture.identifiers[0], gesture.__class__))
22 | try:
23 | if isinstance(gesture, KeyboardInputGesture):
24 | log.debug("gesture: vkCode= %s, scanCode= %s, isextended= %s, modifiers= %s" % (
25 | gesture.vkCode, gesture.scanCode, gesture.isExtended, gesture.modifiers))
26 | from ..commandKeysSelectiveAnnouncementAndRemanence import _myInputManager
27 | _myInputManager.executeKeyboardGesture(gesture)
28 | else:
29 | log.debug("Gesture executed by: %s.%s" % (
30 | _NVDAInputCoreManagerExecuteGesture.__module__, _NVDAInputCoreManagerExecuteGesture.__name__))
31 | _NVDAInputCoreManagerExecuteGesture(gesture)
32 | except NoInputGestureAction:
33 | log.debug("myExecuteGesture exception NoInputGestureAction")
34 | raise NoInputGestureAction
35 |
36 |
37 | def patche(install=True):
38 | if not install:
39 | removePatch()
40 | return
41 | if not (
42 | isInstall(addonConfig.FCT_CommandKeysSelectiveAnnouncement)
43 | or isInstall(addonConfig.FCT_KeyRemanence)):
44 | return
45 | global _NVDAInputCoreManager, _NVDAInputCoreManagerExecuteGesture
46 | _NVDAInputCoreManager = inputCore.manager
47 | if _NVDAInputCoreManager .__module__ != "inputCore":
48 | log.warning(
49 | "Incompatibility: imput.manager variable has also been patched"
50 | " probably by another add-on: %s of %s module. "
51 | "There is a risk of malfunction" % (_NVDAInputCoreManager.__name__, _NVDAInputCoreManager.__module__))
52 | _NVDAInputCoreManagerExecuteGesture = inputCore.manager.executeGesture
53 | if _NVDAInputCoreManagerExecuteGesture .__module__ != "inputCore":
54 | log.warning(
55 | "Incompatibility: inputCore.manager.executeGesture manager has also been patched probably"
56 | " by another add-on:"
57 | " %s of %s. There is a risk of malfunction" % (
58 | _NVDAInputCoreManagerExecuteGesture .__name__, _NVDAInputCoreManagerExecuteGesture .__module__))
59 | inputCore.manager.executeGesture = myExecuteGesture
60 | log.debug(
61 | "For command selective announcement and key remanence functionnalities,"
62 | " NVDA core manager executeGesture method has been replaced"
63 | " by %s method of %s module" % (
64 | inputCore.manager.executeGesture.__name__, inputCore.manager.executeGesture .__module__))
65 |
66 |
67 | def removePatch():
68 | global _NVDAInputCoreManager
69 | global _NVDAInputCoreManagerExecuteGesture
70 | if _NVDAInputCoreManager is not None:
71 | inputCore.manager = _NVDAInputCoreManager
72 | _NVDAInputCoreManager = None
73 | if _NVDAInputCoreManagerExecuteGesture is not None:
74 | inputCore.manager.executeGesture = _NVDAInputCoreManagerExecuteGesture
75 | _NVDAInputCoreManagerExecuteGesture = None
76 |
--------------------------------------------------------------------------------
/addon/locale/ar/symbolCategories.dic:
--------------------------------------------------------------------------------
1 | #the symbols and their description are divided in category and each category is defined by a section beginning with the category name enclosed between brackets.
2 | # Each line of a section define a symbol with its description:
3 | #- the symbol (one caracter)
4 | #- the "Tab" separator
5 | #- the symbol description
6 |
7 | [حروف العلة الصغيرة]
8 | á a acute
9 | é e acute
10 | í i acute
11 | ó o acute
12 | ú u acute
13 | ý y acute
14 | à a accent grave
15 | è e grave
16 | ì i grave
17 | ò o grave
18 | ù u grave
19 | â a circunflex
20 | ê e circunflex
21 | î i circunflex
22 | ô o circunflex
23 | û u circunflex
24 | ã a tilde
25 | ñ n tilde
26 | õ o tilde
27 | ä a umloat
28 | ë e umloat
29 | ï i umloat
30 | ö o umloat
31 | ü u umloat
32 |
33 | [حروف العلة الكبيرة]
34 | Á A acute capital
35 | É E acute capital
36 | Í I acute capital
37 | Ó O acute capital
38 | Ú U acute capital
39 | Ý Y acute capital
40 | À a grave capitale
41 | È e grave capitale
42 | Ì i grave capitale
43 | Ò o grave capitale
44 | Ù u grave capitale
45 | Â a circunflex capitale
46 | Ê e circunflex capitale
47 | Î i circunflex capitale
48 | Ô o circunflex capitale
49 | Û u circunflex capitale
50 | Ã a tilde capitale
51 | Ñ n tilde capitale
52 | Õ o tilde capitale
53 | Ä a umloat capitale
54 | Ë e umloat capitale
55 | Ï i umloat capitale
56 | Ö o umloat capitale
57 | Ü u umloat capitale
58 | [رموز العملات]
59 |
60 | € Euro currency
61 | $ Dollar Sign
62 | ¢ Cent sign
63 | £ British Pound
64 | ¥ Japanese Yen
65 | ƒ Dutch Florin
66 | ¤ Generic currency symbol
67 |
68 | [الرموز الرياضية]
69 |
70 | ÷ Division sign
71 | × Multiplication Sign
72 | ± Plus/minus
73 | ¹ Superscript 1
74 | ² Superscript 2
75 | ³ Superscript 3
76 | ⁿ Superscript N
77 | ° Degree symbol
78 | µ Micro
79 | ‰ Per Mille sign (1/1000th)
80 | ‰ Per Million
81 | ¼ Fraction 1/4
82 | ½ Fraction 1/2
83 | ¾ Fraction 3/4
84 | ⅛ One Eighth Fraction
85 | ⅜ Three Eighths Fraction
86 | ⅞ Seven Eighths Fraction
87 | ¬ Not symbol logic
88 | ≠ Not Equal To Sign
89 | ≤ Less Than or Equal To Sign
90 | ≥ Greater Than or Equal To Sign
91 | ∞ Infinity Sign
92 | ∫ Integral Sign
93 | ∂ Partial Differential Sign
94 | ∆ Increment Sign
95 | ∏ N-ary Product Sign
96 | ∑ N-ary Sum Sign
97 | √ Square Root Sign
98 | ∟ Right Angle Sign
99 | ∩ Intersection Sign
100 | ƒ Function Sign
101 | [علامات الترقيم]
102 |
103 | … نقطة نقطة نقطة
104 | Dash
105 | • List Dot
106 | ∙ Bullet Operator
107 | ‣ Triangle Bullet
108 | ¦ Broken Vertical Bar
109 | مسافة
110 | § قسم
111 | ¶ المؤشر الى اليسار
112 | † خنجر
113 | ‡ خنجر مزدوج
114 | “ فتح تنصيص
115 | ” مغلق تنصيص
116 | ‚ إقتباس واحد منخفض
117 | „ علامة تنصيص مزدوجة
118 | ‹ زاوية إقتباس واحدة
119 | › زاوية إقتباسواحدة يمين
120 | « زاوية إقتباس يسار
121 | » زاوية إقتباس الحقل
122 | وصلة ناعمة
123 | – em-dash
124 | — em-dash
125 | ℅ رعاية
126 | ― شريط أفقي
127 | ‾ خط إضافي
128 | ‼ تعجب مزدوج
129 | ♦ ورقة لعب بشكل ماسي
130 | & علامة العطف
131 | [رموز أخرى]
132 | © علامة حقوق النشر
133 | ® مسجل
134 | ™ علامة تجارية
135 | Ç الفرنسية C cedille capitale
136 | ç French C cedille
137 | Æ A-E ligature capitale
138 | æ A-E ligature
139 | Œ O-E ligature capitale
140 | œ O-E ligature
141 | Ø شمالي مائل كبيرة
142 | ø شمال مائل
143 | º ترتيب عدد مذكر
144 | ª ترتيب عدد مؤنث
145 | ¡ علامة تعجب مقلوبة
146 | ¿ علامة استفهام مقلوبة
147 | ¯ Macron accent
148 | Å Uppercase A, ring (angström)
149 | å Lowercase a, ring
150 | Þ Uppercase Thorn, Icelandic
151 | þ Lowercase Thorn, Icelandic
152 | Ð Uppercase Eth, Icelandic
153 | ð Lowercase Eth, Icelandic
--------------------------------------------------------------------------------
/addon/utilities/markdownEx/markdown/preprocessors.py:
--------------------------------------------------------------------------------
1 | # Python Markdown
2 |
3 | # A Python implementation of John Gruber's Markdown.
4 |
5 | # Documentation: https://python-markdown.github.io/
6 | # GitHub: https://github.com/Python-Markdown/markdown/
7 | # PyPI: https://pypi.org/project/Markdown/
8 |
9 | # Started by Manfred Stienstra (http://www.dwerg.net/).
10 | # Maintained for a few years by Yuri Takhteyev (http://www.freewisdom.org).
11 | # Currently maintained by Waylan Limberg (https://github.com/waylan),
12 | # Dmitry Shachnev (https://github.com/mitya57) and Isaac Muse (https://github.com/facelessuser).
13 |
14 | # Copyright 2007-2023 The Python Markdown Project (v. 1.7 and later)
15 | # Copyright 2004, 2005, 2006 Yuri Takhteyev (v. 0.2-1.6b)
16 | # Copyright 2004 Manfred Stienstra (the original version)
17 |
18 | # License: BSD (see LICENSE.md for details).
19 |
20 | """
21 | Preprocessors work on source text before it is broken down into its individual parts.
22 | This is an excellent place to clean up bad characters or to extract portions for later
23 | processing that the parser may otherwise choke on.
24 | """
25 |
26 | from __future__ import annotations
27 |
28 | from typing import TYPE_CHECKING, Any
29 | from . import util
30 | from .htmlparser import HTMLExtractor
31 | import re
32 |
33 | if TYPE_CHECKING: # pragma: no cover
34 | from markdown import Markdown
35 |
36 |
37 | def build_preprocessors(md: Markdown, **kwargs: Any) -> util.Registry[Preprocessor]:
38 | """ Build and return the default set of preprocessors used by Markdown. """
39 | preprocessors = util.Registry()
40 | preprocessors.register(NormalizeWhitespace(md), 'normalize_whitespace', 30)
41 | preprocessors.register(HtmlBlockPreprocessor(md), 'html_block', 20)
42 | return preprocessors
43 |
44 |
45 | class Preprocessor(util.Processor):
46 | """
47 | Preprocessors are run after the text is broken into lines.
48 |
49 | Each preprocessor implements a `run` method that takes a pointer to a
50 | list of lines of the document, modifies it as necessary and returns
51 | either the same pointer or a pointer to a new list.
52 |
53 | Preprocessors must extend `Preprocessor`.
54 |
55 | """
56 | def run(self, lines: list[str]) -> list[str]:
57 | """
58 | Each subclass of `Preprocessor` should override the `run` method, which
59 | takes the document as a list of strings split by newlines and returns
60 | the (possibly modified) list of lines.
61 |
62 | """
63 | pass # pragma: no cover
64 |
65 |
66 | class NormalizeWhitespace(Preprocessor):
67 | """ Normalize whitespace for consistent parsing. """
68 |
69 | def run(self, lines: list[str]) -> list[str]:
70 | source = '\n'.join(lines)
71 | source = source.replace(util.STX, "").replace(util.ETX, "")
72 | source = source.replace("\r\n", "\n").replace("\r", "\n") + "\n\n"
73 | source = source.expandtabs(self.md.tab_length)
74 | source = re.sub(r'(?<=\n) +\n', '\n', source)
75 | return source.split('\n')
76 |
77 |
78 | class HtmlBlockPreprocessor(Preprocessor):
79 | """
80 | Remove html blocks from the text and store them for later retrieval.
81 |
82 | The raw HTML is stored in the [`htmlStash`][markdown.util.HtmlStash] of the
83 | [`Markdown`][markdown.Markdown] instance.
84 | """
85 |
86 | def run(self, lines: list[str]) -> list[str]:
87 | source = '\n'.join(lines)
88 | parser = HTMLExtractor(self.md)
89 | parser.feed(source)
90 | parser.close()
91 | return ''.join(parser.cleandoc).split('\n')
92 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/tools/gettextTools.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\tools\gettextTools.py
2 | # a part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2016 -2020 Paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 |
8 | import addonHandler
9 | import subprocess
10 | import os
11 | import glob
12 | from ..utils.py3Compatibility import getCommonUtilitiesPath
13 |
14 | addonHandler.initTranslation()
15 |
16 | XGETTEXT_COMMON_ARGS = (
17 | "--from-code=utf-8 "
18 | "--msgid-bugs-address\"={gettext_package_bugs_address}\" "
19 | "--package-name=\"{gettext_package_name}\" "
20 | "--package-version=\"{gettext_package_version}\" "
21 | "-c -o \"{TARGET}\" -D \"{inputDirectory}\" {SOURCES}"
22 | )
23 |
24 |
25 | def getI18nSources(addon, buildVarsI18nSources):
26 | i18nSources = []
27 | for path in buildVarsI18nSources:
28 | pathList = path.split("\\")
29 | if pathList[0] == "addon":
30 | pathList = pathList[1:]
31 | p = os.path.join(addon.path, "\\".join(pathList))
32 | if "*" in pathList[-1]:
33 | files = glob.glob(p)
34 | i18nSources .extend(files)
35 | else:
36 | i18nSources .append(p)
37 | return i18nSources
38 |
39 |
40 | def generatePotFile(
41 | addon, potFileName, buildVarsAddonInfo, buildVarsI18nSources):
42 | gettextVars = {
43 | 'gettext_package_bugs_address': buildVarsAddonInfo['addon_author'],
44 | 'gettext_package_name': buildVarsAddonInfo['addon_name'],
45 | 'gettext_package_version': buildVarsAddonInfo['addon_version']
46 | }
47 | addonPath = addon.path
48 | potFileDir = os.path.join(addonPath, "locale", "en")
49 | files = glob.glob(os.path.join(potFileDir, "*.pot"))
50 | for f in files:
51 | os.remove(f)
52 |
53 | if not os.path.exists(potFileDir):
54 | os.mkdir(potFileDir)
55 | potFile = os.path.join(potFileDir, potFileName)
56 | i18nSources = getI18nSources(addon, buildVarsI18nSources)
57 | if len(i18nSources) == 0:
58 | return -1
59 | gettextVars["TARGET"] = potFile
60 | gettextVars["inputDirectory"] = addonPath
61 | utilitiesPath = getCommonUtilitiesPath()
62 | xgettextPath = os.path.join(utilitiesPath, "xgettext.exe")
63 | sources = ""
64 | for item in i18nSources:
65 | f = item.replace(addon.path + "\\", "")
66 | sources = sources + " " + "\"%s\"" % f
67 | gettextVars["SOURCES"] = sources
68 | commandLine = xgettextPath + " " + XGETTEXT_COMMON_ARGS
69 | commandLine = commandLine.format(**gettextVars)
70 | p = subprocess.Popen(commandLine)
71 | retval = p.wait()
72 | return retval
73 |
74 |
75 | def compilePoFiles(addon):
76 | utilitiesPath = getCommonUtilitiesPath()
77 | msgfmtPath = os.path.join(utilitiesPath, "msgfmt.exe")
78 | prefixe = "nvda"
79 | localeDir = os.path.join(addon.path, "locale")
80 | poFiles = []
81 | for root, directories, files in os.walk(localeDir):
82 | for filename in files:
83 | if os.path.isdir(filename):
84 | continue
85 | if not filename.endswith(".po"):
86 | continue
87 | poFiles.append(os.path.join(root, filename))
88 | count = 0
89 | for poFile in poFiles:
90 | moPath = os.path.split(poFile)[0]
91 | moFile = os.path.join(moPath, "%s.mo" % prefixe)
92 | if os.path.exists(moFile):
93 | os.remove(moFile)
94 | commandLine = [
95 | "\"%s\"" % msgfmtPath,
96 | "-o",
97 | "\"%s\"" % moFile,
98 | "\"%s\"" % poFile]
99 | commandLine = " ".join(commandLine)
100 | p = subprocess.Popen(commandLine)
101 | retval = p.wait()
102 | if retval == 0:
103 | count += 1
104 | return (count, len(poFiles))
105 |
--------------------------------------------------------------------------------
/addon/utilities/markdownEx/markdown/extensions/wikilinks.py:
--------------------------------------------------------------------------------
1 | # WikiLinks Extension for Python-Markdown
2 | # ======================================
3 |
4 | # Converts [[WikiLinks]] to relative links.
5 |
6 | # See https://Python-Markdown.github.io/extensions/wikilinks
7 | # for documentation.
8 |
9 | # Original code Copyright [Waylan Limberg](http://achinghead.com/).
10 |
11 | # All changes Copyright The Python Markdown Project
12 |
13 | # License: [BSD](https://opensource.org/licenses/bsd-license.php)
14 |
15 | """
16 | Converts `[[WikiLinks]]` to relative links.
17 |
18 | See the [documentation](https://Python-Markdown.github.io/extensions/wikilinks)
19 | for details.
20 | """
21 |
22 | from __future__ import annotations
23 |
24 | from . import Extension
25 | from ..inlinepatterns import InlineProcessor
26 | import xml.etree.ElementTree as etree
27 | import re
28 | from typing import Any
29 |
30 |
31 | def build_url(label: str, base: str, end: str) -> str:
32 | """ Build a URL from the label, a base, and an end. """
33 | clean_label = re.sub(r'([ ]+_)|(_[ ]+)|([ ]+)', '_', label)
34 | return '{}{}{}'.format(base, clean_label, end)
35 |
36 |
37 | class WikiLinkExtension(Extension):
38 | """ Add inline processor to Markdown. """
39 |
40 | def __init__(self, **kwargs):
41 | self.config = {
42 | 'base_url': ['/', 'String to append to beginning or URL.'],
43 | 'end_url': ['/', 'String to append to end of URL.'],
44 | 'html_class': ['wikilink', 'CSS hook. Leave blank for none.'],
45 | 'build_url': [build_url, 'Callable formats URL from label.'],
46 | }
47 | """ Default configuration options. """
48 | super().__init__(**kwargs)
49 |
50 | def extendMarkdown(self, md):
51 | self.md = md
52 |
53 | # append to end of inline patterns
54 | WIKILINK_RE = r'\[\[([\w0-9_ -]+)\]\]'
55 | wikilinkPattern = WikiLinksInlineProcessor(WIKILINK_RE, self.getConfigs())
56 | wikilinkPattern.md = md
57 | md.inlinePatterns.register(wikilinkPattern, 'wikilink', 75)
58 |
59 |
60 | class WikiLinksInlineProcessor(InlineProcessor):
61 | """ Build link from `wikilink`. """
62 |
63 | def __init__(self, pattern: str, config: dict[str, Any]):
64 | super().__init__(pattern)
65 | self.config = config
66 |
67 | def handleMatch(self, m: re.Match[str], data: str) -> tuple[etree.Element | str, int, int]:
68 | if m.group(1).strip():
69 | base_url, end_url, html_class = self._getMeta()
70 | label = m.group(1).strip()
71 | url = self.config['build_url'](label, base_url, end_url)
72 | a = etree.Element('a')
73 | a.text = label
74 | a.set('href', url)
75 | if html_class:
76 | a.set('class', html_class)
77 | else:
78 | a = ''
79 | return a, m.start(0), m.end(0)
80 |
81 | def _getMeta(self) -> tuple[str, str, str]:
82 | """ Return meta data or `config` data. """
83 | base_url = self.config['base_url']
84 | end_url = self.config['end_url']
85 | html_class = self.config['html_class']
86 | if hasattr(self.md, 'Meta'):
87 | if 'wiki_base_url' in self.md.Meta:
88 | base_url = self.md.Meta['wiki_base_url'][0]
89 | if 'wiki_end_url' in self.md.Meta:
90 | end_url = self.md.Meta['wiki_end_url'][0]
91 | if 'wiki_html_class' in self.md.Meta:
92 | html_class = self.md.Meta['wiki_html_class'][0]
93 | return base_url, end_url, html_class
94 |
95 |
96 | def makeExtension(**kwargs): # pragma: no cover
97 | return WikiLinkExtension(**kwargs)
98 |
--------------------------------------------------------------------------------
/addon/locale/cs/symbolCategories.dic:
--------------------------------------------------------------------------------
1 | #the symbols and their description are divided in category and each category is defined by a section beginning with the category name enclosed between brackets.
2 | # Each line of a section define a symbol with its description:
3 | #- the symbol (one caracter)
4 | #- the "Tab" separator
5 | #- the symbol description
6 |
7 | [Lower-case accented vowels]
8 | á a acute
9 | é e acute
10 | í i acute
11 | ó o acute
12 | ú u acute
13 | ý y acute
14 | à a accent grave
15 | è e grave
16 | ì i grave
17 | ò o grave
18 | ù u grave
19 | â a circunflex
20 | ê e circunflex
21 | î i circunflex
22 | ô o circunflex
23 | û u circunflex
24 | ã a tilde
25 | ñ n tilde
26 | õ o tilde
27 | ä a umloat
28 | ë e umloat
29 | ï i umloat
30 | ö o umloat
31 | ü u umloat
32 |
33 | [Capital accented vowels]
34 | Á A acute capital
35 | É E acute capital
36 | Í I acute capital
37 | Ó O acute capital
38 | Ú U acute capital
39 | Ý Y acute capital
40 | À a grave capitale
41 | È e grave capitale
42 | Ì i grave capitale
43 | Ò o grave capitale
44 | Ù u grave capitale
45 | Â a circunflex capitale
46 | Ê e circunflex capitale
47 | Î i circunflex capitale
48 | Ô o circunflex capitale
49 | Û u circunflex capitale
50 | Ã a tilde capitale
51 | Ñ n tilde capitale
52 | Õ o tilde capitale
53 | Ä a umloat capitale
54 | Ë e umloat capitale
55 | Ï i umloat capitale
56 | Ö o umloat capitale
57 | Ü u umloat capitale
58 |
59 | [Moneytary symbols]
60 | € Euro currency
61 | $ Dollar Sign
62 | ¢ Cent sign
63 | £ British Pound
64 | ¥ Japanese Yen
65 | ƒ Dutch Florin
66 | ¤ Generic currency symbol
67 |
68 | [Math symbols]
69 | ÷ Division sign
70 | × Multiplication Sign
71 | ± Plus/minus
72 | ¹ Superscript 1
73 | ² Superscript 2
74 | ³ Superscript 3
75 | ⁿ Superscript N
76 | ° Degree symbol
77 | µ Micro
78 | ‰ Per Mille sign (1/1000th)
79 | ‰ Per Million
80 | ¼ Fraction 1/4
81 | ½ Fraction 1/2
82 | ¾ Fraction 3/4
83 | ⅛ One Eighth Fraction
84 | ⅜ Three Eighths Fraction
85 | ⅞ Seven Eighths Fraction
86 | ¬ Not symbol logic
87 | ≠ Not Equal To Sign
88 | ≤ Less Than or Equal To Sign
89 | ≥ Greater Than or Equal To Sign
90 | ∞ Infinity Sign
91 | ∫ Integral Sign
92 | ∂ Partial Differential Sign
93 | ∆ Increment Sign
94 | ∏ N-ary Product Sign
95 | ∑ N-ary Sum Sign
96 | √ Square Root Sign
97 | ∟ Right Angle Sign
98 | ∩ Intersection Sign
99 | ƒ Function Sign
100 |
101 | [Punctuation symbols]
102 | … Elipsis
103 | Dash
104 | • List Dot
105 | ∙ Bullet Operator
106 | ‣ Triangle Bullet
107 | ¦ Broken Vertical Bar
108 | Non-breaking space
109 | § Section Symbol
110 | ¶ Paragraph Symbol (Pilcrow)
111 | † Dagger
112 | ‡ Double Dagger
113 | “ Left Double Quote
114 | ” Right Double Quote
115 | ‚ Single Low Quote
116 | „ Double Low Quote
117 | ‹ Left Single Angle Quote
118 | › Right Single Angle Quote
119 | « Left Angle Quote
120 | » Right Angle Quote
121 | Soft Hyphen
122 | – en-dash
123 | — em-dash
124 | ℅ Care Of
125 | ― Horizontal Bar
126 | ‾ Overline
127 | ‼ Double exclamation mark
128 | ♦ Diamonds card
129 | & Ampersand
130 |
131 | [Other symbols]
132 | © Copyright symbol
133 | ® Registered symbol
134 | ™ Trademark
135 | Ç French C cedille capitale
136 | ç French C cedille
137 | Æ A-E ligature capitale
138 | æ A-E ligature
139 | Œ O-E ligature capitale
140 | œ O-E ligature
141 | Ø Nordic O slash capitale
142 | ø Nordic O slash
143 | º Masculine Ordinal Number
144 | ª Feminine Ordinal Number
145 | ¡ Upside-down exclamation mark
146 | ¿ Upside-down question mark
147 | ¯ Macron accent
148 | Å Uppercase A, ring (angström)
149 | å Lowercase a, ring
150 | Þ Uppercase Thorn, Icelandic
151 | þ Lowercase Thorn, Icelandic
152 | Ð Uppercase Eth, Icelandic
153 | ð Lowercase Eth, Icelandic
--------------------------------------------------------------------------------
/addon/locale/da/symbolCategories.dic:
--------------------------------------------------------------------------------
1 | #the symbols and their description are divided in category and each category is defined by a section beginning with the category name enclosed between brackets.
2 | # Each line of a section define a symbol with its description:
3 | #- the symbol (one caracter)
4 | #- the "Tab" separator
5 | #- the symbol description
6 |
7 | [Lower-case accented vowels]
8 | á a acute
9 | é e acute
10 | í i acute
11 | ó o acute
12 | ú u acute
13 | ý y acute
14 | à a accent grave
15 | è e grave
16 | ì i grave
17 | ò o grave
18 | ù u grave
19 | â a circunflex
20 | ê e circunflex
21 | î i circunflex
22 | ô o circunflex
23 | û u circunflex
24 | ã a tilde
25 | ñ n tilde
26 | õ o tilde
27 | ä a umloat
28 | ë e umloat
29 | ï i umloat
30 | ö o umloat
31 | ü u umloat
32 |
33 | [Capital accented vowels]
34 | Á A acute capital
35 | É E acute capital
36 | Í I acute capital
37 | Ó O acute capital
38 | Ú U acute capital
39 | Ý Y acute capital
40 | À a grave capitale
41 | È e grave capitale
42 | Ì i grave capitale
43 | Ò o grave capitale
44 | Ù u grave capitale
45 | Â a circunflex capitale
46 | Ê e circunflex capitale
47 | Î i circunflex capitale
48 | Ô o circunflex capitale
49 | Û u circunflex capitale
50 | Ã a tilde capitale
51 | Ñ n tilde capitale
52 | Õ o tilde capitale
53 | Ä a umloat capitale
54 | Ë e umloat capitale
55 | Ï i umloat capitale
56 | Ö o umloat capitale
57 | Ü u umloat capitale
58 |
59 | [Moneytary symbols]
60 | € Euro currency
61 | $ Dollar Sign
62 | ¢ Cent sign
63 | £ British Pound
64 | ¥ Japanese Yen
65 | ƒ Dutch Florin
66 | ¤ Generic currency symbol
67 |
68 | [Math symbols]
69 | ÷ Division sign
70 | × Multiplication Sign
71 | ± Plus/minus
72 | ¹ Superscript 1
73 | ² Superscript 2
74 | ³ Superscript 3
75 | ⁿ Superscript N
76 | ° Degree symbol
77 | µ Micro
78 | ‰ Per Mille sign (1/1000th)
79 | ‰ Per Million
80 | ¼ Fraction 1/4
81 | ½ Fraction 1/2
82 | ¾ Fraction 3/4
83 | ⅛ One Eighth Fraction
84 | ⅜ Three Eighths Fraction
85 | ⅞ Seven Eighths Fraction
86 | ¬ Not symbol logic
87 | ≠ Not Equal To Sign
88 | ≤ Less Than or Equal To Sign
89 | ≥ Greater Than or Equal To Sign
90 | ∞ Infinity Sign
91 | ∫ Integral Sign
92 | ∂ Partial Differential Sign
93 | ∆ Increment Sign
94 | ∏ N-ary Product Sign
95 | ∑ N-ary Sum Sign
96 | √ Square Root Sign
97 | ∟ Right Angle Sign
98 | ∩ Intersection Sign
99 | ƒ Function Sign
100 |
101 | [Punctuation symbols]
102 | … Elipsis
103 | Dash
104 | • List Dot
105 | ∙ Bullet Operator
106 | ‣ Triangle Bullet
107 | ¦ Broken Vertical Bar
108 | Non-breaking space
109 | § Section Symbol
110 | ¶ Paragraph Symbol (Pilcrow)
111 | † Dagger
112 | ‡ Double Dagger
113 | “ Left Double Quote
114 | ” Right Double Quote
115 | ‚ Single Low Quote
116 | „ Double Low Quote
117 | ‹ Left Single Angle Quote
118 | › Right Single Angle Quote
119 | « Left Angle Quote
120 | » Right Angle Quote
121 | Soft Hyphen
122 | – en-dash
123 | — em-dash
124 | ℅ Care Of
125 | ― Horizontal Bar
126 | ‾ Overline
127 | ‼ Double exclamation mark
128 | ♦ Diamonds card
129 | & Ampersand
130 |
131 | [Other symbols]
132 | © Copyright symbol
133 | ® Registered symbol
134 | ™ Trademark
135 | Ç French C cedille capitale
136 | ç French C cedille
137 | Æ A-E ligature capitale
138 | æ A-E ligature
139 | Œ O-E ligature capitale
140 | œ O-E ligature
141 | Ø Nordic O slash capitale
142 | ø Nordic O slash
143 | º Masculine Ordinal Number
144 | ª Feminine Ordinal Number
145 | ¡ Upside-down exclamation mark
146 | ¿ Upside-down question mark
147 | ¯ Macron accent
148 | Å Uppercase A, ring (angström)
149 | å Lowercase a, ring
150 | Þ Uppercase Thorn, Icelandic
151 | þ Lowercase Thorn, Icelandic
152 | Ð Uppercase Eth, Icelandic
153 | ð Lowercase Eth, Icelandic
--------------------------------------------------------------------------------
/addon/locale/en/symbolCategories.dic:
--------------------------------------------------------------------------------
1 | #the symbols and their description are divided in category and each category is defined by a section beginning with the category name enclosed between brackets.
2 | # Each line of a section define a symbol with its description:
3 | #- the symbol (one caracter)
4 | #- the "Tab" separator
5 | #- the symbol description
6 |
7 | [Lower-case accented vowels]
8 | á a acute
9 | é e acute
10 | í i acute
11 | ó o acute
12 | ú u acute
13 | ý y acute
14 | à a accent grave
15 | è e grave
16 | ì i grave
17 | ò o grave
18 | ù u grave
19 | â a circunflex
20 | ê e circunflex
21 | î i circunflex
22 | ô o circunflex
23 | û u circunflex
24 | ã a tilde
25 | ñ n tilde
26 | õ o tilde
27 | ä a umloat
28 | ë e umloat
29 | ï i umloat
30 | ö o umloat
31 | ü u umloat
32 |
33 | [Capital accented vowels]
34 | Á A acute capital
35 | É E acute capital
36 | Í I acute capital
37 | Ó O acute capital
38 | Ú U acute capital
39 | Ý Y acute capital
40 | À a grave capitale
41 | È e grave capitale
42 | Ì i grave capitale
43 | Ò o grave capitale
44 | Ù u grave capitale
45 | Â a circunflex capitale
46 | Ê e circunflex capitale
47 | Î i circunflex capitale
48 | Ô o circunflex capitale
49 | Û u circunflex capitale
50 | Ã a tilde capitale
51 | Ñ n tilde capitale
52 | Õ o tilde capitale
53 | Ä a umloat capitale
54 | Ë e umloat capitale
55 | Ï i umloat capitale
56 | Ö o umloat capitale
57 | Ü u umloat capitale
58 |
59 | [Moneytary symbols]
60 | € Euro currency
61 | $ Dollar Sign
62 | ¢ Cent sign
63 | £ British Pound
64 | ¥ Japanese Yen
65 | ƒ Dutch Florin
66 | ¤ Generic currency symbol
67 |
68 | [Math symbols]
69 | ÷ Division sign
70 | × Multiplication Sign
71 | ± Plus/minus
72 | ¹ Superscript 1
73 | ² Superscript 2
74 | ³ Superscript 3
75 | ⁿ Superscript N
76 | ° Degree symbol
77 | µ Micro
78 | ‰ Per Mille sign (1/1000th)
79 | ‰ Per Million
80 | ¼ Fraction 1/4
81 | ½ Fraction 1/2
82 | ¾ Fraction 3/4
83 | ⅛ One Eighth Fraction
84 | ⅜ Three Eighths Fraction
85 | ⅞ Seven Eighths Fraction
86 | ¬ Not symbol logic
87 | ≠ Not Equal To Sign
88 | ≤ Less Than or Equal To Sign
89 | ≥ Greater Than or Equal To Sign
90 | ∞ Infinity Sign
91 | ∫ Integral Sign
92 | ∂ Partial Differential Sign
93 | ∆ Increment Sign
94 | ∏ N-ary Product Sign
95 | ∑ N-ary Sum Sign
96 | √ Square Root Sign
97 | ∟ Right Angle Sign
98 | ∩ Intersection Sign
99 | ƒ Function Sign
100 |
101 | [Punctuation symbols]
102 | … Elipsis
103 | Dash
104 | • List Dot
105 | ∙ Bullet Operator
106 | ‣ Triangle Bullet
107 | ¦ Broken Vertical Bar
108 | Non-breaking space
109 | § Section Symbol
110 | ¶ Paragraph Symbol (Pilcrow)
111 | † Dagger
112 | ‡ Double Dagger
113 | “ Left Double Quote
114 | ” Right Double Quote
115 | ‚ Single Low Quote
116 | „ Double Low Quote
117 | ‹ Left Single Angle Quote
118 | › Right Single Angle Quote
119 | « Left Angle Quote
120 | » Right Angle Quote
121 | Soft Hyphen
122 | – en-dash
123 | — em-dash
124 | ℅ Care Of
125 | ― Horizontal Bar
126 | ‾ Overline
127 | ‼ Double exclamation mark
128 | ♦ Diamonds card
129 | & Ampersand
130 |
131 | [Other symbols]
132 | © Copyright symbol
133 | ® Registered symbol
134 | ™ Trademark
135 | Ç French C cedille capitale
136 | ç French C cedille
137 | Æ A-E ligature capitale
138 | æ A-E ligature
139 | Œ O-E ligature capitale
140 | œ O-E ligature
141 | Ø Nordic O slash capitale
142 | ø Nordic O slash
143 | º Masculine Ordinal Number
144 | ª Feminine Ordinal Number
145 | ¡ Upside-down exclamation mark
146 | ¿ Upside-down question mark
147 | ¯ Macron accent
148 | Å Uppercase A, ring (angström)
149 | å Lowercase a, ring
150 | Þ Uppercase Thorn, Icelandic
151 | þ Lowercase Thorn, Icelandic
152 | Ð Uppercase Eth, Icelandic
153 | ð Lowercase Eth, Icelandic
--------------------------------------------------------------------------------
/addon/locale/sk/symbolCategories.dic:
--------------------------------------------------------------------------------
1 | #the symbols and their description are divided in category and each category is defined by a section beginning with the category name enclosed between brackets.
2 | # Each line of a section define a symbol with its description:
3 | #- the symbol (one caracter)
4 | #- the "Tab" separator
5 | #- the symbol description
6 |
7 | [Lower-case accented vowels]
8 | á a acute
9 | é e acute
10 | í i acute
11 | ó o acute
12 | ú u acute
13 | ý y acute
14 | à a accent grave
15 | è e grave
16 | ì i grave
17 | ò o grave
18 | ù u grave
19 | â a circunflex
20 | ê e circunflex
21 | î i circunflex
22 | ô o circunflex
23 | û u circunflex
24 | ã a tilde
25 | ñ n tilde
26 | õ o tilde
27 | ä a umloat
28 | ë e umloat
29 | ï i umloat
30 | ö o umloat
31 | ü u umloat
32 |
33 | [Capital accented vowels]
34 | Á A acute capital
35 | É E acute capital
36 | Í I acute capital
37 | Ó O acute capital
38 | Ú U acute capital
39 | Ý Y acute capital
40 | À a grave capitale
41 | È e grave capitale
42 | Ì i grave capitale
43 | Ò o grave capitale
44 | Ù u grave capitale
45 | Â a circunflex capitale
46 | Ê e circunflex capitale
47 | Î i circunflex capitale
48 | Ô o circunflex capitale
49 | Û u circunflex capitale
50 | Ã a tilde capitale
51 | Ñ n tilde capitale
52 | Õ o tilde capitale
53 | Ä a umloat capitale
54 | Ë e umloat capitale
55 | Ï i umloat capitale
56 | Ö o umloat capitale
57 | Ü u umloat capitale
58 |
59 | [Moneytary symbols]
60 | € Euro currency
61 | $ Dollar Sign
62 | ¢ Cent sign
63 | £ British Pound
64 | ¥ Japanese Yen
65 | ƒ Dutch Florin
66 | ¤ Generic currency symbol
67 |
68 | [Math symbols]
69 | ÷ Division sign
70 | × Multiplication Sign
71 | ± Plus/minus
72 | ¹ Superscript 1
73 | ² Superscript 2
74 | ³ Superscript 3
75 | ⁿ Superscript N
76 | ° Degree symbol
77 | µ Micro
78 | ‰ Per Mille sign (1/1000th)
79 | ‰ Per Million
80 | ¼ Fraction 1/4
81 | ½ Fraction 1/2
82 | ¾ Fraction 3/4
83 | ⅛ One Eighth Fraction
84 | ⅜ Three Eighths Fraction
85 | ⅞ Seven Eighths Fraction
86 | ¬ Not symbol logic
87 | ≠ Not Equal To Sign
88 | ≤ Less Than or Equal To Sign
89 | ≥ Greater Than or Equal To Sign
90 | ∞ Infinity Sign
91 | ∫ Integral Sign
92 | ∂ Partial Differential Sign
93 | ∆ Increment Sign
94 | ∏ N-ary Product Sign
95 | ∑ N-ary Sum Sign
96 | √ Square Root Sign
97 | ∟ Right Angle Sign
98 | ∩ Intersection Sign
99 | ƒ Function Sign
100 |
101 | [Punctuation symbols]
102 | … Elipsis
103 | Dash
104 | • List Dot
105 | ∙ Bullet Operator
106 | ‣ Triangle Bullet
107 | ¦ Broken Vertical Bar
108 | Non-breaking space
109 | § Section Symbol
110 | ¶ Paragraph Symbol (Pilcrow)
111 | † Dagger
112 | ‡ Double Dagger
113 | “ Left Double Quote
114 | ” Right Double Quote
115 | ‚ Single Low Quote
116 | „ Double Low Quote
117 | ‹ Left Single Angle Quote
118 | › Right Single Angle Quote
119 | « Left Angle Quote
120 | » Right Angle Quote
121 | Soft Hyphen
122 | – en-dash
123 | — em-dash
124 | ℅ Care Of
125 | ― Horizontal Bar
126 | ‾ Overline
127 | ‼ Double exclamation mark
128 | ♦ Diamonds card
129 | & Ampersand
130 |
131 | [Other symbols]
132 | © Copyright symbol
133 | ® Registered symbol
134 | ™ Trademark
135 | Ç French C cedille capitale
136 | ç French C cedille
137 | Æ A-E ligature capitale
138 | æ A-E ligature
139 | Œ O-E ligature capitale
140 | œ O-E ligature
141 | Ø Nordic O slash capitale
142 | ø Nordic O slash
143 | º Masculine Ordinal Number
144 | ª Feminine Ordinal Number
145 | ¡ Upside-down exclamation mark
146 | ¿ Upside-down question mark
147 | ¯ Macron accent
148 | Å Uppercase A, ring (angström)
149 | å Lowercase a, ring
150 | Þ Uppercase Thorn, Icelandic
151 | þ Lowercase Thorn, Icelandic
152 | Ð Uppercase Eth, Icelandic
153 | ð Lowercase Eth, Icelandic
--------------------------------------------------------------------------------
/addon/locale/vi/symbolCategories.dic:
--------------------------------------------------------------------------------
1 | #the symbols and their description are divided in category and each category is defined by a section beginning with the category name enclosed between brackets.
2 | # Each line of a section define a symbol with its description:
3 | #- the symbol (one caracter)
4 | #- the "Tab" separator
5 | #- the symbol description
6 |
7 | [Lower-case accented vowels]
8 | á a acute
9 | é e acute
10 | í i acute
11 | ó o acute
12 | ú u acute
13 | ý y acute
14 | à a accent grave
15 | è e grave
16 | ì i grave
17 | ò o grave
18 | ù u grave
19 | â a circunflex
20 | ê e circunflex
21 | î i circunflex
22 | ô o circunflex
23 | û u circunflex
24 | ã a tilde
25 | ñ n tilde
26 | õ o tilde
27 | ä a umloat
28 | ë e umloat
29 | ï i umloat
30 | ö o umloat
31 | ü u umloat
32 |
33 | [Capital accented vowels]
34 | Á A acute capital
35 | É E acute capital
36 | Í I acute capital
37 | Ó O acute capital
38 | Ú U acute capital
39 | Ý Y acute capital
40 | À a grave capitale
41 | È e grave capitale
42 | Ì i grave capitale
43 | Ò o grave capitale
44 | Ù u grave capitale
45 | Â a circunflex capitale
46 | Ê e circunflex capitale
47 | Î i circunflex capitale
48 | Ô o circunflex capitale
49 | Û u circunflex capitale
50 | Ã a tilde capitale
51 | Ñ n tilde capitale
52 | Õ o tilde capitale
53 | Ä a umloat capitale
54 | Ë e umloat capitale
55 | Ï i umloat capitale
56 | Ö o umloat capitale
57 | Ü u umloat capitale
58 |
59 | [Moneytary symbols]
60 | € Euro currency
61 | $ Dollar Sign
62 | ¢ Cent sign
63 | £ British Pound
64 | ¥ Japanese Yen
65 | ƒ Dutch Florin
66 | ¤ Generic currency symbol
67 |
68 | [Math symbols]
69 | ÷ Division sign
70 | × Multiplication Sign
71 | ± Plus/minus
72 | ¹ Superscript 1
73 | ² Superscript 2
74 | ³ Superscript 3
75 | ⁿ Superscript N
76 | ° Degree symbol
77 | µ Micro
78 | ‰ Per Mille sign (1/1000th)
79 | ‰ Per Million
80 | ¼ Fraction 1/4
81 | ½ Fraction 1/2
82 | ¾ Fraction 3/4
83 | ⅛ One Eighth Fraction
84 | ⅜ Three Eighths Fraction
85 | ⅞ Seven Eighths Fraction
86 | ¬ Not symbol logic
87 | ≠ Not Equal To Sign
88 | ≤ Less Than or Equal To Sign
89 | ≥ Greater Than or Equal To Sign
90 | ∞ Infinity Sign
91 | ∫ Integral Sign
92 | ∂ Partial Differential Sign
93 | ∆ Increment Sign
94 | ∏ N-ary Product Sign
95 | ∑ N-ary Sum Sign
96 | √ Square Root Sign
97 | ∟ Right Angle Sign
98 | ∩ Intersection Sign
99 | ƒ Function Sign
100 |
101 | [Punctuation symbols]
102 | … Elipsis
103 | Dash
104 | • List Dot
105 | ∙ Bullet Operator
106 | ‣ Triangle Bullet
107 | ¦ Broken Vertical Bar
108 | Non-breaking space
109 | § Section Symbol
110 | ¶ Paragraph Symbol (Pilcrow)
111 | † Dagger
112 | ‡ Double Dagger
113 | “ Left Double Quote
114 | ” Right Double Quote
115 | ‚ Single Low Quote
116 | „ Double Low Quote
117 | ‹ Left Single Angle Quote
118 | › Right Single Angle Quote
119 | « Left Angle Quote
120 | » Right Angle Quote
121 | Soft Hyphen
122 | – en-dash
123 | — em-dash
124 | ℅ Care Of
125 | ― Horizontal Bar
126 | ‾ Overline
127 | ‼ Double exclamation mark
128 | ♦ Diamonds card
129 | & Ampersand
130 |
131 | [Other symbols]
132 | © Copyright symbol
133 | ® Registered symbol
134 | ™ Trademark
135 | Ç French C cedille capitale
136 | ç French C cedille
137 | Æ A-E ligature capitale
138 | æ A-E ligature
139 | Œ O-E ligature capitale
140 | œ O-E ligature
141 | Ø Nordic O slash capitale
142 | ø Nordic O slash
143 | º Masculine Ordinal Number
144 | ª Feminine Ordinal Number
145 | ¡ Upside-down exclamation mark
146 | ¿ Upside-down question mark
147 | ¯ Macron accent
148 | Å Uppercase A, ring (angström)
149 | å Lowercase a, ring
150 | Þ Uppercase Thorn, Icelandic
151 | þ Lowercase Thorn, Icelandic
152 | Ð Uppercase Eth, Icelandic
153 | ð Lowercase Eth, Icelandic
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/computerTools/waves.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\computerTools\waves.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2024 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 | import addonHandler
8 | from logHandler import log
9 | import os
10 | import globalVars
11 | import sys
12 | sysPath = list(sys.path)
13 | pydubModulePath = None
14 | if "pydub" in sys.modules:
15 | log.warning("Potential incompatibility: pydub module used and loaded probably by other add-on")
16 | pydubModulePath = sys.modules["pydub"]
17 | del sys.modules["pydub"]
18 | sys.path = [sys.path[0]]
19 | from ..utils.py3Compatibility import getCommonUtilitiesPath
20 | commonUtilitiesPath = getCommonUtilitiesPath()
21 | pydubPath = os.path.join(commonUtilitiesPath, "pydubEx")
22 | sys.path.append(commonUtilitiesPath)
23 | sys.path.append(pydubPath)
24 | from pydubEx import AudioSegment
25 | # restore sys.path
26 | sys.path = sysPath
27 | del sys.modules["pydubEx"]
28 | if pydubModulePath is not None:
29 | sys.modules["pydub"] = pydubModulePath
30 |
31 |
32 | # NVDA application path
33 | _NVDAAppPath = os.getcwd()
34 |
35 | # modified waves directory
36 | _addon = addonHandler.getCodeAddon()
37 | _modifiedWavesPath = os.path.join(
38 | os.path.abspath(globalVars.appArgs.configPath),
39 | "%s-NVDAWaves" % _addon.manifest['name']
40 | )
41 |
42 |
43 | def getSoundNameFromID(soundID):
44 | return soundID.split("_")[-1]
45 |
46 |
47 | def getFileNameIdentification(fileName):
48 | baseName = os.path.basename(fileName)
49 | if isNVDAWaveFile(fileName):
50 | id = "NVDAWaves_%s" % baseName
51 | elif isAddonSoundFile(fileName):
52 | temp = fileName[len(_addon.path) + 1:].split("\\")[:-1]
53 | id = "%s%s_%s" % (_addon.manifest["name"], "".join(temp), baseName)
54 | else:
55 | id = None
56 | return id
57 |
58 |
59 | def getModifiedWavesPath():
60 | return _modifiedWavesPath
61 |
62 |
63 | def getModifiedNVDAWaveFile(fileName):
64 | from ..settings import (
65 | toggleAllowNVDATonesVolumeAdjustmentAdvancedOption,
66 | toggleAllowNVDASoundGainModificationAdvancedOption
67 | )
68 | if (
69 | not toggleAllowNVDATonesVolumeAdjustmentAdvancedOption(False)
70 | or not toggleAllowNVDASoundGainModificationAdvancedOption(False)
71 | ):
72 | return fileName
73 | if not isNVDAWaveFile(fileName) and not isAddonSoundFile(fileName):
74 | return fileName
75 | if not os.path.exists(_modifiedWavesPath):
76 | return fileName
77 | soundID = getFileNameIdentification(fileName)
78 | newFileName = os.path.join(_modifiedWavesPath, soundID)
79 | if os.path.exists(newFileName):
80 | return newFileName
81 | return fileName
82 |
83 |
84 | def isNVDAWaveFile(fileName):
85 | NVDAWavesPath = os.path.join(_NVDAAppPath, "waves")
86 | return fileName.startswith(NVDAWavesPath)
87 |
88 |
89 | def isAddonSoundFile(fileName):
90 | addonSoundsPath = os.path.join(_addon.path, "sounds")
91 | return addonSoundsPath in fileName
92 |
93 |
94 | def applyGain(gain, source, target=None):
95 | try:
96 | song = AudioSegment.from_wav(source)
97 | mod = song + gain
98 | if target:
99 | mod.export(target, format="wav")
100 | return mod
101 | except Exception:
102 | log.error("Cannott modify gain: gain = %s, source = %s, target = %s" % (gain, source, target))
103 | return None
104 |
105 |
106 | def exportSong(song, target):
107 | if not target:
108 | return False
109 | try:
110 | song.export(target, format="wav")
111 | return True
112 | except Exception:
113 | log.error("Cannot exporte to %s" % target)
114 | return False
115 |
--------------------------------------------------------------------------------
/addon/locale/en/manifest.ini:
--------------------------------------------------------------------------------
1 | name = NVDAExtensionGlobalPlugin
2 | summary = "NVDA global commands extension"
3 | version = 8.1-dev35
4 | description = """This Module has been developed with the participation of Daniel Poiraud.
5 | It is not compatible with versions of NVDA below to 2018.3.2.
6 | It adds to NVDA:
7 | 1- The features
8 | some features can be enabled or disabled individually.
9 | * Display of the list of icons in the notification area ,
10 | * Display of the windows list of running applications,
11 | * Assistance in the composition of a symbol that is complex such as, for example, a a e related, a symbol power of 2
12 | and possibility to add its own categories and symbols,
13 | * Extension of the functionality of the virtual buffer
14 | for browsers Mozilla Firefox, Microsoft Internet Explorer, Microsoft Edge, and Google Chrome:
15 |
16 | * new commands for navigation mode (paragraph, division, anchor, main landmark,
17 | * new types of elements for the dialog box opened by "NVDA+F7" (radio button, paragraph, frame, checkBox, etc) with the announcement of the number of items found,
18 | * commands for the tables:
19 | announce the cells of a row /column , go to first/last cell in the row/current column, move the column/row preceding or following with announcement possible of the cells in that row/column,
20 | * announcement of the URL of the document,
21 | * navigation loop,
22 | * Announcement of the function associated with editing commands
23 | style Copy, Paste, etc.,
24 | * Announcement of the name of the folder pre-selected in the dialog boxes like "Open","Save", "Save as",etc.,
25 | * display of information on the focused application:
26 | * the current profile configuration,
27 | * the name and version number of the application,
28 | * the add-on loaded for the application,
29 | * NVDA logs tools:
30 | * Opening the previous or current log,
31 | * copy of current Log path to the clipboard,
32 |
33 | * history of voice speechs,
34 | * renaming keyboard keys,
35 | * selective announcement of command keyboard keys ,
36 | * simple countdown timer,
37 | * display of visible elements making up the object in the foreground,
38 | * fast switching of voice profile,
39 | * remanence of the modifier keys,
40 | * shutdown, restart or put on prolonged sleep the computer,
41 | * control the master or NVDA volume:
42 | * mute or unmute volume for the focused application,
43 | * establishment of the main Windows or NVDA volume at the add-on loading,
44 | * modification of main volume or audio flow's volume of focused application,
45 | * Tools for development of add-on
46 | * supplements regarding the date and time: copy date and time to clipboard, report time with seconds
47 |
48 |
49 | 2- The options
50 | * remove the ad from the description of the objects in the ribbons Windows,
51 | * proclaim the word focused when deleting a word,
52 | * automatically maximize the foreground window,
53 | * announce punctuations and symbols when moving by word .
54 |
55 | 3- The advanced options
56 | * report, with a sound, the registration of an error in the NVDA log also for the final versions and release candidate of NVDA,
57 | * Caption dialog title with the name of the module,
58 | * Do not take account of the option called Report object descriptions during the display of the dialog box style confirmation,
59 | * use numeric keypad's keys as arrow keys.
60 |
61 |
62 | 4- Various other elements
63 | * presentation formatting of the text in a dialog box,
64 | * sub-menus to explore the program folders or configuration,
65 | * script to quickly restart NVDA.
66 | """
67 | author = "PaulBer19"
68 | url = paulber19@laposte.net
69 | docFileName = addonUserManual.html
70 | minimumNVDAVersion = 2018.3.2
71 | lastTestedNVDAVersion = 2019.2.0
72 | updateChannel = None
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/utils/textInfo.py:
--------------------------------------------------------------------------------
1 | # NVDAExtensionGlobalPlugin/utils/textInfo.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2023 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 | from logHandler import log
7 |
8 | import textInfos
9 | import speech
10 |
11 |
12 | def getStartOffset(textInfo):
13 | from NVDAObjects.UIA import UIATextInfo
14 | if issubclass(textInfo.obj.TextInfo, UIATextInfo):
15 | # UIA bookmark has no endOffset, so calculate it
16 | first = textInfo.copy()
17 | first.expand(textInfos.UNIT_STORY)
18 | startOffset = textInfo.compareEndPoints(first, "startToStart")
19 | else:
20 | if hasattr(textInfo.bookmark, "_start"):
21 | startOffset = textInfo.bookmark._start._startOffset
22 | else:
23 | startOffset = textInfo.bookmark.startOffset
24 | return startOffset
25 |
26 |
27 | def getEndOffset(textInfo):
28 | from NVDAObjects.UIA import UIATextInfo
29 | if issubclass(textInfo.obj.TextInfo, UIATextInfo):
30 | # UIA bookmark has no endOffset, so calculate it
31 | first = textInfo.copy()
32 | first.expand(textInfos.UNIT_STORY)
33 | endOffset = textInfo.compareEndPoints(first, "endToStart")
34 | else:
35 | if hasattr(textInfo.bookmark, "_end"):
36 | endOffset = textInfo.bookmark._end._endOffset
37 | else:
38 | endOffset = textInfo.bookmark.endOffset
39 | return endOffset
40 |
41 |
42 | def getTextInfoPositions(info):
43 | tempInfo = info.copy()
44 | start = getStartOffset(tempInfo)
45 | tempInfo.expand(textInfos.UNIT_LINE)
46 | start = getStartOffset(tempInfo)
47 | end = getEndOffset(tempInfo)
48 | tempInfo.collapse()
49 | textInfoPositions = []
50 | tempInfo.expand(textInfos.UNIT_CHARACTER)
51 | pos = getStartOffset(tempInfo)
52 | textInfoPositions.append(0)
53 | i = 0
54 | while i < (end - start):
55 | i += 1
56 | res = tempInfo.move(textInfos.UNIT_CHARACTER, 1)
57 | if res == 0:
58 | break
59 | tempInfo.expand(textInfos.UNIT_CHARACTER)
60 | pos = getStartOffset(tempInfo)
61 | textInfoPositions.append(pos - start)
62 | return textInfoPositions
63 |
64 |
65 | def getRealPosition(info):
66 | tempInfo = info.copy()
67 | curPosition = getStartOffset(tempInfo)
68 | tempInfo.expand(textInfos.UNIT_LINE)
69 | lineStart = getStartOffset(tempInfo)
70 | tempInfo.collapse()
71 | positions = getTextInfoPositions(tempInfo)
72 | for pos in positions:
73 | if pos == curPosition - lineStart:
74 | return positions.index(pos)
75 | return None
76 |
77 |
78 | _lastLineInfo = []
79 |
80 |
81 | def getLineInfo(info):
82 | reportFormattingOptions = ("reportLineNumber", "reportPage")
83 | tempInfo = info.copy()
84 | formatConfig = dict()
85 | from config import conf
86 | for i in conf["documentFormatting"]:
87 | formatConfig[i] = i in reportFormattingOptions
88 | formatField = textInfos.FormatField()
89 | tempInfo.expand(textInfos.UNIT_LINE)
90 | for field in tempInfo.getTextWithFields(formatConfig):
91 | if isinstance(field, textInfos.FieldCommand) and\
92 | isinstance(field.field, textInfos.FormatField):
93 | formatField.update(field.field)
94 | lineInfoList = speech.getFormatFieldSpeech(
95 | formatField, formatConfig=formatConfig) if formatField else None
96 | if not lineInfoList:
97 | return ""
98 | log.debug("on: %s" % lineInfoList)
99 | return lineInfoList
100 |
101 |
102 | def getLineInfoMessage(info):
103 | lineInfo = getLineInfo(info)
104 | global _lastLineInfo
105 | if _lastLineInfo != lineInfo:
106 | temp = []
107 | for item in lineInfo:
108 | if item in _lastLineInfo:
109 | continue
110 | temp.append(item)
111 | _lastLineInfo = lineInfo
112 | lineInfoMsg = ", ".join(temp)
113 | else:
114 | lineInfoMsg = ""
115 | return lineInfoMsg
116 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/winExplorer/__init__.py:
--------------------------------------------------------------------------------
1 | # NVDAExtensionGlobalPlugin/winExplorer/__init__.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2016 - 2023 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 | import addonHandler
8 | import ui
9 | from controlTypes.role import Role
10 | from controlTypes.state import State
11 |
12 | import api
13 | import queueHandler
14 | import itertools
15 | from .elementListDialog import ElementListDialog
16 | from ..utils import runInThread, isOpened
17 | addonHandler.initTranslation()
18 |
19 | _generatorID = None
20 | _running = False
21 |
22 |
23 | def _startGenerator(generator):
24 | global _generatorID
25 | stop()
26 | _generatorID = queueHandler.registerGeneratorObject(generator)
27 |
28 |
29 | def stop():
30 | global _generatorID
31 | if _generatorID is None:
32 | return
33 | queueHandler.cancelGeneratorObject(_generatorID)
34 | _generatorID = None
35 |
36 |
37 | def isRunning():
38 | global _running
39 | ret = _running
40 | _running = False
41 | return ret
42 |
43 |
44 | def generateObjectSubtreeGetObject(obj, indexGen, th):
45 | global _running
46 | index = next(indexGen)
47 | yield obj, index
48 | rowCount = 0
49 | treeCount = 0
50 | listCount = 0
51 | try:
52 | # childCount = len(obj.children)
53 | childCount = obj.childCount
54 | except Exception:
55 | childCount = 0
56 | for i in range(childCount):
57 | _running = True
58 | try:
59 | child = obj.getChild(i)
60 | if child is None:
61 | continue
62 | except Exception:
63 | continue
64 | role = child.role
65 | invisible = State.INVISIBLE in child.states
66 | try:
67 | childParent = child.parent
68 | try:
69 | parentChildCount = childParent.childCount
70 | except Exception:
71 | parentChildCount = 0
72 | except Exception:
73 | childParent = None
74 | parentChildCount = 0
75 | if role == Role.TABLEROW:
76 | if childParent and parentChildCount > 500:
77 | break
78 | if invisible:
79 | continue
80 | rowCount += 1
81 | treeCount = 0
82 | listCount = 0
83 | if rowCount > 40:
84 | break
85 | if role == Role.TREEVIEWITEM:
86 | if childParent and (
87 | parentChildCount > 500
88 | or childParent.role not in [Role.TREEVIEW, Role.LIST]
89 | ):
90 | break
91 | if invisible:
92 | continue
93 | treeCount += 1
94 | rowCount = 0
95 | listCount = 0
96 | if treeCount > 40:
97 | break
98 | if role == Role.LISTITEM:
99 | if childParent and parentChildCount > 500:
100 | break
101 | if invisible:
102 | continue
103 | listCount += 1
104 | rowCount = 0
105 | treeCount = 0
106 | if listCount > 40:
107 | break
108 |
109 | if role in [Role.DOCUMENT, ]:
110 | continue
111 | childGetObject = generateObjectSubtreeGetObject(child, indexGen, th)
112 | for r in childGetObject:
113 | _running = True
114 | yield r
115 |
116 |
117 | def getObjectsHelper_generator(oParent):
118 | global _running
119 | global objectList
120 | ui.message(_("Elements's searching"))
121 | objectList = []
122 | lastSentIndex = 0
123 | th = runInThread.RepeatBeep(
124 | delay=2.0, beep=(200, 200), isRunning=isRunning)
125 | th.start()
126 | getObjectGen = generateObjectSubtreeGetObject(oParent, itertools.count(), th)
127 | focus = api.getFocusObject()
128 | while True:
129 | _running = True
130 | if api.getFocusObject() != focus:
131 | th.stop()
132 | del th
133 | return
134 | try:
135 | o, lastSentIndex = next(getObjectGen)
136 | # Consider only objects that are visible on screen and with known role
137 | if o.role != Role.UNKNOWN\
138 | and State.INVISIBLE not in o.states:
139 | objectList.append(o)
140 | except StopIteration:
141 | break
142 | yield
143 | _running = True
144 | th.stop()
145 | del th
146 | ElementListDialog.run(oParent, objectList)
147 |
148 |
149 | def findAllNVDAObjects(oParent):
150 | if isOpened(ElementListDialog):
151 | return
152 | _startGenerator(getObjectsHelper_generator(oParent))
153 |
--------------------------------------------------------------------------------
/addon/doc/ar/addon_keys.t2tconf:
--------------------------------------------------------------------------------
1 | % script command keys definition
2 | %!PostProc (html): KEY_NEXT_ROW_REPORT NVDA+alt+down arrow
3 | %!PostProc (html): KEY_PREVIOUS_ROW_REPORT NVDA+up arrow
4 | %!PostProc (html): KEY_NEXT_COLUMN_REPORT NVDA+alt+right arrow
5 | %!PostProc (html): KEY_PREVIOUS_COLUMN_REPORT NVDA+alt+left arrow
6 | %!PostProc (html): KEY_MOVE_FIRST_CELL_ROW control+alt+shift+left arrow
7 | %!PostProc (html): KEY_MOVE_LAST_CELL_ROW control+alt+shift+right arrow
8 | %!PostProc (html): KEY_MOVE_FIRST_CELL_COLUMN control+alt+shift+up arrow
9 | %!PostProc (html): KEY_MOVE_LAST_CELL_COLUMN control+alt+shift+down arrow
10 | %!PostProc (html): KEY_CURRENT_ROW_REPORT NVDA+alt+j
11 | %!PostProc (html): KEY_CURRENT_COLUMN_REPORT NVDA+alt+l
12 | %!PostProc (html): KEY1_CELL_POSITION_REPORT NVDA+alt+numpad5
13 | %!PostProc (html): KEY2_CELL_POSITION_REPORT NVDA+alt+;
14 | %!PostProc (html): KEY1_DOCUMENT_ADDRESS NVDA+a
15 | %!PostProc (html): KEY2_DOCUMENT_ADDRESS NVDA+shift+a
16 |
17 | % main script command keys definition
18 | %!PostProc (html): KEY_SHELL NVDA+j
19 | %!PostProc (html): KEY_DATE_TIME NVDA + F12
20 |
21 | % default fonctionnality script command keys definition
22 | %!PostProc (html): MAIN_KEY_ICONS_List NVDA + F11
23 | %!PostProc (html): MAIN_KEY_COMPLEX_SYMBOL NVDA + shift + f4
24 | %!PostProc (html): MAIN_KEY_REPORT_NAME_VERSION NVDA + shift + f1
25 | %!PostProc (html): MAIN_KEY_CONFIGURATION_PROFILE NVDA+ control +F1
26 | %!PostProc (html): MAIN_KEY_SAY_CURRENT_FOLDER NVDA+o
27 | %!PostProc (html): MAIN_KEY_LOG_VIEW NVDA+shift+j
28 | %!PostProc (html): MAIN_KEY_PREVIOUS_RECORD NVDA+control+f8
29 | %!PostProc (html): MAIN_KEY_CURRENT_RECORD NVDA+control+f9
30 | %!PostProc (html): MAIN_KEY_NEXT_RECORD NVDA+control+f10
31 | %!PostProc (html): MAIN_KEY_MINUTE_TIMER NVDA+shift+f12
32 | %!PostProc (html): MAIN_KEY_RESTART_NVDA NVDA+control+f4
33 | %!PostProc (html): MAIN_KEY_OBJECTS_LIST NVDA+b
34 | %!PostProc (html): MAIN_KEY_VOICEPROFILE_SELECTOR nvda+shift+control+ selector number
35 | %!PostProc (html): MAIN_KEY_NEXT_VOICEPROFILE nvda+shift+control+right arrow
36 | %!PostProc (html): MAIN_KEY_PREVIOUS_VOICEPROFILE nvda+shift+control+left arrow
37 | %!PostProc (html): MAIN_KEY_MANAGE_SELECTOR nvda+shift+control+m
38 | %!PostProc (html): MAIN_KEY_VOLUME_ON nvda+shift+Échapp"
39 | %!PostProc (html): MAIN_KEY_TOGGLE_MUTE nvda+shift+pause
40 | %!PostProc (html): MAIN_KEY_CLIC_LEFT_MOUSE_BUTTON_At_NAVIGATOR nvda+,
41 | %!PostProc (html): MAIN_KEY_CLIC_RIGHT_MOUSE_BUTTON_At_NAVIGATOR nvda+majuscule+,
42 | % script shell command keys definitions
43 | %!PostProc (html): KEY_APPLICATION_INFORMATIONS a
44 | %!PostProc (html): KEY_OBJECTS_LIST b
45 | %!PostProc (html): KEY_COPY_DATETIME c
46 | %!PostProc (html): KEY_REPORT_FORMATTING f
47 | %!PostProc (html): KEY_ADDON_SETTINGS f1
48 | %!PostProc (html): KEY_RENAMING f2
49 | %!PostProc (html): KEY_SELECTIVE_ANNOUNCEMENT f3
50 | %!PostProc (html): KEY_COMPLEX_SYMBOL f4
51 | %!PostProc (html): KEY_LAST_USED_COMPLEX_SYMBOL control+f4
52 | %!PostProc (html): KEY_TOGGLE_NUMPAD_NAVIGATION f5
53 | %!PostProc (html): KEY_DISPLAY_SPEECH_HISTORY f9
54 | %!PostProc (html): KEY_WINDOWS_LIST F10
55 | %!PostProc (html): KEY_ICONS_List F11
56 | %!PostProc (html): KEY_MINUTE_TIMER f12
57 | %!PostProc (html): KEY_MODULE_GUIDE g
58 | %!PostProc (html): KEY_HELP_SHELL h
59 | %!PostProc (html): KEY_LOG_VIEW j
60 | %!PostProc (html): KEY_SAY_CURRENT_FOLDER o
61 | %!PostProc (html): KEY_VOICE_PROFIL_SWITCHING p
62 | %!PostProc (html): KEY_SHUTDOWN r
63 | %!PostProc (html): KEY_TOGGLE_MUTE s
64 | %!PostProc (html): KEY_VOLUME_ON control+s
65 | %!PostProc (html): KEY_MAIN_VOLUME_UP control+up arrow
66 | %!PostProc (html): KEY_MAIN_VOLUME_DOWN control+down arrow
67 | %!PostProc (html): KEY_MAIN_VOLUME_MAX control+page up
68 | %!PostProc (html): KEY_MAIN_VOLUME_MIN control+page down
69 | %!PostProc (html): KEY_APP_VOLUME_UP up arrow
70 | %!PostProc (html): KEY_APP_VOLUME_DOWN down arrow
71 | %!PostProc (html): KEY_APP_VOLUME_MAX page up
72 | %!PostProc (html): KEY_APP_VOLUME_MIN page down
73 | %!PostProc (html): KEY_TOOLSFORADDON t
74 | %!PostProc (html): KEY_USER_INPUT_GESTURE u
75 | %!PostProc (html): KEY_MANAGE_VOICE_PROFIL v
76 | %!PostProc (html): KEY_CLOSE_ALL_WINDOWS k
77 | %!PostProc (html): KEY_RUNNING_ADDONS e
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/textAnalysis/symbols.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\textAnalysis\symbols.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2021 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 | import addonHandler
8 | from logHandler import log
9 | import os.path
10 | from configobj import ConfigObj
11 | from configobj.validate import Validator
12 | from io import StringIO
13 |
14 | # sections
15 | SCT_SymbolToSymetric = "SymbolToSymetric"
16 | SCT_Punctuations = "Punctuations"
17 | # symbols for numbers
18 | NUM_DecimalSymbol = "decimalSymbol"
19 | NUM_DigitGroupingSymbol = "digitGroupingSymbol"
20 | # items of Punctuations section
21 | SMBL_All = "All"
22 | SMBL_NeedSpaceBefore = "NeedSpaceBefore"
23 | SMBL_NeedSpaceAfter = "NeedSpaceAfter"
24 | SMBL_NoSpaceBefore = "NoSpaceBefore"
25 | SMBL_NoSpaceAfter = "NoSpaceAfter"
26 |
27 | _configSpec = """
28 | {decimalSymbol}= string(default=".")
29 | {digitGroupingSymbol}= string(default=",")
30 | [{symbolToSymetric}]
31 | [{punctuations}]
32 | {all}= string(default="")
33 | {needSpaceBefore}= string(default="")
34 | {needSpaceAfter}= string(default="")
35 | {noSpaceBefore}= string(default="")
36 | {noSpaceAfter}= string(default="")
37 | """.format(
38 | decimalSymbol=NUM_DecimalSymbol,
39 | digitGroupingSymbol=NUM_DigitGroupingSymbol,
40 | symbolToSymetric=SCT_SymbolToSymetric,
41 | punctuations=SCT_Punctuations,
42 | all=SMBL_All,
43 | needSpaceBefore=SMBL_NeedSpaceBefore,
44 | needSpaceAfter=SMBL_NeedSpaceAfter,
45 | noSpaceBefore=SMBL_NoSpaceBefore,
46 | noSpaceAfter=SMBL_NoSpaceAfter)
47 |
48 |
49 | def getTextAnalysisIniFilePath():
50 | from languageHandler import getLanguage
51 | lang = getLanguage()
52 | langs = [lang, ]
53 | addonFolderPath = addonHandler.getCodeAddon().path
54 | if '_' in lang:
55 | langs.append(lang.split("_")[0])
56 | langs.append("en")
57 | for lang in langs:
58 | langDir = os.path.join(addonFolderPath, "locale", lang)
59 | if os.path.exists(langDir):
60 | file = os.path.join(langDir, "textAnalysis.ini")
61 | if os.path.isfile(file):
62 | log.debugWarning("textAnalyzis.ini file loaded from locale\\%s folder" % lang)
63 | return file
64 | log.error("textAnalysis.ini file not found")
65 | return ""
66 |
67 |
68 | def getSymbolChoiceLabels():
69 | symbolChoiceLabels = {}
70 | symbolToSymetricDic = getSymbolToSymetricDic()
71 | for symbol, symetric in symbolToSymetricDic.items():
72 | label = "{symbol} {symetric}".format(
73 | symbol=symbol,
74 | symetric=symetric)
75 | symbolChoiceLabels[symbol] = label
76 | return symbolChoiceLabels
77 |
78 |
79 | def getSymbols_all():
80 | dic = getPunctuationsDic()
81 | return dic[SMBL_All]
82 |
83 |
84 | def getPunctuationsDic():
85 | if _conf:
86 | sct = _conf.get(SCT_Punctuations)
87 | if sct is None:
88 | log.error("textAnalysis punctuations section not found")
89 | return sct
90 | log.error("textAnalysis configuration cannot be loaded")
91 | return None
92 |
93 |
94 | def getSymbolToSymetricDic():
95 | if _conf:
96 | sct = _conf.get(SCT_SymbolToSymetric)
97 | if sct is None:
98 | log.error("textAnalysis symbols section not found")
99 | return sct
100 | log.error("textAnalysis configuration cannot be loaded")
101 | return None
102 |
103 |
104 | def getDecimalSymbol():
105 | if _conf is None:
106 | return ""
107 | return _conf.get(NUM_DecimalSymbol, "")
108 |
109 |
110 | def getDigitGroupingSymbol():
111 | if _conf is None:
112 | return ""
113 | return _conf.get(NUM_DigitGroupingSymbol, "")
114 |
115 |
116 | def getTextAnalysisConfig():
117 | path = getTextAnalysisIniFilePath()
118 | conf = ConfigObj(
119 | path,
120 | configspec=StringIO(""),
121 | encoding="utf-8",
122 | list_values=False)
123 | conf.newlines = "\r\n"
124 | val = Validator()
125 | ret = conf.validate(val, preserve_errors=True, copy=True)
126 | if not ret:
127 | log.warning("KeyboardKeys configuration file is invalid: %s", ret)
128 | return conf
129 |
130 |
131 | # singleton
132 | _conf = getTextAnalysisConfig()
133 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/speechHistory/speechHistoryPatches.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\speechHistory\speechHistoryPatches.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2024 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 | from logHandler import log
8 | from speech import speech as speech
9 | from collections.abc import Sequence
10 | from ..settings import isInstall
11 | from ..settings.addonConfig import FCT_SpeechHistory, FCT_TemporaryAudioDevice
12 | from ..computerTools.temporaryOutputDevice import checkOutputDeviceChange
13 | from ..speechHistory import getSpeechRecorder
14 | from ..utils.nvdaInfos import NVDAVersion
15 |
16 | # global variables to save original NVDA patched functions
17 | _NVDASpeechSpeak = None
18 | _NVDASpeechSpeakSpelling = None
19 |
20 |
21 | def preSpeechAction(speechSequence):
22 | """
23 | - record the sequence to speak
24 | - redirect synthetizer and tones to temporary output device if there is one
25 | """
26 | # reset current output device if temporary output device is set and output device has changed
27 | checkOutputDeviceChange()
28 | if not isinstance(speechSequence, Sequence):
29 | return
30 | if isInstall(FCT_SpeechHistory):
31 | text = " ".join([x for x in speechSequence if isinstance(x, str)])
32 | getSpeechRecorder().record(text)
33 |
34 |
35 | def _mySpeechSpeak(speechSequence, *args, **kwargs):
36 | """
37 | speech.speak must be patched to notify pre speech
38 | """
39 | log.debug("_mySpeechSpeak")
40 | from .extensions import my_pre_speech
41 | my_pre_speech.notify(speechSequence=speechSequence)
42 | _NVDASpeechSpeak(speechSequence, *args, **kwargs)
43 |
44 |
45 | def _mySpeechSpeakSpelling(text, *args, **kwargs):
46 | """
47 | speech.speakSpelling must be patched to notify pre speech
48 | """
49 | log.debug("_mySpeechSpeakSpelling")
50 | from .extensions import my_pre_speech
51 | my_pre_speech.notify(speechSequence=text)
52 | _NVDASpeechSpeakSpelling(text, *args, **kwargs)
53 |
54 |
55 | def patche(install=True):
56 | if not install:
57 | removePatch()
58 | return
59 | if not isInstall(FCT_SpeechHistory) and not isInstall(FCT_TemporaryAudioDevice):
60 | return
61 | from . import extensions
62 | extensions.my_pre_speech.register(preSpeechAction)
63 | if NVDAVersion >= [2024, 2]:
64 | # we don't need to patch nvda speech methods
65 | return
66 | global _NVDASpeechSpeak, _NVDASpeechSpeakSpelling
67 | # patche speech.speak
68 | _NVDASpeechSpeak = speech.speak
69 | if speech.speak.__module__ != "speech.speech":
70 | log.warning(
71 | "Incompatibility: speech.speech.speak method has also been patched probably by another add-on: %s."
72 | "There is a risk of malfunction" % speech.speak.__module__)
73 | speech.speak = _mySpeechSpeak
74 | log.debug(
75 | "For speech history functionality,"
76 | " speech.speech.speak method has been replaced by %s method of %s module" % (
77 | _mySpeechSpeak.__name__, _mySpeechSpeak.__module__)
78 | )
79 | # patce speech.speakSpelling
80 | _NVDASpeechSpeakSpelling = speech.speakSpelling
81 | if speech.speakSpelling .__module__ != "speech.speech":
82 | log.warning(
83 | "Incompatibility: speech.speech.speakSpelling method has also been atched probably by another add-on: %s."
84 | "There is a risk of malfunction" % speech.speakSpelling .__module__)
85 | speech.speakSpelling = _mySpeechSpeakSpelling
86 | log.debug(
87 | "For speech history functionality,"
88 | " speech.speech.speakSpelling method has been replaced by %s method of %s module" % (
89 | _mySpeechSpeakSpelling.__name__, _mySpeechSpeakSpelling.__module__)
90 | )
91 |
92 |
93 | def removePatch():
94 | from .extensions import my_pre_speech
95 | my_pre_speech.unregister(preSpeechAction)
96 | global _NVDASpeechSpeak, _NVDASpeechSpeakSpelling
97 | if _NVDASpeechSpeak:
98 | speech.speak = _NVDASpeechSpeak
99 | _NVDASpeechSpeak = None
100 | log.debug("nvda speech method is restored")
101 | if _NVDASpeechSpeakSpelling:
102 | speech.speakSpelling = _NVDASpeechSpeakSpelling
103 | _NVDASpeechSpeakSpelling = None
104 | log.debug("NVDA speakSpelling method is restored")
105 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/computerTools/pycawUtils.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\utilities\pycawEx\myPycawUtils.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2024 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 | # patch of AudioUtilities pycaw class to get audio sources of a specific device
8 |
9 | from logHandler import log
10 | import comtypes
11 | from ..utils.nvdaInfos import NVDAVersion
12 |
13 | if NVDAVersion >= [2024, 2]:
14 | # for nvda version >= 2024.2
15 | from pycaw.api.audiopolicy import IAudioSessionControl2, IAudioSessionManager2
16 | from pycaw.api.mmdeviceapi import IMMDeviceEnumerator
17 | from pycaw.constants import (
18 | DEVICE_STATE,
19 | CLSID_MMDeviceEnumerator,
20 | EDataFlow,
21 | ERole,
22 | )
23 | from pycaw.utils import AudioUtilities, AudioSession
24 | else:
25 | # for nvda version <2024.2
26 | import sys
27 | import os
28 | sysPath = list(sys.path)
29 | if "pycaw" in sys.modules:
30 | log.warning("Potential incompatibility: pycaw module is also used and loaded probably by other add-on")
31 | del sys.modules["pycaw"]
32 | sys.path = [sys.path[0]]
33 | from ..utils.py3Compatibility import getCommonUtilitiesPath
34 | commonUtilitiesPath = getCommonUtilitiesPath()
35 | pycawPath = os.path.join(commonUtilitiesPath, "pycawEx")
36 | psutilPath = os.path.join(commonUtilitiesPath, "psutilEx")
37 | sys.path.append(commonUtilitiesPath)
38 | sys.path.append(psutilPath)
39 | sys.path.append(pycawPath)
40 | from pycawEx.pycaw.api.audiopolicy import IAudioSessionControl2, IAudioSessionManager2
41 | from pycawEx.pycaw.api.mmdeviceapi import IMMDeviceEnumerator
42 | from pycawEx.pycaw.constants import (
43 | DEVICE_STATE,
44 | CLSID_MMDeviceEnumerator,
45 | EDataFlow,
46 | ERole,
47 | )
48 | from pycawEx.pycaw.utils import AudioUtilities, AudioSession
49 | sys.path = sysPath
50 |
51 |
52 | class MyAudioUtilities(AudioUtilities):
53 |
54 | @staticmethod
55 | def GetSpeakers(audioDeviceID=None):
56 | """
57 | get the speakers (1st render + multimedia) device
58 | """
59 | deviceEnumerator = comtypes.CoCreateInstance(
60 | CLSID_MMDeviceEnumerator,
61 | IMMDeviceEnumerator,
62 | comtypes.CLSCTX_INPROC_SERVER)
63 | if audioDeviceID is None:
64 | speakers = deviceEnumerator.GetDefaultAudioEndpoint(
65 | EDataFlow.eRender.value, ERole.eMultimedia.value)
66 | else:
67 | speakers = deviceEnumerator.GetDevice(audioDeviceID)
68 | return speakers
69 |
70 | @staticmethod
71 | def GetAudioSessionManager(audioDeviceID=None):
72 | speakers = MyAudioUtilities.GetSpeakers(audioDeviceID)
73 | if speakers is None:
74 | return None
75 | # win7+ only
76 | o = speakers.Activate(IAudioSessionManager2._iid_, comtypes.CLSCTX_ALL, None)
77 | mgr = o.QueryInterface(IAudioSessionManager2)
78 | return mgr
79 |
80 | @staticmethod
81 | def GetAllSessions(audioDeviceID=None):
82 | audio_sessions = []
83 | mgr = MyAudioUtilities.GetAudioSessionManager(audioDeviceID)
84 | if mgr is None:
85 | return audio_sessions
86 | sessionEnumerator = mgr.GetSessionEnumerator()
87 | count = sessionEnumerator.GetCount()
88 | for i in range(count):
89 | ctl = sessionEnumerator.GetSession(i)
90 | if ctl is None:
91 | continue
92 | ctl2 = ctl.QueryInterface(IAudioSessionControl2)
93 | if ctl2 is not None:
94 | audio_session = AudioSession(ctl2)
95 | audio_sessions.append(audio_session)
96 | return audio_sessions
97 |
98 | @staticmethod
99 | def GetAllDevices(flow=EDataFlow.eAll, state=DEVICE_STATE.MASK_ALL):
100 | devices = []
101 | deviceEnumerator = comtypes.CoCreateInstance(
102 | CLSID_MMDeviceEnumerator, IMMDeviceEnumerator, comtypes.CLSCTX_INPROC_SERVER
103 | )
104 | if deviceEnumerator is None:
105 | return devices
106 |
107 | collection = deviceEnumerator.EnumAudioEndpoints(
108 | flow.value, state.value
109 | )
110 | if collection is None:
111 | return devices
112 |
113 | count = collection.GetCount()
114 | for i in range(count):
115 | dev = collection.Item(i)
116 | if dev is not None:
117 | devices.append(MyAudioUtilities.CreateDevice(dev))
118 | return devices
119 |
--------------------------------------------------------------------------------
/addon/globalPlugins/NVDAExtensionGlobalPlugin/speechHistory/__init__.py:
--------------------------------------------------------------------------------
1 | # globalPlugins\NVDAExtensionGlobalPlugin\speechHistory\__init__.py
2 | # A part of NVDAExtensionGlobalPlugin add-on
3 | # Copyright (C) 2016 - 2025 paulber19
4 | # This file is covered by the GNU General Public License.
5 | # See the file COPYING for more details.
6 |
7 | import addonHandler
8 | import tones
9 | import ui
10 | import api
11 | from ..utils.informationDialog import InformationDialog
12 | from ..utils.NVDAStrings import NVDAString
13 | from ..settings import toggleSpeechRecordWithNumberOption, toggleSpeechRecordInAscendingOrderOption
14 |
15 | addonHandler.initTranslation()
16 |
17 | # constants
18 | MAX_RECORD = 200
19 | # global variables
20 | _speechRecorder = None
21 | _NVDASpeak = None
22 | _NVDASpeakSpelling = None
23 |
24 |
25 | def getSpeechRecorder():
26 | return _speechRecorder
27 |
28 |
29 | def isActive():
30 | return _speechRecorder is not None
31 |
32 |
33 | class SpeechRecorderManager(object):
34 | def __init__(self):
35 | self._speechHistory = []
36 | self._lastSpeechHistoryReportIndex = None
37 | self._onMonitoring = True
38 |
39 | def record(self, text):
40 | if not text or not self._onMonitoring:
41 | return
42 | while len(text):
43 | if text[-1] not in ["\n", "\r"]:
44 | break
45 | text = text[:-1]
46 |
47 | if len(text.strip()) == 0:
48 | return
49 | self._speechHistory.append(text)
50 | if len(self._speechHistory) > MAX_RECORD:
51 | self._speechHistory.pop(0)
52 | self._lastSpeechHistoryReportIndex = len(self._speechHistory) - 1
53 |
54 | def reportSpeechHistory(self, position, toClip=False):
55 | index = self._lastSpeechHistoryReportIndex
56 | if index is None:
57 | return
58 | oldOnMonitoring = self._onMonitoring
59 | self._onMonitoring = False
60 | if position == "previous" and index > 0:
61 | index -= 1
62 | elif position == "next" and index < len(self._speechHistory) - 1:
63 | index += 1
64 | if (position != "current") and (index == self._lastSpeechHistoryReportIndex):
65 | tones.beep(100, 40)
66 | self._lastSpeechHistoryReportIndex = index
67 | text = self._speechHistory[index]
68 | if not toClip:
69 | ui.message(text)
70 | self._onMonitoring = oldOnMonitoring
71 | return
72 | if not api.copyToClip(text):
73 | # Translators: Presented when unable to copy to the clipboard because of an error.
74 | ui.message(NVDAString("Unable to copy"))
75 | # Translators: message to user to report copy to clipboard
76 | ui.message(_("{0} copied to clipboard") .format(text))
77 | self._onMonitoring = oldOnMonitoring
78 |
79 | def displaySpeechHistory(self):
80 | text = []
81 | for index in range(0, len(self._speechHistory)):
82 | s = self._speechHistory[index]
83 | if toggleSpeechRecordWithNumberOption(False):
84 | text.append(str(" {index}: {annonce}").format(
85 | index=index + 1, annonce=s))
86 | else:
87 | text .append(str(s))
88 | if not toggleSpeechRecordInAscendingOrderOption(False):
89 | text.reverse()
90 | text = "\r\n".join(text)
91 | # Translators: title of informations dialog.
92 | dialogTitle = _("Speech history")
93 | if toggleSpeechRecordInAscendingOrderOption(False):
94 | insertionPointOnLastLine = True
95 | else:
96 | insertionPointOnLastLine = False
97 | # Translators: label of information area.
98 | informationLabel = _("Records:")
99 | InformationDialog.run(
100 | None, dialogTitle, informationLabel, text, insertionPointOnLastLine)
101 |
102 |
103 | def initialize():
104 | from . import speechHistoryPatches
105 | from ..settings import isInstall
106 | from ..settings.addonConfig import FCT_SpeechHistory, FCT_TemporaryAudioDevice
107 | global _NVDASpeak, _NVDASpeakSpelling
108 | global _speechRecorder
109 | if _speechRecorder is not None:
110 | return
111 | if not isInstall(FCT_SpeechHistory) and not isInstall(FCT_TemporaryAudioDevice):
112 | return
113 | _speechRecorder = SpeechRecorderManager()
114 | speechHistoryPatches.patche(install=True)
115 |
116 |
117 | def terminate():
118 | global _speechRecorder
119 | if _speechRecorder is None:
120 | return
121 | from . import speechHistoryPatches
122 | speechHistoryPatches.patche(install=False)
123 | _speechRecorder = None
124 |
--------------------------------------------------------------------------------