diff --git a/source/NVDAObjects/window/excel.py b/source/NVDAObjects/window/excel.py index 7ca4b3b4203..af7f98d335d 100755 --- a/source/NVDAObjects/window/excel.py +++ b/source/NVDAObjects/window/excel.py @@ -25,6 +25,7 @@ import api from logHandler import log import gui +import gui.contextHelp import winUser import mouseHandler from displayModel import DisplayModelTextInfo @@ -597,7 +598,7 @@ class ElementsListDialog(browseMode.ElementsListDialog): class EditCommentDialog( - gui.ContextHelpMixin, + gui.contextHelp.ContextHelpMixin, wx.TextEntryDialog, # wxPython does not seem to call base class initializer, put last in MRO ): helpId = "ExcelReportingComments" diff --git a/source/api.py b/source/api.py index 2f819ded16d..326e06f415a 100644 --- a/source/api.py +++ b/source/api.py @@ -318,7 +318,7 @@ def copyToClip(text: str, notify: Optional[bool] = False) -> bool: winUser.emptyClipboard() winUser.setClipboardData(winUser.CF_UNICODETEXT, text) got = getClipData() - except ctypes.WinError: + except OSError: if notify: ui.reportTextCopiedToClipboard() # No argument reports a failure. return False diff --git a/source/brailleDisplayDrivers/papenmeier.py b/source/brailleDisplayDrivers/papenmeier.py index 2257b444e62..21082b2067e 100644 --- a/source/brailleDisplayDrivers/papenmeier.py +++ b/source/brailleDisplayDrivers/papenmeier.py @@ -421,12 +421,60 @@ def _handleKeyPresses(self): "kb:alt": ("br(papenmeier):lt+d3",), "kb:control": ("br(papenmeier):lt+d2",), "kb:escape": ("br(papenmeier):space+d7",), - "kb:control+escape": ("br(papenmeier):lt+d1+d2+d3+d4+d5+d6",), "kb:tab": ("br(papenmeier):space+d3+d7",), "kb:upArrow": ("br(papenmeier):space+d2",), "kb:downArrow": ("br(papenmeier):space+d5",), "kb:leftArrow": ("br(papenmeier):space+d1",), "kb:rightArrow": ("br(papenmeier):space+d4",), + + "kb:control+escape": ("br(papenmeier):space+d1+d2+d3+d4+d5+d6",), + "kb:control+alt+delete": ("br(papenmeier):space+d1+d2+d3+d4+d5+d6+d7+d8",), + "kb:enter": ("br(papenmeier):space+d8", "br(papenmeier):d8",), + "kb:pageup": ("br(papenmeier):space+d3",), + "kb:pagedown": ("br(papenmeier):space+d6",), + "kb:backspace": ("br(papenmeier):space+d6+d8", "br(papenmeier):d7",), + "kb:home": ("br(papenmeier):space+d1+d2",), + "kb:end": ("br(papenmeier):space+d4+d5",), + "kb:delete": ("br(papenmeier):space+d5+d6",), + + "kb:f1": ("br(papenmeier):rt+d1",), + "kb:f2": ("br(papenmeier):rt+d1+d2",), + "kb:f3": ("br(papenmeier):rt+d1+d4",), + "kb:f4": ("br(papenmeier):rt+d1+d4+d5",), + "kb:f5": ("br(papenmeier):rt+d1+d5",), + "kb:f6": ("br(papenmeier):rt+d1+d2+d4",), + "kb:f7": ("br(papenmeier):rt+d1+d2+d4+d5",), + "kb:f8": ("br(papenmeier):rt+d1+d2+d5",), + "kb:f9": ("br(papenmeier):rt+d2+d4",), + "kb:f10": ("br(papenmeier):rt+d2+d4+d5",), + "kb:f11": ("br(papenmeier):rt+d1+d3",), + "kb:f12": ("br(papenmeier):rt+d1+d2+d3",), + "kb:control+a": ("br(papenmeier):d1+d7+d8",), + "kb:control+p": ("br(papenmeier):d1+d2+d3+d4+d7+d8",), + "kb:control+s": ("br(papenmeier):d2+d3+d4+d7+d8",), + "kb:control+b": ("br(papenmeier):d1+d2+d7+d8",), + "kb:control+c": ("br(papenmeier):d1+d4+d7+d8",), + "kb:control+d": ("br(papenmeier):d1+d4+d5+d7+d8",), + "kb:control+e": ("br(papenmeier):d1+d5+d7+d8",), + "kb:control+f": ("br(papenmeier):d1+d2+d4+d7+d8",), + "kb:control+g": ("br(papenmeier):d1+d2+d4+d5+d7+d8",), + "kb:control+h": ("br(papenmeier):d1+d2+d5+d7+d8",), + "kb:control+i": ("br(papenmeier):d2+d4+d7+d8",), + "kb:control+j": ("br(papenmeier):d2+d4+d5+d7+d8",), + "kb:control+k": ("br(papenmeier):d1+d3+d7+d8",), + "kb:control+l": ("br(papenmeier):d1+d2+d3+d7+d8",), + "kb:control+m": ("br(papenmeier):d1+d3+d4+d7+d8",), + "kb:control+n": ("br(papenmeier):d1+d3+d4+d5+d7+d8",), + "kb:control+o": ("br(papenmeier):d1+d3+d5+d7+d8",), + "kb:control+q": ("br(papenmeier):d1+d2+d3+d4+d5+d7+d8",), + "kb:control+r": ("br(papenmeier):d1+d2+d3+d5+d7+d8",), + "kb:control+t": ("br(papenmeier):d2+d3+d4+d5+d7+d8",), + "kb:control+u": ("br(papenmeier):d1+d3+d6+d7+d8",), + "kb:control+v": ("br(papenmeier):d1+d2+d3+d6+d7+d8",), + "kb:control+w": ("br(papenmeier):d2+d4+d5+d6+d7+d8",), + "kb:control+x": ("br(papenmeier):d1+d3+d4+d6+d7+d8",), + "kb:control+y": ("br(papenmeier):d1+d3+d4+d5+d6+d7+d8",), + "kb:control+z": ("br(papenmeier):d1+d3+d5+d6+d7+d8",), } }) @@ -535,7 +583,7 @@ def __init__(self, keys: Optional[Union[bytes, int]], driver: BrailleDisplayDriv self.id=brl_join_keys(brl_decode_key_names_repeat(driver)) return - if driver._baud != 1 and keys[0] == 'L': + if driver._baud != 1 and keys[0] == ord(b'L'): assert isinstance(keys, bytes) if (keys[3] - 48) >> 3: scancode = keys[5] - 48 << 4 | keys[6] - 48 diff --git a/source/brailleTables.py b/source/brailleTables.py index 60ea2a37baa..a640bae931b 100644 --- a/source/brailleTables.py +++ b/source/brailleTables.py @@ -1,7 +1,7 @@ # A part of NonVisual Desktop Access (NVDA) # This file is covered by the GNU General Public License. # See the file COPYING for more details. -# Copyright (C) 2008-2019 NV Access Limited, Joseph Lee, Babbage B.V. +# Copyright (C) 2008-2020 NV Access Limited, Joseph Lee, Babbage B.V. """Manages information about available braille translation tables. """ @@ -93,6 +93,9 @@ def listTables(): addTable("afr-za-g1.ctb", _("Afrikaans grade 1")) # Translators: The name of a braille table displayed in the # braille settings dialog. +addTable("afr-za-g2.ctb", _("Afrikaans grade 2"), contracted=True) +# Translators: The name of a braille table displayed in the +# braille settings dialog. addTable("ar-ar-comp8.utb", _("Arabic 8 dot computer braille")) # Translators: The name of a braille table displayed in the # braille settings dialog. diff --git a/source/cursorManager.py b/source/cursorManager.py index 4cbc0329744..3c2e17aaea1 100644 --- a/source/cursorManager.py +++ b/source/cursorManager.py @@ -15,6 +15,7 @@ import documentBase import gui from gui import guiHelper +import gui.contextHelp import sayAllHandler import review from scriptHandler import willSayAllResume, script @@ -31,7 +32,7 @@ class FindDialog( - gui.ContextHelpMixin, + gui.contextHelp.ContextHelpMixin, wx.Dialog, # wxPython does not seem to call base class initializer, put last in MRO ): """A dialog used to specify text to find in a cursor manager. diff --git a/source/gui/__init__.py b/source/gui/__init__.py index fea2a7a4d68..7a4e46e7851 100644 --- a/source/gui/__init__.py +++ b/source/gui/__init__.py @@ -1,9 +1,15 @@ # -*- coding: UTF-8 -*- -#gui/__init__.py -#A part of NonVisual Desktop Access (NVDA) -#Copyright (C) 2006-2018 NV Access Limited, Peter Vágner, Aleksey Sadovoy, Mesar Hameed, Joseph Lee, Thomas Stivers, Babbage B.V. -#This file is covered by the GNU General Public License. -#See the file COPYING for more details. +# A part of NonVisual Desktop Access (NVDA) +# Copyright (C) 2006-2020 NV Access Limited, Peter Vágner, Aleksey Sadovoy, Mesar Hameed, Joseph Lee, +# Thomas Stivers, Babbage B.V. +# This file is covered by the GNU General Public License. +# See the file COPYING for more details. + +from .contextHelp import ( + # several other submodules depend on ContextHelpMixin + # ensure early that it can be imported successfully. + ContextHelpMixin as _ContextHelpMixin, # don't expose from gui, import submodule directly. +) import time import os @@ -25,7 +31,6 @@ import queueHandler import core from . import guiHelper -from .contextHelp import ContextHelpMixin from .settingsDialogs import * from .inputGestures import InputGesturesDialog import speechDictHandler @@ -671,7 +676,7 @@ def run(): class WelcomeDialog( - ContextHelpMixin, + _ContextHelpMixin, wx.Dialog # wxPython does not seem to call base class initializer, put last in MRO ): """The NVDA welcome dialog. @@ -774,7 +779,7 @@ def run(cls): class LauncherDialog( - ContextHelpMixin, + _ContextHelpMixin, wx.Dialog # wxPython does not seem to call base class initializer, put last in MRO ): """The dialog that is displayed when NVDA is started from the launcher. @@ -1068,7 +1073,7 @@ def _isDebug(): class AskAllowUsageStatsDialog( - ContextHelpMixin, + _ContextHelpMixin, wx.Dialog # wxPython does not seem to call base class initializer, put last in MRO ): """A dialog asking if the user wishes to allow NVDA usage stats to be collected by NV Access.""" diff --git a/source/gui/addonGui.py b/source/gui/addonGui.py index b5afa36b44c..96f2e364f43 100644 --- a/source/gui/addonGui.py +++ b/source/gui/addonGui.py @@ -22,6 +22,8 @@ from . import nvdaControls from .dpiScalingHelper import DpiScalingHelperMixin, DpiScalingHelperMixinWithoutInit import gui.contextHelp + + def promptUserForRestart(): restartMessage = _( # Translators: A message asking the user if they wish to restart NVDA @@ -138,7 +140,7 @@ def _showAddonInfo(addon): class AddonsDialog( DpiScalingHelperMixinWithoutInit, - gui.ContextHelpMixin, + gui.contextHelp.ContextHelpMixin, wx.Dialog # wxPython does not seem to call base class initializer, put last in MRO ): @classmethod @@ -664,7 +666,7 @@ def _showConfirmAddonInstallDialog(parent, bundle): class IncompatibleAddonsDialog( DpiScalingHelperMixinWithoutInit, - gui.ContextHelpMixin, + gui.contextHelp.ContextHelpMixin, wx.Dialog # wxPython does not seem to call base class initializer, put last in MRO ): """A dialog that lists incompatible addons, and why they are not compatible""" diff --git a/source/gui/configProfiles.py b/source/gui/configProfiles.py index 0e512dea14a..ceb20ae0b3c 100644 --- a/source/gui/configProfiles.py +++ b/source/gui/configProfiles.py @@ -15,7 +15,7 @@ class ProfilesDialog( - gui.ContextHelpMixin, + gui.contextHelp.ContextHelpMixin, wx.Dialog # wxPython does not seem to call base class initializer, put last in MRO ): shouldSuspendConfigProfileTriggers = True @@ -310,7 +310,7 @@ def __init__(self, spec, display, profile): class TriggersDialog( - gui.ContextHelpMixin, + gui.contextHelp.ContextHelpMixin, wx.Dialog # wxPython does not seem to call base class initializer, put last in MRO ): helpId = "ConfigProfileTriggers" @@ -401,7 +401,7 @@ def onClose(self, evt): class NewProfileDialog( - gui.ContextHelpMixin, + gui.contextHelp.ContextHelpMixin, wx.Dialog # wxPython does not seem to call base class initializer, put last in MRO ): helpId = "ProfilesCreating" @@ -537,7 +537,7 @@ def onTriggerChoice(self, evt): class RenameProfileDialog( - gui.ContextHelpMixin, + gui.contextHelp.ContextHelpMixin, wx.TextEntryDialog, # wxPython does not seem to call base class initializer, put last in MRO ): helpId = "ProfilesBasicManagement" diff --git a/source/gui/contextHelp.py b/source/gui/contextHelp.py index a043ce7a0a3..5c562d25f7a 100644 --- a/source/gui/contextHelp.py +++ b/source/gui/contextHelp.py @@ -6,10 +6,7 @@ import os import tempfile import typing -import queueHandler -import gui -import ui import wx from logHandler import log @@ -29,11 +26,16 @@ def showHelp(helpId: str): button in an NVDA dialog is pressed or the F1 key is pressed on a recognized control. """ + + import ui + import queueHandler if not helpId: # Translators: Message indicating no context sensitive help is available for the control or dialog. noHelpMessage = _("No help available here.") queueHandler.queueFunction(queueHandler.eventQueue, ui.message, noHelpMessage) return + + import gui helpFile = gui.getDocFilePath("userGuide.html") if helpFile is None: # Translators: Message shown when trying to display context sensitive help, diff --git a/source/gui/installerGui.py b/source/gui/installerGui.py index cfccd3ec6ce..8c7fd3e6377 100644 --- a/source/gui/installerGui.py +++ b/source/gui/installerGui.py @@ -18,8 +18,8 @@ from logHandler import log import gui from gui import guiHelper +import gui.contextHelp from gui.dpiScalingHelper import DpiScalingHelperMixinWithoutInit -from .contextHelp import ContextHelpMixin import tones import systemUtils @@ -125,7 +125,7 @@ def doSilentInstall( class InstallerDialog( DpiScalingHelperMixinWithoutInit, - gui.ContextHelpMixin, + gui.contextHelp.ContextHelpMixin, wx.Dialog, # wxPython does not seem to call base class initializer, put last in MRO ): @@ -268,7 +268,7 @@ def onReviewAddons(self, evt): class InstallingOverNewerVersionDialog( DpiScalingHelperMixinWithoutInit, - gui.ContextHelpMixin, + gui.contextHelp.ContextHelpMixin, wx.Dialog, # wxPython does not seem to call base class initializer, put last in MRO ): @@ -330,7 +330,7 @@ def showInstallGui(): class PortableCreaterDialog( - ContextHelpMixin, + gui.contextHelp.ContextHelpMixin, wx.Dialog, # wxPython does not seem to call base class initializer, put last in MRO ): diff --git a/source/gui/settingsDialogs.py b/source/gui/settingsDialogs.py index d4fc5899d84..b2647c7dfbb 100644 --- a/source/gui/settingsDialogs.py +++ b/source/gui/settingsDialogs.py @@ -23,6 +23,7 @@ import languageHandler import speech import gui +import gui.contextHelp import globalVars from logHandler import log import nvwave @@ -55,10 +56,9 @@ import keyLabels from .dpiScalingHelper import DpiScalingHelperMixinWithoutInit - class SettingsDialog( DpiScalingHelperMixinWithoutInit, - gui.ContextHelpMixin, + gui.contextHelp.ContextHelpMixin, wx.Dialog, # wxPython does not seem to call base class initializer, put last in MRO metaclass=guiHelper.SIPABCMeta ): @@ -252,7 +252,7 @@ def _onWindowDestroy(self, evt): class SettingsPanel( DpiScalingHelperMixinWithoutInit, - gui.ContextHelpMixin, + gui.contextHelp.ContextHelpMixin, wx.Panel, # wxPython does not seem to call base class initializer, put last in MRO metaclass=guiHelper.SIPABCMeta ): @@ -864,7 +864,7 @@ def postSave(self): class LanguageRestartDialog( - gui.ContextHelpMixin, + gui.contextHelp.ContextHelpMixin, wx.Dialog, # wxPython does not seem to call base class initializer, put last in MRO ): @@ -2472,7 +2472,7 @@ def onSave(self): class AdvancedPanelControls( - gui.ContextHelpMixin, + gui.contextHelp.ContextHelpMixin, wx.Panel, # wxPython does not seem to call base class initializer, put last in MRO ): """Holds the actual controls for the Advanced Settings panel, this allows the state of the controls to @@ -2820,7 +2820,7 @@ def onEnableControlsCheckBox(self, evt): class DictionaryEntryDialog( - gui.ContextHelpMixin, + gui.contextHelp.ContextHelpMixin, wx.Dialog, # wxPython does not seem to call base class initializer, put last in MRO ): helpId = "SpeechDictionaries" @@ -3943,7 +3943,7 @@ def Destroy(self): class AddSymbolDialog( - gui.ContextHelpMixin, + gui.contextHelp.ContextHelpMixin, wx.Dialog # wxPython does not seem to call base class initializer, put last in MRO ): diff --git a/source/keyboardHandler.py b/source/keyboardHandler.py index 2b256263ca6..5d685d32fab 100644 --- a/source/keyboardHandler.py +++ b/source/keyboardHandler.py @@ -651,16 +651,9 @@ def injectRawKeyboardInput(isPress, code, isExtended): # Change what we pass to MapVirtualKeyEx, but don't change what NVDA gets. mapScan |= 0xE000 vkCode = winUser.user32.MapVirtualKeyExW(mapScan, winUser.MAPVK_VSC_TO_VK_EX, getInputHkl()) - if isPress: - shouldSend = internal_keyDownEvent(vkCode, code, isExtended, False) - else: - shouldSend = internal_keyUpEvent(vkCode, code, isExtended, False) - if shouldSend: - flags = 0 - if not isPress: - flags |= 2 - if isExtended: - flags |= 1 - with ignoreInjection(): - winUser.keybd_event(vkCode, code, flags, None) - wx.Yield() + flags = 0 + if not isPress: + flags |= 2 + if isExtended: + flags |= 1 + winUser.keybd_event(vkCode, code, flags, None) diff --git a/source/locale/fr/symbols.dic b/source/locale/fr/symbols.dic index 31e3942f9c7..6f24a53cd34 100644 --- a/source/locale/fr/symbols.dic +++ b/source/locale/fr/symbols.dic @@ -7,13 +7,13 @@ complexSymbols: # identifier regexp # Sentence endings. . sentence ending (?<=[^\s.])\s?\.(?=[\"'”’);\s]|$) -! sentence ending (?<=[^\s!])\s?\!(?=[\"'”’);\s]|$) -? sentence ending (?<=[^\s?])\s?\?(?=[\"'”’);\s]|$) +! sentence ending (?<=[^\s!])\s?\!(?=[\"'”’);!\s]|$) +? sentence ending (?<=[^\s?])\s?\?(?=[\"'”’);?\s]|$) ... sentence ending (?<=[^\s.])\s?\.\.\.(?=[\"'”’);\s]|$) … sentence ending (?<=[^\s…])\s?\…(?=[\"'”’);\s]|$) # Phrase endings. -; phrase ending (?<=[^\s;])\s?;(?=\s|$) -: phrase ending (?<=[^\s:])\s?:(?=\s|$) +; phrase ending (?<=[^\s;])\s?;(?=[\"'”’);\s]|$) +: phrase ending (?<=[^\s:])\s?:(?=[\"'”’);\s]|$) # Others decimal point (?