def script_end_combKeys(self, gesture): _tmpGesture = { 'up': 'uparrow', 'down': 'downarrow', 'left': 'leftarrow', 'right': 'rightarrow', } for g in configBE.iniGestures['globalCommands.GlobalCommands']: if isinstance( configBE.iniGestures['globalCommands.GlobalCommands'][g], list): for h in range( len(configBE.iniGestures['globalCommands.GlobalCommands'][g])): _tmpGesture[inputCore.normalizeGestureIdentifier(str(configBE.iniGestures['globalCommands.GlobalCommands'][g][h])).replace( 'br(' + configBE.curBD + '):', '')] = g.replace('kb:', '') elif ('kb:' in g and g not in ['kb:alt', 'kb:ctrl', 'kb:windows', 'kb:control', 'kb:applications'] and 'br(' + configBE.curBD + '):' in str(configBE.iniGestures['globalCommands.GlobalCommands'][g])): _tmpGesture[inputCore.normalizeGestureIdentifier(str(configBE.iniGestures['globalCommands.GlobalCommands'][g])).replace( 'br(' + configBE.curBD + '):', '')] = g.replace('kb:', '') gId = inputCore.normalizeGestureIdentifier( 'br(' + configBE.curBD + '):' + str(gesture.id)).replace('br(' + configBE.curBD + '):', '') sht = self.getActualModifiers(False) + _tmpGesture[gId] if gId not in _tmpGesture: return ui.message("Unknown " + gId) self.clearModifiers() self.clearMessageFlash() return self.sendComb(sht, gesture)
def initGestures(): global gesturesFileExists, iniGestures if profileFileExists and gesturesBDPath() != '?': log.debug('Main gestures map found') confGen = gesturesBDPath() confspec = ConfigObj(StringIO(""""""), encoding="UTF-8", list_values=False) iniGestures = ConfigObj(confGen, configspec=confspec, indent_type="\t", encoding="UTF-8") result = iniGestures.validate(Validator()) if result is not True: log.exception('Malformed configuration file') gesturesFileExists = False else: gesturesFileExists = True else: log.warn('No main gestures map (%s) found' % gesturesBDPath(1)) gesturesFileExists = False if gesturesFileExists: for g in iniGestures['globalCommands.GlobalCommands']: if isinstance( iniGestures['globalCommands.GlobalCommands'][g], list): for h in range( len(iniGestures['globalCommands.GlobalCommands'][g])): iniGestures[inputCore.normalizeGestureIdentifier( str(iniGestures['globalCommands.GlobalCommands'][g][h]))] = g elif ('kb:' in g and g not in ['kb:alt', 'kb:control', 'kb:windows', 'kb:control', 'kb:applications'] and 'br(' + curBD + '):' in str(iniGestures['globalCommands.GlobalCommands'][g])): iniGestures[inputCore.normalizeGestureIdentifier(str( iniGestures['globalCommands.GlobalCommands'][g])).replace('br(' + curBD + '):', '')] = g return gesturesFileExists, iniGestures
def initialize(self): if not hasattr(self, 'scriptTable'): self.scriptTable = {} for qn, (searchType, scriptMaker) in self.QUICK_NAV_SCRIPT_INFO.items(): gestureId = normalizeGestureIdentifier('kb:' + qn) self.scriptTable[gestureId] = 'script_moveToNext{st}'.format(st=searchType) gestureId = normalizeGestureIdentifier('kb:shift+' + qn) self.scriptTable[gestureId] = 'script_moveToPrevious{st}'.format(st=searchType) self.scriptTable['kb:c'] = 'script_openSourceFile'
def getGestureLabel(gesture): source, main = inputCore.getDisplayTextForGestureIdentifier( inputCore.normalizeGestureIdentifier(gesture) ) if gesture.startswith("kb:"): return main return u"{main} ({source})".format(source=source, main=main)
def removeGestureBinding(self,gestureIdentifier): """ Removes the binding for the given gesture identifier if a binding exists. @param gestureIdentifier: The identifier of the input gesture. @type gestureIdentifier: str @raise LookupError: If there is no binding for this gesture """ # Import late to avoid circular import. import inputCore del self._gestureMap[inputCore.normalizeGestureIdentifier(gestureIdentifier)]
def _setNVDANavMode(self): # A setMode() helper method, to put the numpad back in NVDA mode. # Overview: for each numpad gesture, check whether: # - There is a script for it; and # - Whether it is our script, which will be an emulated gesture or None. # If so, remove it. # If not (meaning it has been reassigned by the user or an add-on), leave it alone. checkThese = {} #: Mungible dict of gestures we use # Build the checkables for gFrag, action in self.numpadGestures.items(): checkThese[normalizeGestureIdentifier("kb(desktop):" + gFrag)] = action checkThese[normalizeGestureIdentifier("kb(laptop):" + gFrag)] = action # For these, the script should be None checkThese[normalizeGestureIdentifier("kb:" + gFrag)] = self.G( action.mod, action.cls, None) # For each user gesture, check: # - Whether it is the laptop or desktop or main version of one of ours; and # - if so, whether it is set as we set it (meaning it hasn't been remapped). # in which case we can delete it. for gest, action in self._getAllGesturesAsGDict().items(): try: # If it matches, we delete the gesture. # We skip it if it doesn't match, or if there's a KeyError. if checkThese[gest] == action: manager.userGestureMap.remove(gest, *action) del checkThese[gest] except KeyError: pass # FixMe: integrate the below code into the above, so we only have to loop the list once. # For our next trick, we need to check whether all former user gestures got reset. # We do that by checking each one against currently set gestures, and setting any that are missing. # We don't overwrite any gesture that has been set in the meantime. #: A map of the currently set user gestures, after Windows nav commands have been removed currentGestures = self._getAllGesturesAsGDict() for gest, action in self.userGestures.items(): # If the gesture isn't set, we need to put it back. if not gest in currentGestures: manager.userGestureMap.add(gest, *action, True)
def initVLCGestures(self): printDebug("appModule VLC: initVLCGestures") self.vlcGestures = {} for (keyList, script) in self._keyListToScript: for name in keyList: key = self.vlcrcSettings.getKeyFromName(name) if key != "": self.vlcGestures["kb:%s" % key] = script self.jumpKeyToDelay = {} for keyName in jumpDelays: key = self.vlcrcSettings.getKeyFromName(keyName) if key != "": identifier = normalizeGestureIdentifier("kb:%s" % key) self.jumpKeyToDelay[identifier] = jumpDelays[keyName] printDebug("appModuleVLC: initVLCGestures: gestures = %s" % self.vlcGestures)
def bindGesture(self, gestureIdentifier, scriptName): """Bind an input gesture to a script. @param gestureIdentifier: The identifier of the input gesture. @type gestureIdentifier: str @param scriptName: The name of the script, which is the name of the method excluding the C{script_} prefix. @type scriptName: str @raise LookupError: If there is no script with the provided name. """ # Don't store the instance method, as this causes a circular reference # and instance methods are meant to be generated on retrieval anyway. func = getattr(self.__class__, "script_%s" % scriptName, None) if not func: raise LookupError("No such script: %s" % func) # Import late to avoid circular import. import inputCore self._gestureMap[inputCore.normalizeGestureIdentifier(gestureIdentifier)] = func
def _get_identifiers(self): ids = super(DummyBrailleInputGesture, self)._get_identifiers() if isinstance(braille.handler.display, NoBrailleDisplayDriver): return ids answer = [] for id in ids: if id.startswith("bk:"): answer.append(id) continue physical_id = id.replace(self.source, braille.handler.display.name, 1) if physical_id.startswith("br(freedomScientific):" ): # Exception specific to this driver. physical_id = re.sub(r"(.*)space", r"\1brailleSpaceBar", physical_id) if cmpNVDAver(2018, 3) < 0: id = "bk:" + id[id.find(":") + 1:] if configure.get("REL_PHYSICAL_DUMMY_BRLKB") == "consistent": answer.append(physical_id) elif configure.get( "REL_PHYSICAL_DUMMY_BRLKB") == "former-precedence": answer.append(physical_id) answer.append(id) elif configure.get( "REL_PHYSICAL_DUMMY_BRLKB") == "latter-precedence": answer.append(id) answer.append(physical_id) elif configure.get("REL_PHYSICAL_DUMMY_BRLKB") == "independent": answer.append(id) else: log.error("Invalid REL_PHYSICAL_DUMMY_BRLKB value.", exc_info=True) if cmpNVDAver(2018, 3) < 0: answer, old_answer, id_set = [], answer, set() for id in old_answer: n_id = inputCore.normalizeGestureIdentifier(id) if n_id not in id_set: id_set.add(n_id) answer.append(id) return answer
def isAJumpOutOfMedia(self, gesture): mainWindow = self.appModule.mainWindow (layout, identifier) = gesture._get_identifiers() delay = self.appModule.jumpKeyToDelay[normalizeGestureIdentifier(identifier)] totalTime = mainWindow.getTotalTime() if totalTime is None: return False totalTimeList = getTimeList(totalTime) totalTimeInSec = int(totalTimeList[0])*3600 + int(totalTimeList[1])*60 + int(totalTimeList[2]) # noqa:E501 currentTime = mainWindow.getCurrentTime() curTimeInSec = getTimeInSec(currentTime) # Translators: message to the user to say time jump is not possible. msg = _("Not available, jump is too big ") if delay > 0: diff = totalTimeInSec - curTimeInSec pause = True if ((diff <= 10) or (diff >= delay and diff - delay <= 10))\ else False if pause: # to prevent vlc to stop media, we pause the media isPlaying = mainWindow.isPlaying() if isPlaying: mainWindow.togglePlayOrPause() queueHandler.queueFunction( queueHandler.eventQueue, speech.speakMessage, _("Pause")) if diff <= abs(delay): queueHandler.queueFunction(queueHandler.eventQueue, ui.message, msg) mainWindow.sayElapsedTime(True) queueHandler.queueFunction( queueHandler.eventQueue, ui.message, # Translators: message to the user to report media duration. _("Media duration %s") % formatTime(totalTime)) return True elif delay < 0: if curTimeInSec < abs(delay): queueHandler.queueFunction(queueHandler.eventQueue, ui.message, msg) mainWindow.sayElapsedTime(True) return True return False
class BrailleInputGesture(inputCore.InputGesture): """Input (dots and/or space bar) from a braille keyboard. This could either be as part of a braille display or a stand-alone unit. L{dots} and L{space} should be set appropriately. """ #: Bitmask of pressed dots. #: @type: int dots = 0 #: Whether the space bar is pressed. #: @type: bool space = False shouldPreventSystemIdle = True def _makeDotsId(self): items = ["dot%d" % (i+1) for i in range(8) if self.dots & (1 << i)] if self.space: items.append("space") return "bk:" + "+".join(items) #: The generic gesture identifier for space plus any dots. #: This could be used to bind many braille commands to a single script. GENERIC_ID_SPACE_DOTS = inputCore.normalizeGestureIdentifier("bk:space+dots") #: The generic gesture identifier for any dots. #: This is used to bind entry of braille text to a single script. GENERIC_ID_DOTS = inputCore.normalizeGestureIdentifier("bk:dots") def _get_identifiers(self): if self.space and self.dots: return (self._makeDotsId(), self.GENERIC_ID_SPACE_DOTS) elif self.dots in (DOT7, DOT8, DOT7 | DOT8): # Allow bindings to dots 7 and/or 8 by themselves. return (self._makeDotsId(), self.GENERIC_ID_DOTS) elif self.dots or self.space: return (self.GENERIC_ID_DOTS,) else: return () @classmethod def _makeDisplayText(cls, dots: int, space: bool): out = "" if space and dots: # Translators: Reported when braille space is pressed with dots in input help mode. out = _("space with dot") elif dots: # Translators: Reported when braille dots are pressed in input help mode. out = _("dot") elif space: # Translators: Reported when braille space is pressed in input help mode. out = _("space") if dots: out += " " + formatDotNumbers(dots) return out def _get_displayName(self): if not self.dots and not self.space: return None return self._makeDisplayText(self.dots, self.space) @classmethod def getDisplayTextForIdentifier(cls, identifier: str): assert isinstance(identifier, str) # Translators: Used when describing keys on a braille keyboard. source = _("braille keyboard") if identifier == cls.GENERIC_ID_SPACE_DOTS: # Translators: Used to describe the press of space # along with any dots on a braille keyboard. return (source, _("space with any dots")) if identifier == cls.GENERIC_ID_DOTS: # Translators: Used to describe the press of any dots # on a braille keyboard. return (source, _("any dots")) # Example identifier: bk:space+dot1+dot2 # Strip the bk: prefix. partsStr = identifier.split(":", 1)[1] parts = partsStr.split("+") dots = 0 space = False for part in parts: if part == "space": space = True else: # Example part: "dot1" # Get the dot number and make it 0 based instead of 1 based. dot = int(part[3]) - 1 # Update the dots bitmask. dots += 1 << dot return (source, cls._makeDisplayText(dots, space))
def gesturesInit(self): # rotor gestures if 'rotor' in configBE.iniProfile.keys(): for k in configBE.iniProfile["rotor"]: if isinstance(configBE.iniProfile["rotor"][k], list): for l in configBE.iniProfile["rotor"][k]: self.rotorGES['br(%s):%s' % (configBE.curBD, l)] = k else: self.rotorGES['br(%s):%s' %(configBE.curBD, configBE.iniProfile["rotor"][k])] = k log.debug(self.rotorGES) else: log.debug('No rotor gestures for this profile') # keyboard layout gestures gK = OrderedDict() try: cK = configBE.iniProfile['keyboardLayouts'][configBE.conf['general']['keyboardLayout_%s' % configBE.curBD]] if configBE.conf['general']['keyboardLayout_%s' % configBE.curBD] and configBE.conf['general']['keyboardLayout_%s' % configBE.curBD] in configBE.iniProfile['keyboardLayouts'] is not None else configBE.iniProfile['keyboardLayouts'].keys()[0] for k in cK: if k in ['enter', 'backspace']: if isinstance(cK[k], list): for l in cK[k]: gK[inputCore.normalizeGestureIdentifier('br(%s):%s' %(configBE.curBD, l))] = 'kb:%s' % k else: gK['kb:%s' % k] = inputCore.normalizeGestureIdentifier('br(%s):%s' % (configBE.curBD, cK[k])) elif k in ['braille_dots', 'braille_enter', 'braille_translate']: if isinstance(cK[k], list): for i in range(len(cK[k])): if ':' not in cK[k][i]: cK[k][i] = inputCore.normalizeGestureIdentifier('br(%s):%s' % (configBE.curBD, cK[k][i])) else: if ':' not in cK[k]: cK[k] = 'br(%s):%s' %(configBE.curBD, cK[k]) gK[k] = cK[k] inputCore.manager.localeGestureMap.update({'globalCommands.GlobalCommands': gK}) self.noKC = False log.debug('Keyboard conf found, loading layout `%s`' %configBE.conf['general']['keyboardLayout_' + configBE.curBD]) except BaseException: log.debug('No keyboard conf found') self.noKC = True # Hack for NVDARemote if 'fr' in lang: nvdaremote_gestures = u"abcdefghijklmnopqrstuvwxyz0123456789²)=^$ù*<,;:!" else: nvdaremote_gestures = u"abcdefghijklmnopqrstuvwxyz0123456789`-=[];'\\,./" nvdaremote_gestures2 = ["escape","home","end","pageup","pagedown","backspace","leftarrow","rightarrow","uparrow","downarrow","enter","delete","space","ACCENT CIRCONFLEXE"] self._tGestures = { "bk:dots": "end_combKeysChar", "br(" + configBE.curBD + "):routing": "cancelShortcut", #: arrow keys "br(" + configBE.curBD + "):up": "end_combKeys", "br(" + configBE.curBD + "):down": "end_combKeys", "br(" + configBE.curBD + "):left": "end_combKeys", "br(" + configBE.curBD + "):right": "end_combKeys", } for k in nvdaremote_gestures: self._tGestures['kb:%s' % k] = "end_combKeysChar" for k in range(0, 13): self._tGestures['kb:f%s' % k] = "end_combKeysChar" for k in nvdaremote_gestures2: self._tGestures['kb:%s' % k] = "end_combKeysChar" if configBE.gesturesFileExists: for g in configBE.iniGestures['globalCommands.GlobalCommands']: if isinstance(configBE.iniGestures['globalCommands.GlobalCommands'][g], list): for h in range(len(configBE.iniGestures['globalCommands.GlobalCommands'][g])): self._tGestures[inputCore.normalizeGestureIdentifier(configBE.iniGestures['globalCommands.GlobalCommands'][g][h])] = "end_combKeys" elif ('kb:' in g and g.lower() not in ['kb:alt', 'kb:control', 'kb:windows', 'kb:control', 'kb:applications']): self._tGestures[inputCore.normalizeGestureIdentifier(configBE.iniGestures['globalCommands.GlobalCommands'][g])] = "end_combKeys" self._pGestures = OrderedDict() for k, v in (configBE.iniProfile["modifierKeys"].items() + [k for k in configBE.iniProfile["miscs"].items() if k[0] != 'defaultQuickLaunches']): if isinstance(v, list): for i, gesture in enumerate(v): if k != 'shortcutsOn': self._pGestures[inputCore.normalizeGestureIdentifier('br(%s):%s' % (configBE.curBD, gesture))] = k else: self._pGestures[inputCore.normalizeGestureIdentifier('br(%s):%s' % (configBE.curBD, v))] = k self.bindGestures(self._pGestures) self.bindGestures({'br(%s):%s' % (configBE.curBD, k): "quickLaunch" for k in configBE.quickLaunches.keys()}) return
def sendCombKeysNVDA(self, sht, gesture): # to improve + not finished if 'kb:' not in sht: sht = 'kb:%s' % sht add = '+nvda' if 'nvda+' in sht else '' sht = '+'.join(sorted((inputCore.normalizeGestureIdentifier(sht.replace('nvda+', '')).replace('kb:','') + add).split('+'))) # Gesture specific scriptable object (TODO). # Global plugin level shtPlugins = {p: eval('globalPlugins.%s.GlobalPlugin._GlobalPlugin__gestures' % p) for p in globalPlugins.__dict__.keys() if not p.startswith('_') and hasattr(eval('globalPlugins.%s.GlobalPlugin' % p), '_GlobalPlugin__gestures')} for k in shtPlugins: shtPlugins[k] = {re.sub(':(.+)$', lambda m: inputCore.normalizeGestureIdentifier(m.group(0)), g.lower().replace(' ', '')): shtPlugins[k][g] for g in shtPlugins[k] if g.lower().startswith('kb:')} for p in shtPlugins.keys(): if 'kb:' + sht in shtPlugins[p]: if self.callScript('globalPlugins.%s' % p, 'script_%s' % shtPlugins[p]['kb:' + sht], gesture): return True # App module level. focus = api.getFocusObject() app = focus.appModule for k in focus.appModule._gestureMap: if app and cls == 'AppModule' and module == app.__module__: func = getattr(app, "script_%s" % scriptName, None) if func: func(gesture) return True # Tree interceptor level. try: obj = api.getFocusObject() if obj.treeInterceptor is not None: obj = obj.treeInterceptor gesS = obj._CursorManager__gestures.values() + obj._BrowseModeDocumentTreeInterceptor__gestures.values() + obj._BrowseModeTreeInterceptor__gestures.values() gesO = [re.sub(':(.+)$', lambda m: m.group(0), g) for g in obj._CursorManager__gestures.keys() + obj._BrowseModeDocumentTreeInterceptor__gestures.keys() + obj._BrowseModeTreeInterceptor__gestures.keys()] gesN = [re.sub(':(.+)$', lambda m: inputCore.normalizeGestureIdentifier(m.group(0)), g) for g in gesO] script = gesS[gesN.index('kb:' + sht)] eval('obj.script_' + script + '(gesture)') return True else: gesO = [re.sub(':(.+)$', lambda m: m.group(0), g) for g in cursorManager.CursorManager._CursorManager__gestures] gesN = [re.sub(':(.+)$', lambda m: inputCore.normalizeGestureIdentifier(m.group(0)), g) for g in cursorManager.CursorManager._CursorManager__gestures] if 'kb:' + sht in gesN: a = cursorManager.CursorManager() a.makeTextInfo = obj.makeTextInfo script = a._CursorManager__gestures[gesO[gesN.index( 'kb:' + sht)]] eval('a.script_' + script + '(gesture)') return True except BaseException: pass # NVDAObject level (todo). # Global Commands level. layouts = ['(%s)' % config.conf["keyboard"]["keyboardLayout"], '', '(%s)' % ('desktop' if config.conf["keyboard"]["keyboardLayout"] == 'laptop' else 'desktop')] places = ['globalCommands.commands._gestureMap'] for layout in layouts: for place in places: try: tSht = eval('scriptHandler.getScriptName(%s[\'kb%s:%s\'])' % (place, layout, sht)) func = getattr(globalCommands.commands, "script_%s" % tSht, None) if func: func(gesture) return True except BaseException: pass return False