def event_appModule_gainFocus(self): inputCore.manager._captureFunc = self._inputCaptor if not config.conf["reviewCursor"]["followFocus"]: # Move the review cursor so others can't access its previous position. self._oldReviewPos = api.getReviewPosition() self._oldReviewObj = self._oldReviewPos.obj api.setNavigatorObject(eventHandler.lastQueuedFocusObject)
def updateNamespaceSnapshotVars(self): """Update the console namespace with a snapshot of NVDA's current state. This creates/updates variables for the current focus, navigator object, etc. Typically, used before the NVDA python console is opened, after which, calls to the 'api' module will refer to this new focus. """ try: caretPos = api.getCaretPosition() except RuntimeError: log.debug( "Unable to set caretPos snapshot variable for python console.") caretPos = None self._namespaceSnapshotVars = { "focus": api.getFocusObject(), # Copy the focus ancestor list, as it gets mutated once it is replaced in api.setFocusObject. "focusAnc": list(api.getFocusAncestors()), "fdl": api.getFocusDifferenceLevel(), "fg": api.getForegroundObject(), "nav": api.getNavigatorObject(), "caretObj": api.getCaretObject(), "caretPos": caretPos, "review": api.getReviewPosition(), "mouse": api.getMouseObject(), "brlRegions": braille.handler.buffer.regions, } self.namespace.update(self._namespaceSnapshotVars)
def getTextToAdd(self): newText = self.getSelectedText() or self.getMath() if not newText: if not self._copyStartMarker: # Translators: message presented when it's not possible to add text, since no text has been selected or marked. ui.message(_("No selection. No start marker set")) return pos = api.getReviewPosition().copy() if self._copyStartMarker.obj != pos.obj: # Translators: Message presented when a start marked has been placed, but not in the current object. ui.message( _("The start marker must reside within the same object")) return pos.move(textInfos.UNIT_CHARACTER, 1, endPoint="end") pos.setEndPoint(self._copyStartMarker, "startToStart") if not pos.compareEndPoints(pos, "startToEnd") < 0: # Translators: message presented when review cursor has been used to add text and there is no text to add. ui.message(_("No text to add")) return newText = pos.clipboardText self._copyStartMarker = None try: clipData = api.getClipData() if config.conf["clipContentsDesigner"]["addTextBefore"]: text = newText + getBookmark() + clipData else: text = clipData + getBookmark() + newText except TypeError: text = newText return text
def script_review_nextCharacter(self,gesture): lineInfo=api.getReviewPosition().copy() lineInfo.expand(textInfos.UNIT_LINE) charInfo=api.getReviewPosition().copy() charInfo.expand(textInfos.UNIT_CHARACTER) charInfo.collapse() res=charInfo.move(textInfos.UNIT_CHARACTER,1) if res==0 or charInfo.compareEndPoints(lineInfo,"endToEnd")>=0: speech.speakMessage(_("right")) reviewInfo=api.getReviewPosition().copy() reviewInfo.expand(textInfos.UNIT_CHARACTER) speech.speakTextInfo(reviewInfo,unit=textInfos.UNIT_CHARACTER,reason=speech.REASON_CARET) else: api.setReviewPosition(charInfo.copy()) charInfo.expand(textInfos.UNIT_CHARACTER) speech.speakTextInfo(charInfo,unit=textInfos.UNIT_CHARACTER,reason=speech.REASON_CARET)
def displayCurrentCharInfoMessage(self): ### Code inspired from NVDA script_review_currentCharacter in file globalCommands.py info=api.getReviewPosition().copy() info.expand(textInfos.UNIT_CHARACTER) if info.text == '': speech.speakTextInfo(info,unit=textInfos.UNIT_CHARACTER,reason=controlTypes.REASON_CARET) return font = self.getCurrCharFontName(info) try: c = ord(info.text) except TypeError: # This might be a character taking multiple code points. # If it is a 32 bit character, encode it to UTF-32 and calculate the ord manually. # In Python 3, this is no longer necessary. try: encoded = info.text.encode("utf_32_le") except UnicodeEncodeError: c = None else: if len(encoded)==4: c = sum(ord(cp)<<i*8 for i, cp in enumerate(encoded)) else: c = None ### End code copy if c is not None: char = Character(c, info.text, font) computedInfoList = [(t, getattr(char, f)()) for t,f in requiredInfoList] if char.isMsFont(): computedInfoList.extend([(t, getattr(char, f)()) for t,f in msCharInfoList]) else: computedInfoList = [(t,'N/A') for t,f in requiredInfoList] infoTable = createHtmlInfoTable(computedInfoList ) htmlMessage = gHtmlMessage.format(infoTable=infoTable) ui.browseableMessage(htmlMessage, title=pageTitle, isHtml= True)
def script_reverse_review_currentCharacter(self, gesture): CJK["direction"] = -1 CJK["isReviewCharacter"] = True info = api.getReviewPosition().copy() info.expand(textInfos.UNIT_CHARACTER) speech.speakSpelling(info.text, useCharacterDescriptions=True) CJK["direction"] = 0 CJK["isReviewCharacter"] = False
def script_review_startOfLine(self,gesture): info=api.getReviewPosition().copy() info.expand(textInfos.UNIT_LINE) info.collapse() api.setReviewPosition(info.copy()) info.expand(textInfos.UNIT_CHARACTER) speech.speakMessage(_("left")) speech.speakTextInfo(info,unit=textInfos.UNIT_CHARACTER,reason=speech.REASON_CARET)
def script_review_currentWord(self,gesture): info=api.getReviewPosition().copy() info.expand(textInfos.UNIT_WORD) scriptCount=scriptHandler.getLastScriptRepeatCount() if scriptCount==0: speech.speakTextInfo(info,reason=speech.REASON_CARET,unit=textInfos.UNIT_WORD) else: speech.speakSpelling(info.text,useCharacterDescriptions=bool(scriptCount>1))
def script_review_currentCharacter(self,gesture): scriptCount=scriptHandler.getLastScriptRepeatCount() if scriptCount >= 4: return elif scriptCount <= 2: commands.script_review_currentCharacter(gesture) return self.displayCurrentCharInfoMessage(info = api.getReviewPosition().copy())
def script_review_previousLine(self,gesture): info=api.getReviewPosition().copy() info.expand(textInfos.UNIT_LINE) info.collapse() res=info.move(textInfos.UNIT_LINE,-1) api.setReviewPosition(info.copy()) info.expand(textInfos.UNIT_LINE) if res==0: speech.speakMessage(_("top")) speech.speakTextInfo(info,unit=textInfos.UNIT_LINE,reason=speech.REASON_CARET)
def review(self, unit, direction, verbose=True): reviewOldMode = api.review.getCurrentMode() api.review.setCurrentMode("object") if self.reviewPosition: api.setReviewPosition(self.reviewPosition) info = api.getReviewPosition().copy() info.expand(unit) info.collapse() info.move(unit, direction) api.setReviewPosition(info) info.expand(unit) if verbose: speakTextInfo(info, unit=unit, reason=controlTypes.REASON_CARET if hasattr( controlTypes, "REASON_CARET") else controlTypes.OutputReason.CARET) self.reviewPosition = api.getReviewPosition() api.review.setCurrentMode(reviewOldMode) return info.move(unit, 1)
def script_review_nextWord(self,gesture): info=api.getReviewPosition().copy() info.expand(textInfos.UNIT_WORD) info.collapse() res=info.move(textInfos.UNIT_WORD,1) api.setReviewPosition(info.copy()) info.expand(textInfos.UNIT_WORD) if res==0: speech.speakMessage(_("bottom")) speech.speakTextInfo(info,reason=speech.REASON_CARET,unit=textInfos.UNIT_WORD)
def script_navigatorObject_moveToObjectAtFlatReviewPosition(self,gesture): pos=api.getReviewPosition() try: obj=pos.NVDAObjectAtStart except NotImplementedError: obj=None if obj and obj!=pos.obj: api.setNavigatorObject(obj) speech.speakObject(obj) else: speech.speakMessage(_("No object at flat review position"))
def handleReviewMove(self): if not self.enabled: return if self.tether != self.TETHER_REVIEW: return reviewPos = api.getReviewPosition() region = self.mainBuffer.regions[-1] if self.mainBuffer.regions else None if region and region.obj == reviewPos.obj: self._doCursorMove(region) else: # We're reviewing a different object. self._doNewObject(getFocusRegions(reviewPos.obj, review=True))
def script_modified_review_nextCharacter(self, gesture): #Add character description Braille output to the review character when Braille review mode is turned on. lineInfo = api.getReviewPosition().copy() lineInfo.expand(textInfos.UNIT_LINE) charInfo = api.getReviewPosition().copy() charInfo.expand(textInfos.UNIT_CHARACTER) charInfo.collapse() res = charInfo.move(textInfos.UNIT_CHARACTER, 1) if res == 0 or charInfo.compareEndPoints(lineInfo, "endToEnd") >= 0: ui.reviewMessage(_("Right")) reviewInfo = api.getReviewPosition().copy() reviewInfo.expand(textInfos.UNIT_CHARACTER) speech.speakTextInfo(reviewInfo, unit=textInfos.UNIT_CHARACTER, reason=controlTypes.OutputReason.CARET) char = reviewInfo.text.lower() if not isAlphanumeric(char) and CJK["brailleReview"] == "Auto": try: charDesc = characterProcessing.getCharacterDescription( CJK["locale"], char) BrailleHandler.message(handler, char + " " + " ".join(charDesc)) except TypeError: pass else: api.setReviewPosition(charInfo) charInfo.expand(textInfos.UNIT_CHARACTER) speech.speakTextInfo(charInfo, unit=textInfos.UNIT_CHARACTER, reason=controlTypes.OutputReason.CARET) char = charInfo.text.lower() if not isAlphanumeric(char) and CJK["brailleReview"] == "Auto": try: charDesc = characterProcessing.getCharacterDescription( CJK["locale"], char) BrailleHandler.message(handler, char + " " + " ".join(charDesc)) except TypeError: pass
def event_typedCharacter(self, ch): if ord(ch) < 128: if config.conf['keyboard']['speakTypedWords'] and hasattr( self.parent, '_caretMovementScriptHelper'): self.focusToParent() info = api.getReviewPosition() if not ch.isspace(): info.move(textInfos.UNIT_CHARACTER, -1) info.move(textInfos.UNIT_CHARACTER, -1) info.collapse() info.expand(textInfos.UNIT_WORD) speech.speakText(info.text) super(KoreanInputComposition, self).event_typedCharacter(ch)
def __init__(self, cursor): self.cursor = cursor self.trigger = SayAllProfileTrigger() self.trigger.enter() # Start at the cursor. if cursor == CURSOR_CARET: try: self.reader = api.getCaretObject().makeTextInfo(textInfos.POSITION_CARET) except (NotImplementedError, RuntimeError): return else: self.reader = api.getReviewPosition() self.speakTextInfoState = speech.SpeakTextInfoState(self.reader.obj) self.numBufferedLines = 0
def getTextToAdd(self): newText = self.getSelectedText() or self.getMath() if not newText: if not getattr(api.getReviewPosition().obj, "_selectThenCopyRange", None) or not api.getReviewPosition( ).obj._selectThenCopyRange: # Translators: message presented when it's not possible to add text, since no text has been selected. ui.message(_("No text to add")) return newText = api.getReviewPosition( ).obj._selectThenCopyRange.clipboardText try: clipData = api.getClipData() except Exception: clipData = None if clipData: if config.conf["clipContentsDesigner"]["addTextBefore"]: text = newText + getBookmark() + clipData else: text = clipData + getBookmark() + newText else: text = newText return text
def getTextToAdd(): newText = getSelectedText() or getMath() if not newText: if not getattr( api.getReviewPosition().obj, "_selectThenCopyRange", None) or not api.getReviewPosition().obj._selectThenCopyRange: # Translators: message presented when it's not possible to add text, since no text has been selected. ui.message(_("No text to add")) return newText = api.getReviewPosition( ).obj._selectThenCopyRange.clipboardText try: clipData = api.getClipData() except Exception: clipData = None if clipData: if _NVDAConfigManager.toggleAddTextBeforeOption(False): text = newText + getBookmark() + clipData else: text = clipData + getBookmark() + newText else: text = newText return text
def copyReviewUnitToClipboard(unit, copyFrom=None): try: pos = api.getReviewPosition() info = pos.copy() info.expand(unit) if copyFrom: info.setEndPoint(pos, copyFrom) copyStatus = info.copyToClipboard() if not copyStatus: raise RuntimeError # Translators: Copying to the clipboard was successful. ui.message(_("Copied")) except: # Translators: Copying to the clipboard failed. ui.message(_("Failed to copy"))
def getMath(self): import mathPres mathMl = mathPres.getMathMlFromTextInfo(api.getReviewPosition()) if not mathMl: obj = api.getNavigatorObject() if obj.role == controlTypes.Role.MATH: try: mathMl = obj.mathMl except (NotImplementedError, LookupError): mathMl = None if not mathMl: return if mathPres.brailleProvider: text = mathPres.brailleProvider.getBrailleForMathMl(mathMl) return text
def script_review_currentCharacter(self,gesture): info=api.getReviewPosition().copy() info.expand(textInfos.UNIT_CHARACTER) scriptCount=scriptHandler.getLastScriptRepeatCount() if scriptCount==0: speech.speakTextInfo(info,unit=textInfos.UNIT_CHARACTER,reason=speech.REASON_CARET) elif scriptCount==1: speech.speakSpelling(info.text,useCharacterDescriptions=True) else: try: c = ord(info.text) speech.speakMessage("%d," % c) speech.speakSpelling(hex(c)) except: speech.speakTextInfo(info,unit=textInfos.UNIT_CHARACTER,reason=speech.REASON_CARET)
def updateNamespaceSnapshotVars(self): """Update the console namespace with a snapshot of NVDA's current state. This creates/updates variables for the current focus, navigator object, etc. """ self._namespaceSnapshotVars = { "focus": api.getFocusObject(), # Copy the focus ancestor list, as it gets mutated once it is replaced in api.setFocusObject. "focusAnc": list(api.getFocusAncestors()), "fdl": api.getFocusDifferenceLevel(), "fg": api.getForegroundObject(), "nav": api.getNavigatorObject(), "review":api.getReviewPosition(), "mouse": api.getMouseObject(), "brlRegions": braille.handler.buffer.regions, } self.namespace.update(self._namespaceSnapshotVars)
def updateNamespaceSnapshotVars(self): """Update the console namespace with a snapshot of NVDA's current state. This creates/updates variables for the current focus, navigator object, etc. """ self._namespaceSnapshotVars = { "focus": api.getFocusObject(), # Copy the focus ancestor list, as it gets mutated once it is replaced in api.setFocusObject. "focusAnc": list(api.getFocusAncestors()), "fdl": api.getFocusDifferenceLevel(), "fg": api.getForegroundObject(), "nav": api.getNavigatorObject(), "review": api.getReviewPosition(), "mouse": api.getMouseObject(), "brlRegions": braille.handler.buffer.regions, } self.namespace.update(self._namespaceSnapshotVars)
def script_review_copy(self, gesture): if not getattr(self, "_copyStartMarker", None): ui.message(_("No start marker set")) return pos = api.getReviewPosition().copy() if self._copyStartMarker.obj != pos.obj: ui.message(_("The start marker must reside within the same object")) return pos.move(textInfos.UNIT_CHARACTER, 1, endPoint="end") pos.setEndPoint(self._copyStartMarker, "startToStart") if pos.compareEndPoints(pos, "startToEnd") < 0 and pos.copyToClipboard(): ui.message(_("Review selection copied to clipboard")) else: ui.message(_("No text to copy")) return self._copyStartMarker = None
def script_forward_review_currentCharacter(self, gesture): #When speech review mode is enabled, the first character description is spoken on first script call. #When Braille review mode is set to "On" or "Auto", character descriptions are displayed on the first script call. CJK["direction"] = 1 info = api.getReviewPosition().copy() info.expand(textInfos.UNIT_CHARACTER) count = getLastScriptRepeatCount() try: c = ord(info.text) except: c = 0 if count == 1 or (CJK["speechReview"] == "On" or CJK["brailleReview"] != "Off"): CJK["isReviewCharacter"] = True if count == 1 or CJK["speechReview"] == "On": speech.speakSpelling(info.text, useCharacterDescriptions=True) else: speech.speakTextInfo(info, unit=textInfos.UNIT_CHARACTER, reason=controlTypes.OutputReason.CARET) if CJK["brailleReview"] == "On" or CJK["brailleReview"] == "Auto": try: char = info.text.lower() charDesc = characterProcessing.getCharacterDescription( CJK["locale"], char) BrailleHandler.message(handler, char + " " + " ".join(charDesc)) except TypeError: pass elif count == 0: speech.speakTextInfo(info, unit=textInfos.UNIT_CHARACTER, reason=controlTypes.OutputReason.CARET) else: try: speech.speakMessage("%d," % c) speech.speakSpelling(hex(c)) except: speech.speakTextInfo(info, unit=textInfos.UNIT_CHARACTER, reason=controlTypes.OutputReason.CARET) #Reset parameters to prepare for the next call. CJK["direction"] = 0 CJK["isReviewCharacter"] = False
def __init__(self, cursor): self.cursor = cursor self.trigger = SayAllProfileTrigger() self.reader = None # Start at the cursor. if cursor == CURSOR_CARET: try: self.reader = api.getCaretObject().makeTextInfo( textInfos.POSITION_CARET) except (NotImplementedError, RuntimeError) as e: raise NotImplementedError("Unable to make TextInfo: " + str(e)) else: self.reader = api.getReviewPosition() # #10899: SayAll profile can't be activated earlier because they may not be anything to read self.trigger.enter() self.speakTextInfoState = speech.SpeakTextInfoState(self.reader.obj) self.numBufferedLines = 0
def script_navigatorObject_moveFocus(self,gesture): obj=api.getNavigatorObject() if not isinstance(obj,NVDAObject): speech.speakMessage(_("no focus")) if scriptHandler.getLastScriptRepeatCount()==0: ui.message(_("move focus")) obj.setFocus() else: review=api.getReviewPosition() try: review.updateCaret() except NotImplementedError: ui.message(_("no caret")) return info=review.copy() info.expand(textInfos.UNIT_LINE) speech.speakTextInfo(info,reason=speech.REASON_CARET)
def _quickNavScript(self, gesture, itemType, direction, errorMessage, readUnit): if itemType == "notLinkBlock": iterFactory = self._iterNotLinkBlock else: iterFactory = lambda direction, info: self._iterNodesByType( itemType, direction, info) info = self.selection try: item = next(iterFactory(direction, info)) except NotImplementedError: # Translators: a message when a particular quick nav command # is not supported in the current document. ui.message(NVDAString("Not supported in this document")) return except StopIteration: if not toggleLoopInNavigationModeOption(False): ui.message(errorMessage) return # return to the top or bottom of page and continue search if direction == "previous": info = api.getReviewPosition().obj.makeTextInfo( textInfos.POSITION_LAST) self._set_selection(info, reason="quickNav") # Translators: message to the user which indicates the return # to the bottom of the page. msg = _("Return to bottom of page") else: info = None # Translators: message to user which indicates the return # to the top of the page. msg = _("Return to top of page") try: item = next(iterFactory(direction, info)) except Exception: ui.message(errorMessage) return ui.message(msg) winsound.PlaySound("default", 1) # #8831: Report before moving because moving might change the focus, which # might mutate the document, potentially invalidating info if it is # offset-based. if not gesture or not willSayAllResume(gesture): item.report(readUnit=readUnit) item.moveTo()
def _get_flatReviewPosition(self): """Locates a TextInfo positioned at this object, in the closest flat review.""" parent=self.simpleParent while parent: ti=parent.treeInterceptor if ti and self in ti and ti.rootNVDAObject==parent: return ti.makeTextInfo(self) if issubclass(parent.TextInfo,DisplayModelTextInfo): try: return parent.makeTextInfo(api.getReviewPosition().pointAtStart) except (NotImplementedError,LookupError): pass try: return parent.makeTextInfo(self) except (NotImplementedError,RuntimeError): pass return parent.makeTextInfo(textInfos.POSITION_FIRST) parent=parent.simpleParent
def script_moveMouseToNavigatorObject(self,gesture): obj=api.getNavigatorObject() try: p=api.getReviewPosition().pointAtStart except (NotImplementedError, LookupError): p=None if p: x=p.x y=p.y else: try: (left,top,width,height)=obj.location except: ui.message(_("object has no location")) return x=left+(width/2) y=top+(height/2) winUser.setCursorPos(x,y) mouseHandler.executeMouseMoveEvent(x,y)
def script_downArrow(self, gesture): if self.objArrowMode == MODE_OBJNAV: commands.script_navigatorObject_firstChild(gesture) elif self.objArrowMode == MODE_WEB: self.webBrowseMode = (self.webBrowseMode + 1) % len( self.webBrowseElements) ui.message(self.webBrowseElements[self.webBrowseMode]) elif self.objArrowMode == MODE_SCANMODE: # Navigate to next line if possible. info = api.getReviewPosition().copy() info.expand(textInfos.UNIT_LINE) info.collapse() res = info.move(textInfos.UNIT_LINE, 1) if res != 0: api.setReviewPosition(info) info.expand(textInfos.UNIT_LINE) speech.speakTextInfo(info, unit=textInfos.UNIT_LINE, reason=controlTypes.REASON_CARET) else: curObject = api.getNavigatorObject() newObject = None if curObject.simpleFirstChild: newObject = curObject.simpleFirstChild elif curObject.simpleNext: newObject = curObject.simpleNext elif curObject.simpleParent: parent = curObject.simpleParent while parent and not parent.simpleNext: parent = parent.simpleParent # As long as one is on current foreground object... #Stay within the current top-level window. if parent and parent.simpleParent != api.getDesktopObject( ): newObject = parent.simpleNext if newObject: api.setNavigatorObject(newObject) speech.speakObject(newObject, reason=controlTypes.REASON_FOCUS) else: # Translators: a message when there is no next object when navigating ui.reviewMessage(_("No next"))
def script_showReviewCursorSymbol(self, gesture): info = api.getReviewPosition().copy() info.expand(textInfos.UNIT_CHARACTER) curLanguage = self._getCurrentLanguageForTextInfo(info) text = info.text expandedSymbol = characterProcessing.processSpeechSymbol( curLanguage, text) if expandedSymbol == text: # Translators: Reported when there is no replacement for the symbol at the position of the review cursor. ui.message(_("No symbol replacement")) return # Translators: Character and its replacement used from the "Review current Symbol" command. Example: "Character: ? Replacement: question" message = _("Character: {}\nReplacement: {}").format( text, expandedSymbol) languageDescription = languageHandler.getLanguageDescription( curLanguage) # Translators: title for expanded symbol dialog. Example: "Expanded symbol (English)" title = _("Symbol at the review cursor position ({})").format( languageDescription) ui.browseableMessage(message, title)
def script_announce_scope(self, gesture): info = api.getReviewPosition().copy() info.expand(textInfos.UNIT_LINE) line_text = info.text if not line_text: ui.message(_("No text found")) return char, position = find_indent(line_text) if position == 0: ui.message(_("Not indented")) return for line in previous_lines(info): prev_line_text = line.text if not prev_line_text.strip(): continue new_char, new_position = find_indent(prev_line_text) if new_position < position: if new_position == 0 or new_char == char: ui.message(prev_line_text) return
def script_getInfo(self, gesture): text = "" obj = api.getFocusObject() treeInterceptor = obj.treeInterceptor if isinstance(treeInterceptor, treeInterceptorHandler.DocumentTreeInterceptor): obj = treeInterceptor try: info = obj.makeTextInfo(textInfos.POSITION_SELECTION) except (RuntimeError, NotImplementedError): info = None if not info or info.isCollapsed: #No text selected, try grabbing word under review cursor info = api.getReviewPosition().copy() try: info.expand(textInfos.UNIT_WORD) except AttributeError: #Nothing more we can do #translators: message spoken when no text is selected or focused ui.message(_("select or focus something first")) return self.get_info(info.text.strip())
def script_review_copy(self, gesture): if not getattr(self, "_copyStartMarker", None): # Translators: Presented when attempting to copy some review cursor text but there is no start marker. ui.message(_("No start marker set")) return pos = api.getReviewPosition().copy() if self._copyStartMarker.obj != pos.obj: # Translators: Presented when trying to copy text residing on a different object (that is, start marker is in object 1 but trying to copy text from object 2). ui.message( _("The start marker must reside within the same object")) return pos.move(textInfos.UNIT_CHARACTER, 1, endPoint="end") pos.setEndPoint(self._copyStartMarker, "startToStart") if pos.compareEndPoints(pos, "startToEnd") < 0 and pos.copyToClipboard(): # Translators: Presented when some review text has been copied to clipboard. ui.message(_("Review selection copied to clipboard")) else: # Translators: Presented when there is no text selection to copy from review cursor. ui.message(_("No text to copy")) return self._copyStartMarker = None
def script_touch_rightClick(self, gesture): self.etsDebugOutput("etouch: attempting to perform right-click") obj=api.getNavigatorObject() try: p=api.getReviewPosition().pointAtStart except (NotImplementedError, LookupError): p=None if p: x=p.x y=p.y else: try: (left,top,width,height)=obj.location except: # Translators: Reported when the object has no location for the mouse to move to it. ui.message(_("object has no location")) return x=left+(width/2) y=top+(height/2) self.etsDebugOutput("etouch: mouse point found at %s, %s"%(x, y)) winUser.setCursorPos(x,y) winUser.mouse_event(winUser.MOUSEEVENTF_RIGHTDOWN,0,0,None,None) winUser.mouse_event(winUser.MOUSEEVENTF_RIGHTUP,0,0,None,None)
def script_upArrow(self, gesture): if self.objArrowMode == MODE_OBJNAV: commands.script_navigatorObject_parent(gesture) elif self.objArrowMode == MODE_WEB: self.webBrowseMode = (self.webBrowseMode - 1) % len( self.webBrowseElements) ui.message(self.webBrowseElements[self.webBrowseMode]) elif self.objArrowMode == MODE_SCANMODE: # Move to previous line first so text can be reviewed before resorting to a new object. info = api.getReviewPosition().copy() info.expand(textInfos.UNIT_LINE) info.collapse() res = info.move(textInfos.UNIT_LINE, -1) if res != 0: api.setReviewPosition(info) info.expand(textInfos.UNIT_LINE) speech.speakTextInfo(info, unit=textInfos.UNIT_LINE, reason=controlTypes.REASON_CARET) else: # Do not move outside of the current window. curObject = api.getNavigatorObject() newObject = None if curObject.parent != api.getDesktopObject(): newObject = curObject.simplePrevious if newObject: while newObject.simpleLastChild: newObject = newObject.simpleLastChild else: newObject = curObject.simpleParent if newObject: api.setNavigatorObject(newObject) speech.speakObject(newObject, reason=controlTypes.REASON_FOCUS) else: # Translators: a message when there is no previous object when navigating ui.reviewMessage(_("No previous"))
def callback(column): speech.cancelSpeech() comboBox = self._getSearchEditComboBoxObject() api.setNavigatorObject(comboBox) review.setCurrentMode("screen", updateReviewPosition=True) info = api.getReviewPosition().copy() info.collapse() info.expand(textInfos.UNIT_LINE) baseInfo = info.copy() info.collapse(True) api.setReviewPosition(info) curObject = api.getNavigatorObject() if curObject.role == ROLE_LISTITEM: info = baseInfo.copy() info.collapse() api.setReviewPosition(info) curObject = api.getNavigatorObject() columnHeaders = curObject.parent.children columnObj = columnHeaders[column - 1] if columnObj is None: log.error("Cannot found stations list column object:%s" % column) return name = columnObj.name[1:] if columnObj.name[ 0] == "*" else columnObj.name ui.message(name) time.sleep(0.5) location = columnObj.location (l, t, w, h) = location i = int(l + w - 10) j = int(t + h / 2) import winUser winUser.setCursorPos(i, j) winUser.mouse_event(winUser.MOUSEEVENTF_RIGHTDOWN, 0, 0, None, None) winUser.mouse_event(winUser.MOUSEEVENTF_RIGHTUP, 0, 0, None, None)
def getLine(): info = api.getReviewPosition().copy() info.expand(textInfos.UNIT_LINE) return info.text
def script_review_markStartForCopy(self, gesture): self._copyStartMarker = api.getReviewPosition().copy() ui.message(_("Start marked"))
def readTextHelper_generator(cursor): if cursor==CURSOR_CARET: try: reader=api.getCaretObject().makeTextInfo(textInfos.POSITION_CARET) except (NotImplementedError, RuntimeError): return else: reader=api.getReviewPosition() lastSentIndex=0 lastReceivedIndex=0 cursorIndexMap={} keepReading=True while True: if not reader.obj: # The object died, so we should too. return # lastReceivedIndex might be None if other speech was interspersed with this say all. # In this case, we want to send more text in case this was the last chunk spoken. if lastReceivedIndex is None or (lastSentIndex-lastReceivedIndex)<=10: if keepReading: bookmark=reader.bookmark index=lastSentIndex+1 delta=reader.move(textInfos.UNIT_READINGCHUNK,1,endPoint="end") if delta<=0: speech.speakWithoutPauses(None) keepReading=False continue speech.speakTextInfo(reader,unit=textInfos.UNIT_READINGCHUNK,reason=controlTypes.REASON_SAYALL,index=index) lastSentIndex=index cursorIndexMap[index]=bookmark try: reader.collapse(end=True) except RuntimeError: #MS Word when range covers end of document speech.speakWithoutPauses(None) keepReading=False else: # We'll wait for speech to catch up a bit before sending more text. if speech.speakWithoutPauses.lastSentIndex is None or (lastSentIndex-speech.speakWithoutPauses.lastSentIndex)>=10: # There is a large chunk of pending speech # Force speakWithoutPauses to send text to the synth so we can move on. speech.speakWithoutPauses(None) receivedIndex=speech.getLastSpeechIndex() if receivedIndex!=lastReceivedIndex and (lastReceivedIndex!=0 or receivedIndex!=None): lastReceivedIndex=receivedIndex bookmark=cursorIndexMap.get(receivedIndex,None) if bookmark is not None: updater=reader.obj.makeTextInfo(bookmark) if cursor==CURSOR_CARET: updater.updateCaret() if cursor!=CURSOR_CARET or config.conf["reviewCursor"]["followCaret"]: api.setReviewPosition(updater) elif not keepReading and lastReceivedIndex==lastSentIndex: # All text has been spoken. # Turn the page and start again if the object supports it. if isinstance(reader.obj,textInfos.DocumentWithPageTurns): try: reader.obj.turnPage() except RuntimeError: break else: reader=reader.obj.makeTextInfo(textInfos.POSITION_FIRST) keepReading=True else: break while speech.isPaused: yield yield
def getCurrentChar(): info = api.getReviewPosition().copy() info.expand(textInfos.UNIT_CHARACTER) return info.text
def _getSelection(self): return api.getReviewPosition().copy()
def script_review_bottom(self,gesture): info=api.getReviewPosition().obj.makeTextInfo(textInfos.POSITION_LAST) api.setReviewPosition(info.copy()) info.expand(textInfos.UNIT_LINE) speech.speakMessage(_("bottom")) speech.speakTextInfo(info,unit=textInfos.UNIT_LINE,reason=speech.REASON_CARET)
def get_navigator_line(self): info = api.getReviewPosition().copy() info.expand(textInfos.UNIT_LINE) return info.clipboardText
def getReviewRect() -> locationHelper.RectLTRB: return getRectFromTextInfo(api.getReviewPosition())
def getAllHTML(): if not isVirtualDocument(): return _("Invalid document"), True obj = api.getReviewPosition().obj return ''.join(getHTML(obj.rootNVDAObject)), False
def readTextHelper_generator(cursor): if cursor==CURSOR_CARET: try: reader=api.getCaretObject().makeTextInfo(textInfos.POSITION_CARET) except (NotImplementedError, RuntimeError): return else: reader=api.getReviewPosition() lastSentIndex=0 lastReceivedIndex=0 cursorIndexMap={} keepReading=True speakTextInfoState=speech.SpeakTextInfoState(reader.obj) with SayAllProfileTrigger(): while True: if not reader.obj: # The object died, so we should too. return # lastReceivedIndex might be None if other speech was interspersed with this say all. # In this case, we want to send more text in case this was the last chunk spoken. if lastReceivedIndex is None or (lastSentIndex-lastReceivedIndex)<=10: if keepReading: bookmark=reader.bookmark index=lastSentIndex+1 delta=reader.move(textInfos.UNIT_READINGCHUNK,1,endPoint="end") if delta<=0: speech.speakWithoutPauses(None) keepReading=False continue speech.speakTextInfo(reader,unit=textInfos.UNIT_READINGCHUNK,reason=controlTypes.REASON_SAYALL,index=index,useCache=speakTextInfoState) lastSentIndex=index cursorIndexMap[index]=(bookmark,speakTextInfoState.copy()) try: reader.collapse(end=True) except RuntimeError: #MS Word when range covers end of document # Word specific: without this exception to indicate that further collapsing is not posible, say-all could enter an infinite loop. speech.speakWithoutPauses(None) keepReading=False else: # We'll wait for speech to catch up a bit before sending more text. if speech.speakWithoutPauses.lastSentIndex is None or (lastSentIndex-speech.speakWithoutPauses.lastSentIndex)>=10: # There is a large chunk of pending speech # Force speakWithoutPauses to send text to the synth so we can move on. speech.speakWithoutPauses(None) receivedIndex=speech.getLastSpeechIndex() if receivedIndex!=lastReceivedIndex and (lastReceivedIndex!=0 or receivedIndex!=None): lastReceivedIndex=receivedIndex bookmark,state=cursorIndexMap.get(receivedIndex,(None,None)) if state: state.updateObj() if bookmark is not None: updater=reader.obj.makeTextInfo(bookmark) if cursor==CURSOR_CARET: updater.updateCaret() if cursor!=CURSOR_CARET or config.conf["reviewCursor"]["followCaret"]: api.setReviewPosition(updater) elif not keepReading and lastReceivedIndex==lastSentIndex: # All text has been sent to the synth. # Turn the page and start again if the object supports it. if isinstance(reader.obj,textInfos.DocumentWithPageTurns): try: reader.obj.turnPage() except RuntimeError: break else: reader=reader.obj.makeTextInfo(textInfos.POSITION_FIRST) keepReading=True else: break while speech.isPaused: yield yield # Wait until the synth has actually finished speaking. # Otherwise, if there is a triggered profile with a different synth, # we will switch too early and truncate speech (even up to several lines). # Send another index and wait for it. index=lastSentIndex+1 speech.speak([speech.IndexCommand(index)]) while speech.getLastSpeechIndex()<index: yield yield # Some synths say they've handled the index slightly sooner than they actually have, # so wait a bit longer. for i in xrange(30): yield
def script_review_sayAll(self,gesture): info=api.getReviewPosition().copy() sayAllHandler.readText(info,sayAllHandler.CURSOR_REVIEW)