Example #1
0
def initialize():
	global _remoteLib, _remoteLoader64, localLib, winEventHookID,generateBeep,VBuf_getTextInRange
	localLib=cdll.LoadLibrary('lib/nvdaHelperLocal.dll')
	for name,func in [
		("nvdaController_speakText",nvdaController_speakText),
		("nvdaController_cancelSpeech",nvdaController_cancelSpeech),
		("nvdaController_brailleMessage",nvdaController_brailleMessage),
		("nvdaControllerInternal_inputLangChangeNotify",nvdaControllerInternal_inputLangChangeNotify),
		("nvdaControllerInternal_displayModelTextChangeNotify",nvdaControllerInternal_displayModelTextChangeNotify),
		("nvdaControllerInternal_logMessage",nvdaControllerInternal_logMessage),
	]:
		try:
			_setDllFuncPointer(localLib,"_%s"%name,func)
		except AttributeError:
			log.error("nvdaHelperLocal function pointer for %s could not be found, possibly old nvdaHelperLocal dll"%name)
	localLib.startServer()
	generateBeep=localLib.generateBeep
	generateBeep.argtypes=[c_char_p,c_float,c_uint,c_ubyte,c_ubyte]
	generateBeep.restype=c_uint
	# Handle VBuf_getTextInRange's BSTR out parameter so that the BSTR will be freed automatically.
	VBuf_getTextInRange = CFUNCTYPE(c_int, c_int, c_int, c_int, POINTER(BSTR), c_int)(
		("VBuf_getTextInRange", localLib),
		((1,), (1,), (1,), (2,), (1,)))
	#Load nvdaHelperRemote.dll but with an altered search path so it can pick up other dlls in lib
	h=windll.kernel32.LoadLibraryExW(os.path.abspath(ur"lib\nvdaHelperRemote.dll"),0,0x8)
	if not h:
		log.critical("Error loading nvdaHelperRemote.dll: %s" % WinError())
		return
	_remoteLib=CDLL("nvdaHelperRemote",handle=h)
	if _remoteLib.injection_initialize(globalVars.appArgs.secure) == 0:
		raise RuntimeError("Error initializing NVDAHelperRemote")
	if os.environ.get('PROCESSOR_ARCHITEW6432')=='AMD64':
		_remoteLoader64=RemoteLoader64()
	winEventHookID=winUser.setWinEventHook(EVENT_TYPEDCHARACTER,EVENT_TYPEDCHARACTER,0,winEventCallback,0,0,0)
Example #2
0
	def onRunCOMRegistrationFixesCommand(self, evt):
		if isInMessageBox:
			return
		if gui.messageBox(
			# Translators: A message to warn the user when starting the COM Registration Fixing tool 
			_("You are about to run the COM Registration Fixing tool. This tool will try to fix common system problems that stop NVDA from being able to access content in many programs including Firefox and Internet Explorer. This tool must make changes to the System registry and therefore requires administrative access. Are you sure you wish to proceed?"),
			# Translators: The title of the warning dialog displayed when launching the COM Registration Fixing tool 
			_("Warning"),wx.YES|wx.NO|wx.ICON_WARNING,self
		)==wx.NO:
			return
		progressDialog = IndeterminateProgressDialog(mainFrame,
			# Translators: The title of the dialog presented while NVDA is running the COM Registration fixing tool 
			_("COM Registration Fixing Tool"),
			# Translators: The message displayed while NVDA is running the COM Registration fixing tool 
			_("Please wait while NVDA tries to fix your system's COM registrations.")
		)
		try:
			config.execElevated(config.SLAVE_FILENAME,["fixCOMRegistrations"])
		except:
			log.error("Could not execute fixCOMRegistrations command",exc_info=True) 
		progressDialog.done()
		del progressDialog
		# Translators: The message displayed when the COM Registration Fixing tool completes.
		gui.messageBox(_("COM Registration Fixing tool complete"),
			# Translators: The title of a dialog presented when the COM Registration Fixing tool is complete. 
			_("COM Registration Fixing Tool"),
			wx.OK)
def internal_keyUpEvent(vkCode,scanCode,extended,injected):
	"""Event called by winInputHook when it receives a keyUp.
	"""
	try:
		global lastNVDAModifier, lastNVDAModifierReleaseTime, bypassNVDAModifier, passKeyThroughCount, lastPassThroughKeyDown, currentModifiers
		if injected:
			return True

		keyCode = (vkCode, extended)

		if passKeyThroughCount >= 1:
			if lastPassThroughKeyDown == keyCode:
				# This key has been released.
				lastPassThroughKeyDown = None
			passKeyThroughCount -= 1
			if passKeyThroughCount == 0:
				passKeyThroughCount = -1
			return True

		if lastNVDAModifier and keyCode == lastNVDAModifier:
			# The last pressed NVDA modifier key is being released and there were no key presses in between.
			# The user may want to press it again quickly to pass it through.
			lastNVDAModifierReleaseTime = time.time()
		# If we were bypassing the NVDA modifier, stop doing so now, as there will be no more repeats.
		bypassNVDAModifier = False

		currentModifiers.discard(keyCode)

		if keyCode in trappedKeys:
			trappedKeys.remove(keyCode)
			return False
	except:
		log.error("", exc_info=True)
	return True
Example #4
0
def winEventCallback(handle,eventID,window,objectID,childID,threadID,timestamp):
	global lastKeyboardLayoutChangeEventTime
	try:
		if eventID==EVENT_TYPEDCHARACTER:
			handleTypedCharacter(window,objectID,childID)
	except:
		log.error("helper.winEventCallback", exc_info=True)
Example #5
0
	def completeRemove(self,runUninstallTask=True):
		if runUninstallTask:
			try:
				# #2715: The add-on must be added to _availableAddons here so that
				# translations can be used in installTasks module.
				_availableAddons[self.path] = self
				self.runInstallTask("onUninstall")
			except:
				log.error("task 'onUninstall' on addon '%s' failed"%self.name,exc_info=True)
			finally:
				del _availableAddons[self.path]
		tempPath=tempfile.mktemp(suffix=DELETEDIR_SUFFIX,dir=os.path.dirname(self.path))
		try:
			os.rename(self.path,tempPath)
		except (WindowsError,IOError):
			raise RuntimeError("Cannot rename add-on path for deletion")
		shutil.rmtree(tempPath,ignore_errors=True)
		if os.path.exists(tempPath):
			log.error("Error removing addon directory %s, deferring until next NVDA restart"%self.path)
		# clean up the addons state. If an addon with the same name is installed, it should not be automatically
		# disabled / blocked.
		log.debug("removing addon {} from _disabledAddons/_blockedAddons".format(self.name))
		_disabledAddons.discard(self.name)
		_blockedAddons.discard(self.name)
		saveState()
Example #6
0
def _getAvailableAddonsFromPath(path):
	""" Gets available add-ons from path.
	An addon is only considered available if the manifest file is loaded with no errors.
	@param path: path from where to find addon directories.
	@type path: string
	@rtype generator of Addon instances
	"""
	log.debug("Listing add-ons from %s", path)
	for p in os.listdir(path):
		if p.endswith(DELETEDIR_SUFFIX): continue
		addon_path = os.path.join(path, p)
		if os.path.isdir(addon_path) and addon_path not in ('.', '..'):
			log.debug("Loading add-on from %s", addon_path)
			try:
				a = Addon(addon_path)
				name = a.manifest['name']
				log.debug(
					"Found add-on {name} - {a.version}."
					" Requires API: {a.minimumNVDAVersion}."
					" Last-tested API: {a.lastTestedNVDAVersion}".format(
						name=name,
						a=a
					))
				if a.isDisabled:
					log.debug("Disabling add-on %s", name)
				if not isAddonCompatible(a):
					log.debugWarning("Add-on %s is considered incompatible", name)
					_blockedAddons.add(a.name)
				yield a
			except:
				log.error("Error loading Addon from path: %s", addon_path, exc_info=True)
Example #7
0
def fetchAppModule(processID,appName):
	"""Returns an appModule found in the appModules directory, for the given application name.
	@param processID: process ID for it to be associated with
	@type processID: integer
	@param appName: the application name for which an appModule should be found.
	@type appName: unicode or str
	@returns: the appModule, or None if not found
	@rtype: AppModule
	"""  
	# First, check whether the module exists.
	# We need to do this separately because even though an ImportError is raised when a module can't be found, it might also be raised for other reasons.
	# Python 2.x can't properly handle unicode module names, so convert them.
	modName = appName.encode("mbcs")

	if doesAppModuleExist(modName):
		try:
			return __import__("appModules.%s" % modName, globals(), locals(), ("appModules",)).AppModule(processID, appName)
		except:
			log.error("error in appModule %r"%modName, exc_info=True)
			# We can't present a message which isn't unicode, so use appName, not modName.
			# Translators: This is presented when errors are found in an appModule (example output: error in appModule explorer).
			ui.message(_("Error in appModule %s")%appName)

	# Use the base AppModule.
	return AppModule(processID, appName)
Example #8
0
	def __call__(self,sample_rate,user_data):
		try:
			self.__player.set_sample_rate(sample_rate)
			return 1
		except:
			log.error("RHVoice sample rate callback",exc_info=True)
			return 0
Example #9
0
def getSynthList():
	synthList=[]
	# The synth that should be placed at the end of the list.
	lastSynth = None
	for loader, name, isPkg in pkgutil.iter_modules(synthDrivers.__path__):
		if name.startswith('_'):
			continue
		try:
			synth=_getSynthDriver(name)
		except:
			log.error("Error while importing SynthDriver %s"%name,exc_info=True)
			continue
		try:
			if synth.check():
				if synth.name == "silence":
					lastSynth = (synth.name,synth.description)
				else:
					synthList.append((synth.name,synth.description))
			else:
				log.debugWarning("Synthesizer '%s' doesn't pass the check, excluding from list"%name)
		except:
			log.error("",exc_info=True)
	synthList.sort(key=lambda s : s[1].lower())
	if lastSynth:
		synthList.append(lastSynth)
	return synthList
	def _initBaseConf(self, factoryDefaults=False):
		fn = os.path.join(globalVars.appArgs.configPath, "nvda.ini")
		if factoryDefaults:
			profile = ConfigObj(None, indent_type="\t", encoding="UTF-8")
			profile.filename = fn
		else:
			try:
				profile = ConfigObj(fn, indent_type="\t", encoding="UTF-8")
				self.baseConfigError = False
			except:
				log.error("Error loading base configuration", exc_info=True)
				self.baseConfigError = True
				return self._initBaseConf(factoryDefaults=True)
		# Python converts \r\n to \n when reading files in Windows, so ConfigObj can't determine the true line ending.
		profile.newlines = "\r\n"

		for key in self.BASE_ONLY_SECTIONS:
			# These sections are returned directly from the base config, so validate them here.
			try:
				sect = profile[key]
			except KeyError:
				profile[key] = {}
				# ConfigObj mutates this into a configobj.Section.
				sect = profile[key]
			sect.configspec = self.spec[key]
			profile.validate(self.validator, section=sect)

		self._profileCache[None] = profile
		self.profiles.append(profile)
		self._handleProfileSwitch()
Example #11
0
	def __init__(self):
		# #6140: Migrate to new table names as smoothly as possible.
		tableName = config.conf["braille"]["inputTable"]
		newTableName = brailleTables.RENAMED_TABLES.get(tableName)
		if newTableName:
			tableName = config.conf["braille"]["inputTable"] = newTableName
		try:
			self._table = brailleTables.getTable(tableName)
		except LookupError:
			log.error("Invalid table: %s" % tableName)
			self._table = brailleTables.getTable(FALLBACK_TABLE)
		#: A buffer of entered braille cells so that state set by previous cells can be maintained;
		#: e.g. capital and number signs.
		self.bufferBraille = []
		#: The text translated so far from the cells in L{bufferBraille}.
		self.bufferText = u""
		#: Indexes of cells which produced text.
		#: For example, this includes letters and numbers, but not number signs,
		#: since a number sign by itself doesn't produce text.
		#: This is used when erasing cells to determine when to backspace an actual character.
		self.cellsWithText = set()
		#: The cells in L{bufferBraille} that have not yet been translated
		#: or were translated but did not produce any text.
		#: This is used to show these cells to the user while they're entering braille.
		#: This is a string of Unicode braille.
		#: @type: unicode
		self.untranslatedBraille = ""
		#: The position in L{brailleBuffer} where untranslated braille begins.
		self.untranslatedStart = 0
		#: The user's cursor position within the untranslated braille.
		#: This enables the user to move within the untranslated braille.
		self.untranslatedCursorPos = 0
		#: The time at which uncontracted characters were sent to the system.
		self._uncontSentTime = None
		config.configProfileSwitched.register(self.handleConfigProfileSwitch)
Example #12
0
def tryRemoveFile(path,numRetries=6,retryInterval=0.5,rebootOK=False):
	dirPath=os.path.dirname(path)
	tempPath=tempfile.mktemp(dir=dirPath)
	try:
		os.rename(path,tempPath)
	except (WindowsError,IOError):
		raise RetriableFailure("Failed to rename file %s before  remove"%path)
	for count in xrange(numRetries):
		try:
			if os.path.isdir(tempPath):
				shutil.rmtree(tempPath)
			else:
				os.remove(tempPath)
			return
		except OSError:
			pass
		time.sleep(retryInterval)
	if rebootOK:
		log.debugWarning("Failed to delete file %s, marking for delete on reboot"%tempPath)
		MoveFileEx=windll.kernel32.MoveFileExW if isinstance(tempPath,unicode) else windll.kernel32.MoveFileExA
		MoveFileEx("\\\\?\\"+tempPath,None,4)
		return
	try:
		os.rename(tempPath,path)
	except:
		log.error("Unable to rename back to %s before retriable failier"%path)
	raise RetriableFailure("File %s could not be removed"%path)
Example #13
0
	def installAddon(self, addonPath, closeAfter=False):
		try:
			try:
				bundle=addonHandler.AddonBundle(addonPath)
			except:
				log.error("Error opening addon bundle from %s"%addonPath,exc_info=True)
				# Translators: The message displayed when an error occurs when opening an add-on package for adding. 
				gui.messageBox(_("Failed to open add-on package file at %s - missing file or invalid file format")%addonPath,
					# Translators: The title of a dialog presented when an error occurs.
					_("Error"),
					wx.OK | wx.ICON_ERROR)
				return
			# Translators: A message asking the user if they really wish to install an addon.
			if gui.messageBox(_("Are you sure you want to install this add-on? Only install add-ons from trusted sources.\nAddon: {summary} {version}\nAuthor: {author}").format(**bundle.manifest),
				# Translators: Title for message asking if the user really wishes to install an Addon.
				_("Add-on Installation"),
				wx.YES|wx.NO|wx.ICON_WARNING)!=wx.YES:
				return
			bundleName=bundle.manifest['name']
			prevAddon=None
			for addon in self.curAddons:
				if not addon.isPendingRemove and bundleName==addon.manifest['name']:
					prevAddon=addon
					break
			if prevAddon:
				# Translators: A message asking if the user wishes to update a previously installed add-on with this one.
				if gui.messageBox(_("A version of this add-on is already installed. Would you like to update it?"),
				# Translators: A title for the dialog  asking if the user wishes to update a previously installed add-on with this one.
				_("Add-on Installation"),
				wx.YES|wx.NO|wx.ICON_WARNING)!=wx.YES:
					return
				prevAddon.requestRemove()
			progressDialog = gui.IndeterminateProgressDialog(gui.mainFrame,
			# Translators: The title of the dialog presented while an Addon is being installed.
			_("Installing Add-on"),
			# Translators: The message displayed while an addon is being installed.
			_("Please wait while the add-on is being installed."))
			try:
				gui.ExecAndPump(addonHandler.installAddonBundle,bundle)
			except:
				log.error("Error installing  addon bundle from %s"%addonPath,exc_info=True)
				self.refreshAddonsList()
				progressDialog.done()
				del progressDialog
				# Translators: The message displayed when an error occurs when installing an add-on package.
				gui.messageBox(_("Failed to install add-on  from %s")%addonPath,
					# Translators: The title of a dialog presented when an error occurs.
					_("Error"),
					wx.OK | wx.ICON_ERROR)
				return
			else:
				self.refreshAddonsList(activeIndex=-1)
				progressDialog.done()
				del progressDialog
		finally:
			if closeAfter:
				# #4460: If we do this immediately, wx seems to drop the WM_QUIT sent if the user chooses to restart.
				# This seems to have something to do with the wx.ProgressDialog.
				# The CallLater seems to work around this.
				wx.CallLater(1, self.Close)
Example #14
0
	def _handlePacket(self, packet):
		mode=packet[1]
		if mode=="\x00": # Cursor routing
			routingIndex = ord(packet[3])
			try:
				inputCore.manager.executeGesture(RoutingInputGesture(routingIndex))
			except inputCore.NoInputGestureAction:
				pass
		elif mode=="\x01": # Braille input or function key
			if not self._model:
				return
			_keys = sum(ord(packet[4+i])<<(i*8) for i in xrange(4))
			keys = set()
			for keyHex in self._model.keys:
				if _keys & keyHex:
					# This key is pressed
					_keys -= keyHex
					keys.add(keyHex)
					if _keys == 0:
						break
			if _keys:
				log.error("Unknown key(s) 0x%x received from Hims display"%_keys)
				return
			try:
				inputCore.manager.executeGesture(KeyInputGesture(self._model, keys))
			except inputCore.NoInputGestureAction:
				pass
		elif mode=="\x02": # Cell count
			self.numCells=ord(packet[3])
def initialize():
	for eventType in winEventIDsToNVDAEventNames.keys():
		hookID=winUser.setWinEventHook(eventType,eventType,0,cWinEventCallback,0,0,0)
		if hookID:
			winEventHookIDs.append(hookID)
		else:
			log.error("initialize: could not register callback for event %s (%s)"%(eventType,winEventIDsToNVDAEventNames[eventType]))
Example #16
0
 def __call__(self,name,user_data):
     try:
         self.index=int(name)
         return 1
     except:
         log.error("RHVoice mark callback",exc_info=True)
         return 0
Example #17
0
def _setDuckingState(switch):
	global _lastDuckedTime
	with _duckingRefCountLock:
		try:
			import gui
			ATWindow=gui.mainFrame.GetHandle()
			if switch:
				oledll.oleacc.AccSetRunningUtilityState(ATWindow,ANRUS_ducking_AUDIO_ACTIVE|ANRUS_ducking_AUDIO_ACTIVE_NODUCK,ANRUS_ducking_AUDIO_ACTIVE|ANRUS_ducking_AUDIO_ACTIVE_NODUCK)
				_lastDuckedTime=time.time()
			else:
				oledll.oleacc.AccSetRunningUtilityState(ATWindow,ANRUS_ducking_AUDIO_ACTIVE|ANRUS_ducking_AUDIO_ACTIVE_NODUCK,ANRUS_ducking_AUDIO_ACTIVE_NODUCK)
		except WindowsError as e:
			# When the NVDA build is not signed, audio ducking fails with access denied.
			# A developer built launcher is unlikely to be signed. Catching this error stops developers from looking into
			# "expected" errors.
			# ERROR_ACCESS_DENIED is 0x5
			# https://docs.microsoft.com/en-us/windows/desktop/debug/system-error-codes--0-499-
			ERROR_ACCESS_DENIED = 0x80070005
			errorCode = e.winerror & 0xFFFFFFFF  # we only care about the first 8 hex values.
			if errorCode == ERROR_ACCESS_DENIED:
				log.warning("Unable to set ducking state: ERROR_ACCESS_DENIED.")
			else:
				# we want developers to hear the "error sound", and to halt, so still raise the exception.
				log.error(
					"Unknown error when setting ducking state:  Error number: {:#010X}".format(errorCode),
					exc_info=True
				)
				raise e
Example #18
0
def executeMouseMoveEvent(x,y):
	global currentMouseWindow
	desktopObject=api.getDesktopObject()
	displays = [ wx.Display(i).GetGeometry() for i in xrange(wx.Display.GetCount()) ]
	x, y = getMouseRestrictedToScreens(x, y, displays)
	screenWidth, screenHeight, minPos = getTotalWidthAndHeightAndMinimumPosition(displays)

	if config.conf["mouse"]["audioCoordinatesOnMouseMove"]:
		playAudioCoordinates(x, y, screenWidth, screenHeight, minPos,
			config.conf['mouse']['audioCoordinates_detectBrightness'],
			config.conf['mouse']['audioCoordinates_blurFactor'])

	oldMouseObject=api.getMouseObject()
	mouseObject=desktopObject.objectFromPoint(x, y)
	while mouseObject and mouseObject.beTransparentToMouse:
		mouseObject=mouseObject.parent
	if not mouseObject:
		return
	if oldMouseObject==mouseObject:
		mouseObject=oldMouseObject
	else:
		api.setMouseObject(mouseObject)
	try:
		eventHandler.executeEvent("mouseMove",mouseObject,x=x,y=y)
		oldMouseObject=mouseObject
	except:
		log.error("api.notifyMouseMoved", exc_info=True)
Example #19
0
def initialize(voice = default_jtalk_voice):
	global player, voice_args
	global speaker_attenuation
	voice_args = voice
	speaker_attenuation = voice_args['speaker_attenuation']
	if not _espeak.espeakDLL:
		_espeak.initialize()
		log.debug("jtalk using eSpeak version %s" % _espeak.info())
	_espeak.setVoiceByLanguage("en")
	_espeak.setVoiceAndVariant(variant=voice["espeak_variant"])
	if not player:
		player = nvwave.WavePlayer(channels=1, samplesPerSec=voice_args['samp_rate'], bitsPerSample=16, outputDevice=config.conf["speech"]["outputDevice"])
	if not _bgthread.bgThread:
		_bgthread.initialize()
	if not mecab:
		Mecab_initialize(log.info, jtalk_dir, dic_dir, user_dics)
	jtalkPrepare.setup()

	jt_dll = os.path.join(jtalk_dir, 'libopenjtalk.dll')
	log.debug('jt_dll %s' % jt_dll)
	libjt_initialize(jt_dll)
	log.debug(libjt_version())

	if os.path.isfile(voice_args['htsvoice']):
		libjt_load(voice_args['htsvoice'])
		log.info("loaded " + voice_args['htsvoice'])
	else:
		log.error("load error " + voice_args['htsvoice'])
	libjt_set_alpha(voice_args['alpha'])
	libjt_set_beta(voice_args['beta'])
Example #20
0
	def setDisplayByName(self, name):
		if not name:
			self.display = None
			self.displaySize = 0
			return
		try:
			newDisplay = _getDisplayDriver(name)
			if newDisplay == self.display.__class__:
				# This is the same driver as was already set, so just re-initialise it.
				self.display.terminate()
				newDisplay = self.display
				newDisplay.__init__()
			else:
				newDisplay = newDisplay()
				if self.display:
					try:
						self.display.terminate()
					except:
						log.error("Error terminating previous display driver", exc_info=True)
				self.display = newDisplay
			self.displaySize = newDisplay.numCells
			self.enabled = bool(self.displaySize)
			config.conf["braille"]["display"] = name
			log.info("Loaded braille display driver %s" % name)
			return True
		except:
			log.error("Error initializing display driver", exc_info=True)
			self.setDisplayByName("noBraille")
			return False
Example #21
0
def getWindowScalingFactor(window):
	"""Gets the logical scaling factor used for the given window handle. This is based off the Dpi reported by windows
	for the given window handle / divided by the "base" DPI level of 96. Typically this is a result of using the scaling
	percentage in the windows display settings. 100% is typically 96 DPI, 150% is typically 144 DPI.
	@param window: a native Windows window handle (hWnd)
	@returns the logical scaling factor. EG. 1.0 if the window DPI level is 96, 1.5 if the window DPI level is 144"""
	user32 = ctypes.windll.user32
	try:
		winDpi = user32.GetDpiForWindow(window)
	except:
		log.debug("GetDpiForWindow failed, using GetDeviceCaps instead")
		dc = user32.GetDC(window)
		winDpi = ctypes.windll.gdi32.GetDeviceCaps(dc, LOGPIXELSX)
		ret = user32.ReleaseDC(window, dc)
		if ret != 1:
			log.error("Unable to release the device context.")

	# For GetDpiForWindow: an invalid hwnd value will result in a return value of 0.
	# There is little information about what GetDeviceCaps does in the case of a failure for LOGPIXELSX, however,
	# a value of zero is certainly an error.
	if winDpi <= 0:
		log.debugWarning("Failed to get the DPI for the window, assuming a "
		                 "DPI of {} and using a scaling of 1.0. The hWnd value "
		                 "used was: {}".format(DEFAULT_DPI_LEVEL, window))
		return 1.0

	return winDpi / DEFAULT_DPI_LEVEL
Example #22
0
 def speak(self,speech_sequence):
     spell_mode=False
     text_list=[]
     for item in speech_sequence:
         if isinstance(item,basestring):
             s=unicode(item).translate(self.__char_mapping)
             text_list.append((u'<say-as interpret-as="characters">%s</say-as>' % s) if spell_mode else s)
         elif isinstance(item,speech.IndexCommand):
             text_list.append('<mark name="%d"/>' % item.index)
         elif isinstance(item,speech.CharacterModeCommand):
             if item.state:
                 spell_mode=True
             else:
                 spell_mode=False
         elif isinstance(item,speech.SpeechCommand):
             log.debugWarning("Unsupported speech command: %s"%item)
         else:
             log.error("Unknown speech: %s"%item)
     text=u"".join(text_list)
     fmt_str=u'<speak><voice name="%s" variant="%d"><prosody rate="%f%%" pitch="%f%%" volume="%f%%">%s</prosody></voice></speak>'
     variant=self.__lib.RHVoice_find_variant(self.__variant)
     if variant==0:
         variant=1
     rate=convert_to_native_percent(self.__rate,*self.__native_rate_range)
     pitch=convert_to_native_percent(self.__pitch,*self.__native_pitch_range)
     volume=convert_to_native_percent(self.__volume,*self.__native_volume_range)
     ssml=fmt_str % (self.__voice,variant,rate,pitch,volume,text)
     self.__tts_queue.put(ssml)
Example #23
0
	def speak(self,speechSequence):
		defaultLanguage=self._language
		textList=[]
		langChanged=False
		for item in speechSequence:
			if isinstance(item,basestring):
				s=unicode(item)
				# Replace \01, as this is used for embedded commands.
				#Also replace < and > as espeak handles xml
				s=s.translate({ord(u'\01'):None,ord(u'<'):u'&lt;',ord(u'>'):u'&gt;'})
				textList.append(s)
			elif isinstance(item,speech.IndexCommand):
				textList.append("<mark name=\"%d\" />"%item.index)
			elif isinstance(item,speech.CharacterModeCommand):
				textList.append("<say-as interpret-as=\"characters\">" if item.state else "</say-as>")
			elif isinstance(item,speech.LangChangeCommand):
				if langChanged:
					textList.append("</voice>")
				textList.append("<voice xml:lang=\"%s\">"%(item.lang if item.lang else defaultLanguage).replace('_','-'))
				langChanged=True
			elif isinstance(item,speech.SpeechCommand):
				log.debugWarning("Unsupported speech command: %s"%item)
			else:
				log.error("Unknown speech: %s"%item)
		if langChanged:
			textList.append("</voice>")
		text=u"".join(textList)
		_espeak.speak(text)
Example #24
0
def initialize():
	config.addConfigDirsToPythonPackagePath(globalPlugins)
	for plugin in listPlugins():
		try:
			runningPlugins.add(plugin())
		except:
			log.error("Error initializing global plugin %r" % plugin, exc_info=True)
Example #25
0
	def _initBaseConf(self, factoryDefaults=False):
		fn = os.path.join(globalVars.appArgs.configPath, "nvda.ini")
		if factoryDefaults:
			profile = self._loadConfig(None)
			profile.filename = fn
		else:
			try:
				profile = self._loadConfig(fn) # a blank config returned if fn does not exist
				self.baseConfigError = False
			except:
				log.error("Error loading base configuration", exc_info=True)
				self.baseConfigError = True
				return self._initBaseConf(factoryDefaults=True)

		for key in self.BASE_ONLY_SECTIONS:
			# These sections are returned directly from the base config, so validate them here.
			try:
				sect = profile[key]
			except KeyError:
				profile[key] = {}
				# ConfigObj mutates this into a configobj.Section.
				sect = profile[key]
			sect.configspec = self.spec[key]
			profile.validate(self.validator, section=sect)

		self._profileCache[None] = profile
		self.profiles.append(profile)
		self._handleProfileSwitch()
Example #26
0
	def onEnableDisable(self, evt):
		index=self.addonsList.GetFirstSelected()
		if index<0: return
		addon=self.curAddons[index]
		shouldDisable = self._shouldDisable(addon)
		try:
			# Counterintuitive, but makes sense when context is taken into account.
			addon.enable(not shouldDisable)
		except addonHandler.AddonError:
			log.error("Couldn't change state for %s add-on"%addon.name, exc_info=True)
			if shouldDisable:
				# Translators: The message displayed when the add-on cannot be disabled.
				message = _("Could not disable the {description} add-on.").format(
					description=addon.manifest['summary'])
			else:
				# Translators: The message displayed when the add-on cannot be enabled.
				message = _("Could not enable the {description} add-on.").format(
					description=addon.manifest['summary'])
			gui.messageBox(
				message,
				# Translators: The title of a dialog presented when an error occurs.
				_("Error"),
				wx.OK | wx.ICON_ERROR
			)
			return

		self.enableDisableButton.SetLabel(_("&Enable add-on") if shouldDisable else _("&Disable add-on"))
		self.refreshAddonsList(activeIndex=index)
Example #27
0
def setSynth(name,isFallback=False):
	global _curSynth,_audioOutputDevice
	if name is None: 
		_curSynth.terminate()
		_curSynth=None
		return True
	if name=='auto':
		# Default to OneCore on Windows 10 and above, and eSpeak on previous Operating Systems
		name='oneCore' if winVersion.winVersion.major>=10 else 'espeak'
	if _curSynth:
		_curSynth.cancel()
		_curSynth.terminate()
		prevSynthName = _curSynth.name
		_curSynth = None
	else:
		prevSynthName = None
	try:
		_curSynth=getSynthInstance(name)
		_audioOutputDevice=config.conf["speech"]["outputDevice"]
		if not isFallback:
			config.conf["speech"]["synth"]=name
		log.info("Loaded synthDriver %s"%name)
		return True
	except:
		log.error("setSynth", exc_info=True)
		if prevSynthName:
			setSynth(prevSynthName,isFallback=True)
		elif name not in ('espeak','silence'):
			setSynth('espeak',isFallback=True)
		elif name=='espeak':
			setSynth('silence',isFallback=True)
		return False
	def speak(self,speechSequence):
		"""
		Speaks the given sequence of text and speech commands.
		This base implementation will fallback to making use of the old speakText and speakCharacter methods. But new synths should override this method to support its full functionality.
		@param speechSequence: a list of text strings and SpeechCommand objects (such as index and parameter changes).
		@type speechSequence: list of string and L{speechCommand}
		"""
		import speech
		lastIndex=None
		text=""
		origSpeakFunc=self.speakText
		speechSequence=iter(speechSequence)
		while True:
			item = next(speechSequence,None)
			if text and (item is None or isinstance(item,(speech.IndexCommand,speech.CharacterModeCommand))):
				# Either we're about to handle a command or this is the end of the sequence.
				# Speak the text since the last command we handled.
				origSpeakFunc(text,index=lastIndex)
				text=""
				lastIndex=None
			if item is None:
				# No more items.
				break
			if isinstance(item,basestring):
				# Merge the text between commands into a single chunk.
				text+=item
			elif isinstance(item,speech.IndexCommand):
				lastIndex=item.index
			elif isinstance(item,speech.CharacterModeCommand):
				origSpeakFunc=self.speakCharacter if item.state else self.speakText
			elif isinstance(item,speech.SpeechCommand):
				log.debugWarning("Unknown speech command: %s"%item)
			else:
				log.error("Unknown item in speech sequence: %s"%item)
Example #29
0
def doCreatePortable(portableDirectory,copyUserConfig=False):
	d = gui.IndeterminateProgressDialog(gui.mainFrame,
		# Translators: The title of the dialog presented while a portable copy of NVDA is bieng created.
		_("Creating Portable Copy"),
		# Translators: The message displayed while a portable copy of NVDA is bieng created.
		_("Please wait while a portable copy of NVDA is created."))
	try:
		gui.ExecAndPump(installer.createPortableCopy,portableDirectory,copyUserConfig)
	except Exception as e:
		log.error("Failed to create portable copy",exc_info=True)
		d.done()
		if isinstance(e,installer.RetriableFailure):
			# Translators: a message dialog asking to retry or cancel when NVDA portable copy creation fails
			message=_("NVDA is unable to remove or overwrite a file.")
			# Translators: the title of a retry cancel dialog when NVDA portable copy creation  fails
			title=_("File in Use")
			if winUser.MessageBox(None,message,title,winUser.MB_RETRYCANCEL)==winUser.IDRETRY:
				return doCreatePortable(portableDirectory,copyUserConfig)
		# Translators: The message displayed when an error occurs while creating a portable copy of NVDA.
		# %s will be replaced with the specific error message.
		gui.messageBox(_("Failed to create portable copy: %s")%e,
			_("Error"),
			wx.OK | wx.ICON_ERROR)
		return
	d.done()
	# Translators: The message displayed when a portable copy of NVDA has been successfully created.
	# %s will be replaced with the destination directory.
	gui.messageBox(_("Successfully created a portable copy of NVDA at %s")%portableDirectory,
		_("Success"))
Example #30
0
	def executeGesture(self, gesture):
		"""Perform the action associated with a gesture.
		@param gesture: The gesture to execute.
		@type gesture: L{InputGesture}
		@raise NoInputGestureAction: If there is no action to perform.
		"""
		if watchdog.isAttemptingRecovery:
			# The core is dead, so don't try to perform an action.
			# This lets gestures pass through unhindered where possible,
			# as well as stopping a flood of actions when the core revives.
			raise NoInputGestureAction

		script = gesture.script
		focus = api.getFocusObject()
		if focus.sleepMode is focus.SLEEP_FULL or (focus.sleepMode and not getattr(script, 'allowInSleepMode', False)):
			raise NoInputGestureAction

		wasInSayAll=False
		if gesture.isModifier:
			if not self.lastModifierWasInSayAll:
				wasInSayAll=self.lastModifierWasInSayAll=sayAllHandler.isRunning()
		elif self.lastModifierWasInSayAll:
			wasInSayAll=True
			self.lastModifierWasInSayAll=False
		else:
			wasInSayAll=sayAllHandler.isRunning()
		if wasInSayAll:
			gesture.wasInSayAll=True

		speechEffect = gesture.speechEffectWhenExecuted
		if speechEffect == gesture.SPEECHEFFECT_CANCEL:
			queueHandler.queueFunction(queueHandler.eventQueue, speech.cancelSpeech)
		elif speechEffect in (gesture.SPEECHEFFECT_PAUSE, gesture.SPEECHEFFECT_RESUME):
			queueHandler.queueFunction(queueHandler.eventQueue, speech.pauseSpeech, speechEffect == gesture.SPEECHEFFECT_PAUSE)

		if log.isEnabledFor(log.IO) and not gesture.isModifier:
			log.io("Input: %s" % gesture.logIdentifier)

		if self._captureFunc:
			try:
				if self._captureFunc(gesture) is False:
					return
			except:
				log.error("Error in capture function, disabling", exc_info=True)
				self._captureFunc = None

		if gesture.isModifier:
			raise NoInputGestureAction

		if config.conf["keyboard"]["speakCommandKeys"] and gesture.shouldReportAsCommand:
			queueHandler.queueFunction(queueHandler.eventQueue, speech.speakMessage, gesture.displayName)

		gesture.reportExtra()

		if script:
			scriptHandler.queueScript(script, gesture)
			return

		raise NoInputGestureAction
Example #31
0
def formatForGUI(versionTuple):
    """Converts a version tuple to a string for displaying in the GUI
	Examples:
	- (2018, 1, 1) becomes "2018.1.1"
	- (2018, 1, 0) becomes "2018.1"
	- (0, 0, 0) becomes "0.0"
	"""
    try:
        year, major, minor = versionTuple
        return buildVersion.formatVersionForGUI(year, major, minor)
    except (
            ValueError,  # Too few/many values to unpack
            TypeError  # versionTuple is None or some other incorrect type
    ):
        # This path should never be hit. But the appearance of "unknown" in the GUI is a better outcome
        # than an exception and unusable dialog.
        # Translators: shown when an addon API version string is unknown
        default = _("unknown")
        log.error("Unable to format versionTuple: {}".format(
            repr(versionTuple)),
                  exc_info=True)
        return default
Example #32
0
def setSynth(name, isFallback=False):
    global _curSynth, _audioOutputDevice
    if name is None:
        _curSynth.terminate()
        _curSynth = None
        return True
    if name == 'auto':
        name = defaultSynthPriorityList[0]
    if _curSynth:
        _curSynth.cancel()
        _curSynth.terminate()
        prevSynthName = _curSynth.name
        _curSynth = None
    else:
        prevSynthName = None
    try:
        _curSynth = getSynthInstance(name)
        _audioOutputDevice = config.conf["speech"]["outputDevice"]
        if not isFallback:
            config.conf["speech"]["synth"] = name
        log.info("Loaded synthDriver %s" % name)
        return True
    except:  # noqa: E722 # Legacy bare except
        log.error("setSynth", exc_info=True)
        # As there was an error loading this synth:
        if prevSynthName:
            # There was a previous synthesizer, so switch back to that one.
            setSynth(prevSynthName, isFallback=True)
        else:
            # There was no previous synth, so fallback to the next available default synthesizer
            # that has not been tried yet.
            try:
                nextIndex = defaultSynthPriorityList.index(name) + 1
            except ValueError:
                nextIndex = 0
            if nextIndex < len(defaultSynthPriorityList):
                newName = defaultSynthPriorityList[nextIndex]
                setSynth(newName, isFallback=True)
        return False
Example #33
0
	def onPasteButton(self, event):
		index = self.symbolsListBox.GetSelection()
		if index == -1:
			# Translators: This is a message announced in complex symbols dialog.
			speakLater(300, _("No symbol selected"))
			return
		symbol = self.complexSymbolsList[index]
		symbolDescription = self.symbolsListBox.GetString(index)
		result = copyToClip(symbol)
		if not result:
			c = ord(symbol)
			log.error("error copyToClip symbol:%s (%s) code = %d" % (
				self.symbolDescriptionList[index], symbol, c))
		else:
			# Translators: This is a message announced in complex symbols dialog.
			msg = _("{0} pasted").format(self.symbolDescriptionList[index])
			ui.message(msg)
			time.sleep(2.0)
			core.callLater(200, SendKey, "Control+v")
		from ..settings import _addonConfigManager
		_addonConfigManager.updateLastSymbolsList(symbolDescription, symbol)
		self.Close()
def registerAddonFileAssociation(slaveExe):
	try:
		# Create progID for NVDA ad-ons
		with winreg.CreateKeyEx(winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\%s" % addonHandler.NVDA_ADDON_PROG_ID, 0, winreg.KEY_WRITE) as k:
			# Translators: A file extension label for NVDA add-on package.
			winreg.SetValueEx(k, None, 0, winreg.REG_SZ, _("NVDA add-on package"))
			with winreg.CreateKeyEx(k, "DefaultIcon", 0, winreg.KEY_WRITE) as k2:
				winreg.SetValueEx(k2, None, 0, winreg.REG_SZ, "@{slaveExe},1".format(slaveExe=slaveExe))
			# Point the open verb to nvda_slave addons_installAddonPackage action
			with winreg.CreateKeyEx(k, "shell\\open\\command", 0, winreg.KEY_WRITE) as k2:
				winreg.SetValueEx(k2, None, 0, winreg.REG_SZ, u"\"{slaveExe}\" addons_installAddonPackage \"%1\"".format(slaveExe=slaveExe))
		# Now associate addon extension to the created prog id.
		with winreg.CreateKeyEx(winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Classes\\.%s" % addonHandler.BUNDLE_EXTENSION, 0, winreg.KEY_WRITE) as k:
			winreg.SetValueEx(k, None, 0, winreg.REG_SZ, addonHandler.NVDA_ADDON_PROG_ID)
			winreg.SetValueEx(k, "Content Type", 0, winreg.REG_SZ, addonHandler.BUNDLE_MIMETYPE)
			# Add NVDA to the "open With" list
			k2 = winreg.CreateKeyEx(k, "OpenWithProgids\\%s" % addonHandler.NVDA_ADDON_PROG_ID, 0, winreg.KEY_WRITE)
			winreg.CloseKey(k2)
		# Notify the shell that a file association has changed:
		shellapi.SHChangeNotify(shellapi.SHCNE_ASSOCCHANGED, shellapi.SHCNF_IDLIST, None, None)
	except WindowsError:
		log.error("Can not create addon file association.", exc_info=True)
	def onExecuteScriptButton(self, evt):

		def callback(script, gestureOrgestureCls):
			self._executeScriptWaitingTimer = None
			wx.CallLater(200, speech.cancelSpeech)
			wx.CallLater(500, self._executeScript, script, gestureOrgestureCls, self.repeatCount)
			self.Destroy()

		self.repeatCount = self.repeatCount + 1 if self._executeScriptWaitingTimer is not None else 0
		if self._executeScriptWaitingTimer is not None:
			self._executeScriptWaitingTimer.Stop()
			self._executeScriptWaitingTimer = None
		selectedItems = self.tree.getSelectedItemData()
		if selectedItems is None:
			item = None
		else:
			# get the leaf of the selection
			item = next((item for item in reversed(selectedItems) if item is not None), None)
		if not item:
			return
		scriptInfo = item.scriptInfo
		script = self.getScript(item)
		if not script:
			log.error("no script to run: %s, %s, %s" % (
				scriptInfo.scriptName, scriptInfo.className, scriptInfo.moduleName))
			return
		try:
			gestureCls = inputCore._getGestureClsForIdentifier(scriptInfo.gestures[0])
		except Exception:
			gestureCls = KeyboardInputGesture
		gesture = None
		if gestureCls == KeyboardInputGesture and len(scriptInfo.gestures):
			identifier = scriptInfo.gestures[0]
			key = identifier.split(":", 1)[1]
			gesture = KeyboardInputGesture.fromName(key)
		gestureOrGestureCls = gesture if gesture else gestureCls
		from ..settings import _addonConfigManager
		delay = _addonConfigManager.getMaximumDelayBetweenSameScript()
		self._executeScriptWaitingTimer = wx.CallLater(delay, callback, script, gestureOrGestureCls)
Example #36
0
    def OnExportClick(self, evt):
        with wx.FileDialog(self,
                           message=_("Export file..."),
                           defaultDir=base_path,
                           defaultFile="export.rule",
                           wildcard="rule files (*.rule)|*.rule",
                           style=wx.FD_SAVE
                           | wx.FD_OVERWRITE_PROMPT) as entryDialog:
            if entryDialog.ShowModal() != wx.ID_OK:
                return
            pathname = entryDialog.GetPath()

        temp = {}
        for key, mathrule in self.mathrules:
            temp[key] = mathrule
        temp['node'] = self.A8M_mathrule['node']
        temp['none'] = self.A8M_mathrule['none']

        try:
            A8M_PM.save_math_rule(temp, path=pathname)
        except IOError as e:
            log.error("Error saving user unicode dictionary: %s" % e)
Example #37
0
 def _bg(self):
     success = False
     for url in self.urls:
         try:
             self._download(url)
         except:
             log.error("Error downloading %s" % url, exc_info=True)
         else:  #Successfully downloaded or canceled
             if not self._shouldCancel:
                 success = True
             break
     else:
         # None of the URLs succeeded.
         self._guiExec(self._error)
         return
     if not success:
         try:
             os.remove(self.destPath)
         except OSError:
             pass
         return
     self._guiExec(self._downloadSuccess)
Example #38
0
def _getProvidersFromFileSystem():
	for loader, moduleName, isPkg in pkgutil.iter_modules(visionEnhancementProviders.__path__):
		if moduleName.startswith('_'):
			continue
		try:
			#  Get each piece of info in a new statement so any exceptions raised identifies the line correctly.
			provider = _getProviderClass(moduleName)
			providerSettings = provider.getSettings()
			providerId = providerSettings.getId()
			displayName = providerSettings.getDisplayName()
			yield providerInfo.ProviderInfo(
				providerId=providerId,
				moduleName=moduleName,
				displayName=displayName,
				providerClass=provider
			)
		except Exception:  # Purposely catch everything as we don't know what a provider might raise.
			log.error(
				f"Error while importing vision enhancement provider module {moduleName}",
				exc_info=True
			)
			continue
Example #39
0
def callback(wav,numsamples,event):
	try:
		global player, isSpeaking, _numBytesPushed
		if not isSpeaking:
			return CALLBACK_ABORT_SYNTHESIS
		indexes = []
		for e in event:
			if e.type==espeakEVENT_MARK:
				indexNum = int(decodeEspeakString(e.id.name))
				# e.audio_position is ms since the start of this utterance.
				# Convert to bytes since the start of the utterance.
				BYTES_PER_SAMPLE = 2
				MS_PER_SEC = 1000
				bytesPerMS = player.samplesPerSec * BYTES_PER_SAMPLE  // MS_PER_SEC
				indexByte = e.audio_position * bytesPerMS
				# Subtract bytes in the utterance that have already been handled
				# to give us the byte offset into the samples for this callback.
				indexByte -= _numBytesPushed
				indexes.append((indexNum, indexByte))
			elif e.type==espeakEVENT_LIST_TERMINATED:
				break
		if not wav:
			player.idle()
			onIndexReached(None)
			isSpeaking = False
			return CALLBACK_CONTINUE_SYNTHESIS
		wav = string_at(wav, numsamples * sizeof(c_short)) if numsamples>0 else b""
		prevByte = 0
		for indexNum, indexByte in indexes:
			player.feed(wav[prevByte:indexByte],
				onDone=lambda indexNum=indexNum: onIndexReached(indexNum))
			prevByte = indexByte
			if not isSpeaking:
				return CALLBACK_ABORT_SYNTHESIS
		player.feed(wav[prevByte:])
		_numBytesPushed += len(wav)
		return CALLBACK_CONTINUE_SYNTHESIS
	except:
		log.error("callback", exc_info=True)
Example #40
0
def callback(wav,numsamples,event):
	try:
		global player, isSpeaking, lastIndex
		if not isSpeaking:
			return 1
		for e in event:
			if e.type==espeakEVENT_MARK:
				lastIndex=int(e.id.name)
			elif e.type==espeakEVENT_LIST_TERMINATED:
				break
		if not wav:
			player.idle()
			isSpeaking = False
			return 0
		if numsamples > 0:
			try:
				player.feed(string_at(wav, numsamples * sizeof(c_short)))
			except:
				log.debugWarning("Error feeding audio to nvWave",exc_info=True)
		return 0
	except:
		log.error("callback", exc_info=True)
Example #41
0
def showUnknownCompatDialog():
	from gui import addonGui, mainFrame, runScriptModalDialog
	if any(getAddonsWithUnknownCompatibility()):
		try:
			incompatibleAddonsDlg = addonGui.IncompatibleAddonsDialog(parent=mainFrame)
		except RuntimeError:
			log.error("Unable to open IncompatibleAddonsDialog", exc_info=True)
			return
	else:
		return
	unknownCompatAddons = incompatibleAddonsDlg.unknownCompatibilityAddonsList
	def afterDialog(res):
		# we may need to change the enabled addons / restart nvda here
		shouldPromptRestart = False
		for addon in unknownCompatAddons:
			if isAddonConsideredCompatible(addon):
				addon.enable(True)
				shouldPromptRestart = True
		saveState()
		if shouldPromptRestart:
			addonGui.promptUserForRestart()
	runScriptModalDialog(incompatibleAddonsDlg, afterDialog)
def onInstallDragonCommands(evt):
    #Translators: Warning about having custom commands already.
    goAhead = gui.messageBox(
        _("If you are on a computer with shared commands, and you have multiple users using these commands, this will override them. Please do not proceed unless you are sure you aren't sharing commands over a network. if you are, please read \"Importing Commands Into a Shared System\" in the Dictation Bridge documentation for manual steps.\nDo you want to proceed?"
          ),
        #Translators: Warning dialog title.
        _("Warning: Potentially Dangerous Opperation Will be Performed"),
        wx.YES | wx.NO)
    if goAhead == wx.NO:
        return
    dialog = gui.IndeterminateProgressDialog(
        gui.mainFrame,
        #Translators: Title for a dialog shown when Dragon  Commands are being installed!
        _("Dragon Command Installation"),
        #Translators: Message shown in the progress dialog for dragon command installation.
        _("Please wait while Dragon commands are installed."))
    try:
        gui.ExecAndPump(_onInstallDragonCommands)
    except:  #Catch all, because if this fails, bad bad bad.
        log.error("DictationBridge commands failed to install!", exc_info=True)
    finally:
        dialog.done()
Example #43
0
 def _loadBuffer(self):
     try:
         if log.isEnabledFor(log.DEBUG):
             startTime = time.time()
         self.VBufHandle = NVDAHelper.localLib.VBuf_createBuffer(
             self.rootNVDAObject.appModule.helperLocalBindingHandle,
             self.rootDocHandle, self.rootID, self.backendName)
         if not self.VBufHandle:
             raise RuntimeError("Could not remotely create virtualBuffer")
     except:
         log.error("", exc_info=True)
         queueHandler.queueFunction(queueHandler.eventQueue,
                                    self._loadBufferDone,
                                    success=False)
         return
     if log.isEnabledFor(log.DEBUG):
         log.debug(
             "Buffer load took %.3f sec, %d chars" %
             (time.time() - startTime,
              NVDAHelper.localLib.VBuf_getTextLength(self.VBufHandle)))
     queueHandler.queueFunction(queueHandler.eventQueue,
                                self._loadBufferDone)
Example #44
0
def showHelp(helpId: str):
	"""Display the corresponding section of the user guide when either the Help
	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
	helpFile = documentationUtils.getDocFilePath("userGuide.html")
	if helpFile is None:
		# Translators: Message shown when trying to display context sensitive help,
		# indicating that	the user guide could not be found.
		noHelpMessage = _("No user guide found.")
		log.debugWarning("No user guide found: possible cause - running from source without building user docs")
		queueHandler.queueFunction(queueHandler.eventQueue, ui.message, noHelpMessage)
		return
	log.debug(f"Opening help: helpId = {helpId}, userGuidePath: {helpFile}")

	nvdaTempDir = os.path.join(tempfile.gettempdir(), "nvda")
	if not os.path.exists(nvdaTempDir):
		os.mkdir(nvdaTempDir)

	contextHelpRedirect = os.path.join(nvdaTempDir, "contextHelp.html")
	try:
		# a redirect is necessary because not all browsers support opening a fragment URL from the command line.
		writeRedirect(helpId, helpFile, contextHelpRedirect)
	except Exception:
		log.error("Unable to write context help redirect file.", exc_info=True)
		return

	try:
		os.startfile(f"file://{contextHelpRedirect}")
	except Exception:
		log.error("Unable to launch context help.", exc_info=True)
Example #45
0
 def startRecognition(self, current_source, current_engine_type):
     try:
         engine = self.getCurrentEngine(current_engine_type)
         repeatCount = scriptHandler.getLastScriptRepeatCount()
         textResultWhenRepeatGesture = not config.conf["onlineOCRGeneral"][
             "swapRepeatedCountEffect"]
         if not current_source == "clipboardImage" and self.isScreenCurtainRunning(
         ):
             ui.message(
                 _("Please disable screen curtain before recognition."))
             return
         if repeatCount == 0:
             if not engine:
                 ui.message(_("Cannot get recognition engine"))
                 return
             engine.text_result = textResultWhenRepeatGesture
             if current_source == "navigatorObject":
                 recogUi.recognizeNavigatorObject(engine)
                 return
             else:
                 imageInfo, recognizeImage = self.getImageFromSource(
                     current_source)
                 if not recognizeImage:
                     ui.message(
                         _("Clipboard URL source is not implemented."))
                     return
                 pixels = recognizeImage.tobytes("raw", "BGRX")
                 # Translators: Reported when content recognition begins.
                 ui.message(_("Recognizing"))
                 engine.recognize(pixels, imageInfo, recogUi._recogOnResult)
         elif repeatCount == 1:
             engine.text_result = not textResultWhenRepeatGesture
     except Exception as e:
         from logHandler import log
         log.error(getattr(e, 'message', repr(e)))
         ui.message(
             _("Error occurred, when trying to start recognition, Please change source or engine and try again."
               ))
Example #46
0
def doCreatePortable(portableDirectory,copyUserConfig=False,silent=False,startAfterCreate=False):
	d = gui.IndeterminateProgressDialog(gui.mainFrame,
		# Translators: The title of the dialog presented while a portable copy of NVDA is bieng created.
		_("Creating Portable Copy"),
		# Translators: The message displayed while a portable copy of NVDA is bieng created.
		_("Please wait while a portable copy of NVDA is created."))
	try:
		gui.ExecAndPump(installer.createPortableCopy,portableDirectory,copyUserConfig)
	except Exception as e:
		log.error("Failed to create portable copy",exc_info=True)
		d.done()
		if isinstance(e,installer.RetriableFailure):
			# Translators: a message dialog asking to retry or cancel when NVDA portable copy creation fails
			message=_("NVDA is unable to remove or overwrite a file.")
			# Translators: the title of a retry cancel dialog when NVDA portable copy creation  fails
			title=_("File in Use")
			if winUser.MessageBox(None,message,title,winUser.MB_RETRYCANCEL)==winUser.IDRETRY:
				return doCreatePortable(portableDirectory,copyUserConfig,silent,startAfterCreate)
		# Translators: The message displayed when an error occurs while creating a portable copy of NVDA.
		# %s will be replaced with the specific error message.
		gui.messageBox(_("Failed to create portable copy: %s")%e,
			_("Error"),
			wx.OK | wx.ICON_ERROR)
		return
	d.done()
	if not silent:
		# Translators: The message displayed when a portable copy of NVDA has been successfully created.
		# %s will be replaced with the destination directory.
		gui.messageBox(_("Successfully created a portable copy of NVDA at %s")%portableDirectory,
			_("Success"))
	if silent or startAfterCreate:
		newNVDA = None
		if startAfterCreate:
			newNVDA = core.NewNVDAInstance(
				filePath=os.path.join(portableDirectory, 'nvda.exe'),
			)
		if not core.triggerNVDAExit(newNVDA):
			log.error("NVDA already in process of exiting, this indicates a logic error.")
Example #47
0
 def __init__(self):
     super(BrailleInputHandler, self).__init__()
     # #6140: Migrate to new table names as smoothly as possible.
     tableName = config.conf["braille"]["inputTable"]
     newTableName = brailleTables.RENAMED_TABLES.get(tableName)
     if newTableName:
         tableName = config.conf["braille"]["inputTable"] = newTableName
     try:
         self._table = brailleTables.getTable(tableName)
     except LookupError:
         log.error("Invalid table: %s" % tableName)
         self._table = brailleTables.getTable(FALLBACK_TABLE)
     #: A buffer of entered braille cells so that state set by previous cells can be maintained;
     #: e.g. capital and number signs.
     self.bufferBraille = []
     #: The text translated so far from the cells in L{bufferBraille}.
     self.bufferText = u""
     #: Indexes of cells which produced text.
     #: For example, this includes letters and numbers, but not number signs,
     #: since a number sign by itself doesn't produce text.
     #: This is used when erasing cells to determine when to backspace an actual character.
     self.cellsWithText = set()
     #: The cells in L{bufferBraille} that have not yet been translated
     #: or were translated but did not produce any text.
     #: This is used to show these cells to the user while they're entering braille.
     #: This is a string of Unicode braille.
     self.untranslatedBraille = ""
     #: The position in L{brailleBuffer} where untranslated braille begins.
     self.untranslatedStart = 0
     #: The user's cursor position within the untranslated braille.
     #: This enables the user to move within the untranslated braille.
     self.untranslatedCursorPos = 0
     #: The time at which uncontracted characters were sent to the system.
     self._uncontSentTime = None
     #: The modifiers currently being held virtually to be part of the next braille input gesture.
     self.currentModifiers = set()
     config.post_configProfileSwitch.register(
         self.handlePostConfigProfileSwitch)
Example #48
0
    def __init__(self, port="Auto"):
        log.info("BAUM VarioPro Init")
        super().__init__()
        self.numCells = 0

        self._dev = None
        self.bp_trans_prev_byte = 0  # BAUM protocol transport layer (ESC dedoubling)

        self.mainModule = None
        self.statusModule = None
        self.telephoneModule = None
        self.connected_modules = {}

        try:
            if port == "auto":
                tryPorts = self._getAutoPorts(
                    hwPortUtils.listComPorts(onlyAvailable=True))
            else:
                tryPorts = ((port, "serial"), )
            for port, portType in tryPorts:
                if self._dev:
                    if self._dev.is_open():
                        self._dev.close()
                self._dev = hwIo.Serial(port,
                                        baudrate=BAUD_RATE,
                                        timeout=self.timeout,
                                        writeTimeout=self.timeout,
                                        onReceive=self._onReceive)
                self.vp_query_modules()
                for i in range(10):  # wait for dev arrival
                    self._dev.waitForRead(self.timeout)
                    if self.numCells:
                        break
                else:
                    log.error("Device arrival timeout")
        except Exception as e:
            log.error(e)
            raise RuntimeError("No BAUM VarioPro display found")
Example #49
0
def terminate():
	import brailleViewer
	brailleViewer.destroyBrailleViewer()

	for instance, state in gui.SettingsDialog._instances.items():
		if state is gui.SettingsDialog._DIALOG_DESTROYED_STATE:
			log.error(
				"Destroyed but not deleted instance of settings dialog exists: {!r}".format(instance)
			)
		else:
			log.debug("Exiting NVDA with an open settings dialog: {!r}".format(instance))
	global mainFrame
	# This is called after the main loop exits because WM_QUIT exits the main loop
	# without destroying all objects correctly and we need to support WM_QUIT.
	# Therefore, any request to exit should exit the main loop.
	safeAppExit()
	# #4460: We need another iteration of the main loop
	# so that everything (especially the TaskBarIcon) is cleaned up properly.
	# ProcessPendingEvents doesn't seem to work, but MainLoop does.
	# Because the top window gets destroyed,
	# MainLoop thankfully returns pretty quickly.
	wx.GetApp().MainLoop()
	mainFrame = None
	def moveToCell(self, type, whichOne ):
		row = Row(self, self.row)
		column = Column(self, self.column)
		if type == "row":
			if (whichOne in ["first", "previous"] and column.isFirst) or (whichOne in ["last", "next"] and column.isLast):
				#table's limit
				ui.message(_("table's limit"))
				return False
			newCell = row.getCell(whichOne, self.columnIndex)
		elif type == "column":
			if (whichOne in  ["first", "previous"] and row.isFirst) or (whichOne in ["last", "next"] and row.isLast):
				#table's limit
				ui.message(_("table's limit"))
				return False
			# move cell in column
			newCell = column.getCell(whichOne, self.rowIndex)
		else:
			# error
			log.error("moveToCell: invalid parameter %s" %type)
		if newCell:
			newCell.goTo()
			return newCell
		return False
Example #51
0
def getObjectByHierarchy(oParent, iHierarchy):
    try:
        sHierarchy = _audacityHierarchyID[iHierarchy]
    except:
        return None
    try:
        o = oParent
        if len(sHierarchy):
            Hierarchy = sHierarchy.split("|")
            for i in Hierarchy:
                iChild = int(i)
                if o and iChild <= o.childCount:
                    o = o.getChild(iChild)

                else:
                    # error, no child
                    return None

            return o
    except:
        log.error("error getObjectByHierarchy: %s, parent: %s" %
                  (sHierarchy, oParent.name))
    return None
Example #52
0
def triggerNVDAExit(newNVDA: Optional[NewNVDAInstance] = None) -> bool:
	"""
	Used to safely exit NVDA. If a new instance is required to start after exit, queue one by specifying
	instance information with `newNVDA`.
	@return: True if this is the first call to trigger the exit, and the shutdown event was queued.
	"""
	from gui.message import isInMessageBox
	import queueHandler
	global _hasShutdownBeenTriggered
	with _shuttingDownFlagLock:
		safeToExit = not isInMessageBox()
		if not safeToExit:
			log.error("NVDA cannot exit safely, ensure open dialogs are closed")
			return False
		elif _hasShutdownBeenTriggered:
			log.debug("NVDA has already been triggered to exit safely.")
			return False
		else:
			# queue this so that the calling process can exit safely (eg a Popup menu)
			queueHandler.queueFunction(queueHandler.eventQueue, _doShutdown, newNVDA)
			_hasShutdownBeenTriggered = True
			log.debug("_doShutdown has been queued")
			return True
Example #53
0
def nextLine(self):
    try:
        dest = self._readingInfo.copy()
        moved = dest.move(self._getReadingUnit(), 1)
        if not moved:
            if self.allowPageTurns and isinstance(
                    dest.obj, textInfos.DocumentWithPageTurns):
                try:
                    dest.obj.turnPage()
                except RuntimeError:
                    pass
                else:
                    dest = dest.obj.makeTextInfo(textInfos.POSITION_FIRST)
            else:  # no page turn support
                return
        dest.collapse()
        self._setCursor(dest)
        sayCurrentLine()
    except BaseException as e:
        log.error("Error with scroll function patch, disabling: %s" % e)
        configBE.conf["patch"]["scrollBraille"] = False
        configBE.conf["general"]["speakScroll"] = False
        core.restart()
Example #54
0
    def findBestAPIClass(cls, kwargs, relation=None):
        """
		Finds out the highest-level APIClass this object can get to given these kwargs, and updates the kwargs and returns the APIClass.
		@param relation: the relationship of a possible new object of this type to  another object creating it (e.g. parent).
		@param type: string
		@param kwargs: the arguments necessary to construct an object of the class this method was called on.
		@type kwargs: dictionary
		@returns: the new APIClass
		@rtype: DynamicNVDAObjectType
		"""
        newAPIClass = cls
        if 'getPossibleAPIClasses' in newAPIClass.__dict__:
            for possibleAPIClass in newAPIClass.getPossibleAPIClasses(
                    kwargs, relation=relation):
                if 'kwargsFromSuper' not in possibleAPIClass.__dict__:
                    log.error(
                        "possible API class %s does not implement kwargsFromSuper"
                        % possibleAPIClass)
                    continue
                if possibleAPIClass.kwargsFromSuper(kwargs, relation=relation):
                    return possibleAPIClass.findBestAPIClass(kwargs,
                                                             relation=relation)
        return newAPIClass if newAPIClass is not NVDAObject else None
Example #55
0
	def completeRemove(self,runUninstallTask=True):
		if runUninstallTask:
			try:
				# #2715: The add-on must be added to _availableAddons here so that
				# translations can be used in installTasks module.
				_availableAddons[self.path] = self
				self.runInstallTask("onUninstall")
			except:
				log.error("task 'onUninstall' on addon '%s' failed"%self.name,exc_info=True)
			finally:
				del _availableAddons[self.path]
		tempPath=tempfile.mktemp(suffix=DELETEDIR_SUFFIX,dir=os.path.dirname(self.path))
		try:
			os.rename(self.path,tempPath)
		except (WindowsError,IOError):
			raise RuntimeError("Cannot rename add-on path for deletion")
		shutil.rmtree(tempPath,ignore_errors=True)
		if os.path.exists(tempPath):
			log.error("Error removing addon directory %s, deferring until next NVDA restart"%self.path)
		# clean up the addons state
		log.debug("removing addon {} from _disabledAddons".format(self.name))
		_disabledAddons.discard(self.name)
		saveState()
Example #56
0
def executeMouseMoveEvent(x,y):
	global currentMouseWindow
	desktopObject=api.getDesktopObject()
	screenLeft,screenTop,screenWidth,screenHeight=desktopObject.location
	x=min(max(screenLeft,x),(screenLeft+screenWidth)-1)
	y=min(max(screenTop,y),(screenTop+screenHeight)-1)
	if config.conf["mouse"]["audioCoordinatesOnMouseMove"]:
		playAudioCoordinates(x,y,screenWidth,screenHeight,config.conf['mouse']['audioCoordinates_detectBrightness'],config.conf['mouse']['audioCoordinates_blurFactor'])
	oldMouseObject=api.getMouseObject()
	mouseObject=desktopObject.objectFromPoint(x,y)
	while mouseObject and mouseObject.beTransparentToMouse:
		mouseObject=mouseObject.parent
	if not mouseObject:
		return
	if oldMouseObject==mouseObject:
		mouseObject=oldMouseObject
	else:
		api.setMouseObject(mouseObject)
	try:
		eventHandler.executeEvent("mouseMove",mouseObject,x=x,y=y)
		oldMouseObject=mouseObject
	except:
		log.error("api.notifyMouseMoved", exc_info=True)
Example #57
0
	def __init__(
		self,
		targetDll: str,
		importDll: str,
		funcName: str,
		newFunction # result of ctypes.WINFUNCTYPE
	):
		# dllImportTableHooks_hookSingle expects byte strings.
		try:
			self._hook=NVDAHelper.localLib.dllImportTableHooks_hookSingle(
				targetDll.encode("mbcs"),
				importDll.encode("mbcs"),
				funcName.encode("mbcs"),
				newFunction
			)
		except UnicodeEncodeError:
			log.error("Error encoding FunctionHooker input parameters", exc_info=True)
			self._hook = None
		if self._hook:
			log.debug(f"Hooked {funcName}")
		else:
			log.error(f"Could not hook {funcName}")
			raise RuntimeError(f"Could not hook {funcName}")
Example #58
0
 def speak(self, speechSequence):
     textList = []
     charMode = False
     for item in speechSequence:
         if isinstance(item, basestring):
             textList.append(item.replace('\\', '\\\\'))
         elif isinstance(item, speech.IndexCommand):
             textList.append("\\mrk=%d\\" % item.index)
         elif isinstance(item, speech.CharacterModeCommand):
             textList.append("\\RmS=1\\" if item.state else "\\RmS=0\\")
             charMode = item.state
         elif isinstance(item, speech.SpeechCommand):
             log.debugWarning("Unsupported speech command: %s" % item)
         else:
             log.error("Unknown speech: %s" % item)
     if charMode:
         # Some synths stay in character mode if we don't explicitly disable it.
         textList.append("\\RmS=0\\")
     text = "".join(textList)
     flags = TTSDATAFLAG_TAGGED
     self._ttsCentral.TextData(VOICECHARSET.CHARSET_TEXT, flags,
                               TextSDATA(text), self._bufSinkPtr,
                               ITTSBufNotifySink._iid_)
	def loadBasicSymbolCategories(self):
		symbol_description_separator = "\t"
		curCategory = None
		fileName = self.getSymbolCategoriesDicPath()
		if fileName is None:
			return False
		symbolCategories = {}
		orderedSymbols = {}
		with codecs.open(fileName, "r", "utf_8_sig", errors="replace") as f:
			for line in f:
				if line.isspace() or line.startswith("#"):
					# Whitespace or comment.
					continue
				line = line.rstrip("\r\n")
				if self.isCategorieName(line):
					curCategory = line[1:-1]
					self.basicOrderedSymbolCategoryNames.append(curCategory)
					symbolCategories[curCategory] = {}
					orderedSymbols[curCategory] = []
					continue
				tempLine = line.split(symbol_description_separator)
				if (len(tempLine) == 2) and tempLine[0] and tempLine[1]:
					symbol = tempLine[0]
					description = tempLine[1]
					if curCategory is None:
						log.error("Symbol without category: %s" % line)
						continue
					symbolCategories[curCategory][symbol] = description
					orderedSymbols[curCategory].append(symbol)
				else:
					log.error("Symbol and description incorrect: %s" % line)
		if len(symbolCategories) == 0:
			return False

		self.basicSymbolCategoriesDic = symbolCategories.copy()
		self.orderedSymbols = orderedSymbols.copy()
		return True
Example #60
0
 def onRunCOMRegistrationFixesCommand(self, evt):
     if isModalMessageBoxActive():
         return
     if messageBox(
             # Translators: A message to warn the user when starting the COM Registration Fixing tool
             _("You are about to run the COM Registration Fixing tool. This tool will try to fix common system problems that stop NVDA from being able to access content in many programs including Firefox and Internet Explorer. This tool must make changes to the System registry and therefore requires administrative access. Are you sure you wish to proceed?"
               ),
             # Translators: The title of the warning dialog displayed when launching the COM Registration Fixing tool
             _("Warning"),
             wx.YES | wx.NO | wx.ICON_WARNING,
             self) == wx.NO:
         return
     progressDialog = IndeterminateProgressDialog(
         mainFrame,
         # Translators: The title of the dialog presented while NVDA is running the COM Registration fixing tool
         _("COM Registration Fixing Tool"),
         # Translators: The message displayed while NVDA is running the COM Registration fixing tool
         _("Please wait while NVDA tries to fix your system's COM registrations."
           ))
     try:
         import systemUtils
         systemUtils.execElevated(config.SLAVE_FILENAME,
                                  ["fixCOMRegistrations"])
     except:
         log.error("Could not execute fixCOMRegistrations command",
                   exc_info=True)
     progressDialog.done()
     del progressDialog
     messageBox(
         _(
             # Translators: The message displayed when the COM Registration Fixing tool completes.
             "The COM Registration Fixing tool has finished. "
             "It is highly recommended that you restart your computer now, to make sure the changes take full effect."
         ),
         # Translators: The title of a dialog presented when the COM Registration Fixing tool is complete.
         _("COM Registration Fixing Tool"),
         wx.OK)