Example #1
0
	def _reportErrorInPreviousWord(self):
		try:
			# self might be a descendant of the text control; e.g. Symphony.
			# We want to deal with the entire text, so use the caret object.
			info = api.getCaretObject().makeTextInfo(textInfos.POSITION_CARET)
			# This gets called for characters which might end a word; e.g. space.
			# The character before the caret is the word end.
			# The one before that is the last of the word, which is what we want.
			info.move(textInfos.UNIT_CHARACTER, -2)
			info.expand(textInfos.UNIT_CHARACTER)
			fields = info.getTextWithFields()
		except RuntimeError:
			return
		except:
			# Focus probably moved.
			log.debugWarning("Error fetching last character of previous word", exc_info=True)
			return
		for command in fields:
			if isinstance(command, textInfos.FieldCommand) and command.command == "formatChange" and command.field.get("invalid-spelling"):
				break
		else:
			# No error.
			return
		import nvwave
		nvwave.playWaveFile(r"waves\textError.wav")
Example #2
0
def getCaretRect(obj: Optional[TextContainerObject] = None) -> locationHelper.RectLTRB:
	if obj is None:
		obj = api.getCaretObject()
	if api.isObjectInActiveTreeInterceptor(obj):
		obj = obj.treeInterceptor
	if api.isNVDAObject(obj):
		# Import late to avoid circular import
		from displayModel import getCaretRect
		# Check whether there is a caret in the window.
		# Note that, even windows that don't have navigable text could have a caret, such as in Excel.
		try:
			return locationHelper.RectLTRB.fromCompatibleType(getCaretRect(obj))
		except RuntimeError:
			if not obj._hasNavigableText:
				raise LookupError
	try:
		caretInfo = obj.makeTextInfo(textInfos.POSITION_CARET)
	except (NotImplementedError, RuntimeError):
		# Try a selection
		try:
			caretInfo = obj.makeTextInfo(textInfos.POSITION_SELECTION)
		except (NotImplementedError, RuntimeError):
			# There is nothing to do here
			raise LookupError
	return getRectFromTextInfo(caretInfo)
Example #3
0
    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)
Example #4
0
	def _reportErrorInPreviousWord(self):
		try:
			# self might be a descendant of the text control; e.g. Symphony.
			# We want to deal with the entire text, so use the caret object.
			info = api.getCaretObject().makeTextInfo(textInfos.POSITION_CARET)
			# This gets called for characters which might end a word; e.g. space.
			# The character before the caret is the word end.
			# The one before that is the last of the word, which is what we want.
			info.move(textInfos.UNIT_CHARACTER, -2)
			info.expand(textInfos.UNIT_CHARACTER)
			fields = info.getTextWithFields()
		except RuntimeError:
			return
		except:
			# Focus probably moved.
			log.debugWarning("Error fetching last character of previous word", exc_info=True)
			return
		for command in fields:
			if isinstance(command, textInfos.FieldCommand) and command.command == "formatChange" and command.field.get("invalid-spelling"):
				break
		else:
			# No error.
			return
		import nvwave
		nvwave.playWaveFile(r"waves\textError.wav")
Example #5
0
	def getSelectedText(self):
		obj = api.getCaretObject()
		try:
			info = obj.makeTextInfo(textInfos.POSITION_SELECTION)
			if info or not info.isCollapsed:
				return info.text
		except (RuntimeError, NotImplementedError):
			return None
Example #6
0
 def script_info(self, gesture):
     #ui.message(str(getPipeFile()['Channels']))
     out = ''
     for x in menuFull:
         if x.role == 11 and not controlTypes.STATE_HASPOPUP in x.states:
             out += repr(x.name.partition('\x09')[0]) + ',\n'
     # ui.browseableMessage(out)
     ui.browseableMessage('\n'.join(
         (api.getCaretObject().name, api.getFocusObject().name,
          str(api.getForegroundObject().windowHandle),
          str(api.winUser.getForegroundWindow()))))
Example #7
0
def getContextRect(
		context: Context,
		obj: Optional[TextContainerObject] = None
) -> Optional[locationHelper.RectLTRB]:
	"""Gets a rectangle for the specified context."""
	if context == Context.FOCUS:
		return getObjectRect(obj or api.getFocusObject())
	elif context == Context.NAVIGATOR:
		return getObjectRect(obj or api.getNavigatorObject())
	elif context == Context.REVIEW:
		return getReviewRect()
	elif context == Context.BROWSEMODE:
		caret = obj or api.getCaretObject()
		if api.isCursorManager(caret):
			return getCaretRect(obj=caret)
		return None
	elif context == Context.CARET:
		caret = obj or api.getCaretObject()
		if not api.isCursorManager(caret):
			return getCaretRect(obj=caret)
		return None
	elif context == Context.MOUSE:
		return getMouseRect()
Example #8
0
	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
Example #9
0
 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
Example #10
0
    def script_linkTitle(self, gesture):
        link = self.getFocusedLink()
        self.vlcProc.terminate() if self.vlcProc is not None else None
        if link is None or link.startswith("http") == False:
            selection = api.getCaretObject().makeTextInfo(
                textInfos.POSITION_SELECTION).text
            if selection.startswith("http"):
                link = selection

            else:
                ui.message("Not a link.")

                return
        if (re.match(".*.(aac|mp4).*", link)):
            self.vlcProc = subprocess.Popen(
                ["c:/program files/VideoLAN/vlc/vlc.exe", "-Idummy", link])

        else:
            title = self.getTitle(link)
            ui.message(title)
Example #11
0
    def _reportErrorInPreviousWord(self):
        try:
            # self might be a descendant of the text control; e.g. Symphony.
            # We want to deal with the entire text, so use the caret object.
            info = api.getCaretObject().makeTextInfo(textInfos.POSITION_CARET)
            # This gets called for characters which might end a word; e.g. space.
            # The character before the caret is the word end.
            # The one before that is the last of the word, which is what we want.
            info.move(textInfos.UNIT_CHARACTER, -2)
            info.expand(textInfos.UNIT_CHARACTER)
        except Exception:
            # Focus probably moved.
            log.debugWarning("Error fetching last character of previous word",
                             exc_info=True)
            return

        # Fetch the formatting for the last word to see if it is marked as a spelling error,
        # However perform the fetch and check in a future core cycle
        # To give the content control more time to detect and mark the error itself.
        # #12161: MS Word's UIA implementation certainly requires this delay.
        def _delayedDetection():
            try:
                fields = info.getTextWithFields()
            except Exception:
                log.debugWarning(
                    "Error fetching formatting for last character of previous word",
                    exc_info=True)
                return
            for command in fields:
                if (isinstance(command, textInfos.FieldCommand)
                        and command.command == "formatChange"
                        and command.field.get("invalid-spelling")):
                    break
            else:
                # No error.
                return
            nvwave.playWaveFile(
                os.path.join(globalVars.appDir, "waves", "textError.wav"))

        core.callLater(50, _delayedDetection)
Example #12
0
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
Example #13
0
	def getInitialTextInfo(self) -> textInfos.TextInfo:
		try:
			return api.getCaretObject().makeTextInfo(textInfos.POSITION_CARET)
		except (NotImplementedError, RuntimeError) as e:
			raise NotImplementedError("Unable to make TextInfo: ", e)
Example #14
0
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)

    start = time.time()

    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,
                                              isCaret=cursor == CURSOR_CARET)
            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

            now = time.time()

            if (now - start) > int(min) * 60 + int(sec):
                speech.cancelSpeech()
                break

        # 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
Example #15
0
	def __init__(self):
		self.object = api.getCaretObject()
		self.textInfo = self.object.makeTextInfo(textInfos.POSITION_CARET)
		self.textInfo.expand(textInfos.UNIT_WORD)
Example #16
0
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