Esempio n. 1
0
 def on_load_password_list(self, evt):
     evt.Skip()
     self.load_password_list.Enable(False)
     self.extend_password_list.Enable(False)
     self.unload_password_list.Enable(False)
     if len(self.passwords) < 1:
         # translators: strings to indicate the password list is being loaded.
         self.prog = gui.IndeterminateProgressDialog(
             gui.mainFrame, _("Loading password list"),
             _("Please wait while the password list is loaded."))
         gui.ExecAndPump(self._load)
         self.prog.done()
         del self.prog
         # translators: text displayed by NVDA when the password list is loaded.
         gui.messageBox(_("Password list loaded."), _("Finished"))
     else:
         # translators: strings to indicate the password list is being reloaded.
         self.prog = gui.IndeterminateProgressDialog(
             gui.mainFrame, _("Reloading password list"),
             _("Please wait while the password list is reloaded."))
         gui.ExecAndPump(self._reload)
         self.prog.done()
         del self.prog
         # translators: text displayed by NVDA when the password list is reloaded.
         gui.messageBox(_("Password list reloaded."), _("Finished"))
     self.load_password_list.Enable(True)
     self.extend_password_list.Enable(True)
     self.unload_password_list.Enable(True)
Esempio n. 2
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"))
Esempio n. 3
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)
def doInstall(createDesktopShortcut,startOnLogon,copyPortableConfig,isUpdate,silent=False,startAfterInstall=True):
	progressDialog = gui.IndeterminateProgressDialog(gui.mainFrame,
		# Translators: The title of the dialog presented while NVDA is being updated.
		_("Updating NVDA") if isUpdate
		# Translators: The title of the dialog presented while NVDA is being installed.
		else _("Installing NVDA"),
		# Translators: The message displayed while NVDA is being updated.
		_("Please wait while your previous installation of NVDA is being updated.") if isUpdate
		# Translators: The message displayed while NVDA is being installed.
		else _("Please wait while NVDA is being installed"))
	try:
		res=config.execElevated(config.SLAVE_FILENAME,["install",str(int(createDesktopShortcut)),str(int(startOnLogon))],wait=True,handleAlreadyElevated=True)
		if res==2: raise installer.RetriableFailure
		if copyPortableConfig:
			installedUserConfigPath=config.getInstalledUserConfigPath()
			if installedUserConfigPath:
				gui.ExecAndPump(installer.copyUserConfig,installedUserConfigPath)
	except Exception as e:
		res=e
		log.error("Failed to execute installer",exc_info=True)
	progressDialog.done()
	del progressDialog
	if isinstance(res,installer.RetriableFailure):
		# Translators: a message dialog asking to retry or cancel when NVDA install fails
		message=_("The installation is unable to remove or overwrite a file. Another copy of NVDA may be running on another logged-on user account. Please make sure all installed copies of NVDA are shut down and try the installation again.")
		# Translators: the title of a retry cancel dialog when NVDA installation fails
		title=_("File in Use")
		if winUser.MessageBox(None,message,title,winUser.MB_RETRYCANCEL)==winUser.IDRETRY:
			return doInstall(createDesktopShortcut,startOnLogon,copyPortableConfig,isUpdate,silent,startAfterInstall)
	if res!=0:
		log.error("Installation failed: %s"%res)
		# Translators: The message displayed when an error occurs during installation of NVDA.
		gui.messageBox(_("The installation of NVDA failed. Please check the Log Viewer for more information."),
			# Translators: The title of a dialog presented when an error occurs.
			_("Error"),
			wx.OK | wx.ICON_ERROR)
		return
	if not silent:
		msg = (
			# Translators: The message displayed when NVDA has been successfully installed.
			_("Successfully installed NVDA. ") if not isUpdate
			# Translators: The message displayed when NVDA has been successfully updated.
			else _("Successfully updated your installation of NVDA. "))
		# Translators: The message displayed to the user after NVDA is installed
		# and the installed copy is about to be started.
		gui.messageBox(msg+_("Please press OK to start the installed copy."),
			# Translators: The title of a dialog presented to indicate a successful operation.
			_("Success"))
	if startAfterInstall:
		# #4475: ensure that the first window of the new process is not hidden by providing SW_SHOWNORMAL  
		shellapi.ShellExecute(
			None,
			None,
			os.path.join(installer.defaultInstallPath,'nvda.exe'),
			None,
			None,
			winUser.SW_SHOWNORMAL
		)
	else:
		wx.GetApp().ExitMainLoop()
Esempio n. 5
0
    def script_nvdaStore(self, gesture):
        if self.lastData is None or self.lastData["type"] is GP_DISCONNECTED:
            ui.message(self.lastData["message"])
            return
        gui.mainFrame.prePopup()
        progressDialog = gui.IndeterminateProgressDialog(
            gui.mainFrame, _("Updating addons' list"),
            _("Please wait while the add-on list is being updated."))
        try:
            gui.ExecAndPump(self.doRefreshAddons)
        except:
            progressDialog.done()
            del progressDialog
            gui.mainFrame.postPopup()
            return
        progressDialog.done()
        del progressDialog
        gui.mainFrame.postPopup()

        gui.mainFrame.prePopup()
        dlg = storeGui.StoreDialog(gui.mainFrame, self.storeClient,
                                   self.addons)
        dlg.Show()
        gui.mainFrame.postPopup()
        del dlg
Esempio n. 6
0
    def updateAll(self):
        updated = 0
        if len(self.updates) is 0:
            self.refreshAddons(True)
            if len(self.updates) == 0:
                ui.message(_(u"NVDAStore: No update available."))
                return

        for update in self.updates:
            gui.mainFrame.prePopup()
            progressDialog = gui.IndeterminateProgressDialog(
                gui.mainFrame, _("NVDAStore"),
                _(u"Updating {name}...".format(name=update.name)))
            ui.message(_("Updating {name}".format(name=update.name)))
            try:
                gui.ExecAndPump(storeUtils.installAddon, self.storeClient,
                                update, False, True)
            except:
                progressDialog.done()
                del progressDialog
                gui.mainFrame.postPopup()
                break
            progressDialog.done()
            del progressDialog
            updated += 1
            gui.mainFrame.postPopup()
        if updated:
            core.restart()
def onInstallMSRCommands(evt):
	dialog = gui.IndeterminateProgressDialog(gui.mainFrame,
		#Translators: Title for a dialog shown when Microsoft speech recognition Commands are being installed!
		_("Microsoft Speech Recognition Command Installation"),
		#Translators: Message shown in the progress dialog for MSR command installation.
		_("Please wait while microsoft speech recognition commands are installed."))
	try:
		gui.ExecAndPump(_onInstallMSRCommands)
	except: #Catch all, because if this fails, bad bad bad.
		log.error("DictationBridge commands failed to install!", exc_info=True)
	finally:
		dialog.done()
Esempio n. 8
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 silent:
        wx.GetApp().ExitMainLoop()
    else:
        # 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 startAfterCreate:
            # #4475: ensure that the first window of the new process is not hidden by providing SW_SHOWNORMAL
            shellapi.ShellExecute(
                None, None,
                os.path.join(os.path.abspath(portableDirectory), 'nvda.exe'),
                u"-r", None, winUser.SW_SHOWNORMAL)
Esempio n. 9
0
def getAddon():
    import tempfile, os
    addon = opener(updateInfo["downloadUrl"])
    content = addon.read()
    addon.close()
    if updateInfo["size"] != len(content):
        gui.messageBox(_("Data load error"),
                       _("Error"),
                       style=wx.OK | wx.ICON_ERROR)
        return
    fd, path = tempfile.mkstemp(".nvda-addon", "tcmd_addon_update-")
    with open(path, "wb") as file:
        file.write(content)
    import core
    bundle = addonHandler.AddonBundle(path)
    try:
        if not addonHandler.addonVersionCheck.isAddonCompatible(bundle):
            gui.messageBox(_(
                "This version of NVDA is incompatible. To install the add-on, NVDA version {year}.{major} or higher is required. Please update NVDA or download an older version of the add-on here: \n{link}"
            ).format(
                year=bundle.minimumNVDAVersion[0],
                major=bundle.minimumNVDAVersion[1],
                link=
                "https://github.com/jawhien/extendedTotalCmd/releases/tag/2.5"
            ),
                           _("Error"),
                           style=wx.OK | wx.ICON_ERROR)
            os.close(fd)
            os.unlink(path)
            return
    except:
        pass
    gui.ExecAndPump(addonHandler.installAddonBundle, bundle)
    for addon in addonHandler.getAvailableAddons():
        if not addon.isPendingRemove and manifest["name"].lower(
        ) == addon.manifest["name"].lower():
            addon.requestRemove()
            break
    os.close(fd)
    os.unlink(path)
    if gui.messageBox(_(
            "Changes were made to add-ons. You must restart NVDA for these changes to take effect. Would you like to restart now?"
    ),
                      _("Restart NVDA"),
                      style=wx.YES | wx.NO | wx.ICON_WARNING) == wx.YES:
        core.restart()
Esempio n. 10
0
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()
Esempio n. 11
0
	def _onSetLocalClick(self, evt):
		# Translators: The message displayed when the current source path is relative.
		if  not path.isabs(self._ttsPath.GetValue()):
			# Translators: The message displayed when the current source path is relative.
			gui.messageBox(_("Relative paths are not allowed."), _("Error"), wx.OK|wx.ICON_ERROR, self)
			return
		# Translators: A message to ask the user to copy IBMTTS files to Add-on folder.
		if gui.messageBox(_("Are you sure to copy IBMTTS files to local NVDA driver Add-on? It may not work in some IBMTTS distributions."),
			# Translators: The title of the Asking dialog displayed when trying to copy IBMTTS files.
			_("Copy IBMTTS files"),
			wx.YES|wx.NO|wx.ICON_QUESTION, self) == wx.YES:
			progressDialog = gui.IndeterminateProgressDialog(gui.mainFrame,
				# Translators: The title of the dialog presented while IBMTTS files  are being copied.
				_("Copying files"),
				# Translators: The message displayed while IBMTTS files are being copied.
				_("Please wait while IBMTTS files  are copied into add-on."))
			while True:
				try:
					gui.ExecAndPump(self.copyTtsFiles)
					res = True
					break
				except Exception:
					# Translators: a message dialog asking to retry or cancel when copying IBMTTS files.
					message=_("Unable to copy a file. Perhaps it is currently being used by another process or you have run out of disc space on the drive you are copying to.")
					# Translators: the title of a retry cancel dialog when copying IBMTTS files.
					title=_("Error Copying")
					if winUser.MessageBox(None,message,title,winUser.MB_RETRYCANCEL) != winUser.IDRETRY:
						res=False
						log.debugWarning("Error when copying IBMTTS files into Add-on",exc_info=True)
						break
			progressDialog.done()
			del progressDialog
			if res:
				self._ttsPath.SetValue("ibmtts")
				# this parameter is saved even if the user doesn't click accept button.
				config.conf['ibmeci']['TTSPath'] = self._ttsPath.GetValue()
				# Translators: The message displayed when copying IBMTTS files to Add-on was successful.
				gui.messageBox(_("Successfully copied IBMTTS files. The local copy will be used after restart NVDA."),
					# Translators: The title  displayed when copying IBMTTS files to Add-on was successful.
					_("Success"),wx.OK|wx.ICON_INFORMATION,self)
			else:
				# Translators: The message displayed when errors were found while trying to copy IBMTTS files to Add-on.
				gui.messageBox(_("Error copying IBMTTS files"), _("Error"), wx.OK|wx.ICON_ERROR, self)
Esempio n. 12
0
 def on_extend_password_list(self, evt):
     evt.Skip()
     if self.inDialog:
         # translators: text to indicate that another dialog is already open.
         gui.messageBox(
             _("Another dialog is already open; close it first!"),
             _("Cannot continue"))
         return
     self.load_password_list.Enable(False)
     self.extend_password_list.Enable(False)
     self.unload_password_list.Enable(False)
     # translators: the open file dialog for extending the password list.
     openfile = wx.FileDialog(
         parent=gui.mainFrame,
         message=_(
             "Select a password list to append to the list of currently loaded passwords (currently {} passwords)"
             .format(len(self.passwords))),
         defaultDir=_(""),
         defaultFile=_(""),
         wildcard=_("Password list files (*.txt)|.txt"),
         style=wx.FD_OPEN | wx.FD_FILE_MUST_EXIST | wx.FD_MULTIPLE)
     self.inDialog = True
     if openfile.ShowModal() == wx.ID_OK:
         self.inDialog = False
         # translators: strings to indicate the password list is being loaded.
         self.prog = gui.IndeterminateProgressDialog(
             gui.mainFrame, _("Loading password list"),
             _("Please wait while the password list is loaded."))
         gui.ExecAndPump(self._load_list, openfile.GetPath())
         self.prog.done()
         del self.prog
         # translators: text announced by NVDA when the password list is loaded.
         gui.messageBox(_("Password list loaded!"), _("Finished"))
     else:
         logHandler.log.error("Could not open password extender dialog")
     self.load_password_list.Enable(True)
     self.extend_password_list.Enable(True)
     self.unload_password_list.Enable(True)
Esempio n. 13
0
 def _downloadSuccess(self):
     self._stopped()
     try:
         try:
             bundle = addonHandler.AddonBundle(self.destPath)
         except:
             log.error(f"Error opening addon bundle from {self.destPath}",
                       exc_info=True)
             gui.messageBox(
                 # Translators: The message displayed when an error occurs
                 # when trying to update an add-on package due to package problems.
                 _("Cannot update {name} - missing file or invalid file format"
                   ).format(name=self.addonName),
                 translate("Error"),
                 wx.OK | wx.ICON_ERROR)
             self.continueUpdatingAddons()
             return
         # NVDA itself will check add-on compatibility range.
         # As such, the below fragment was borrowed from NVDA Core (credit: NV Access).
         from addonHandler import addonVersionCheck
         from gui import addonGui
         if not addonVersionCheck.hasAddonGotRequiredSupport(bundle):
             addonGui._showAddonRequiresNVDAUpdateDialog(
                 gui.mainFrame, bundle)
             self.continueUpdatingAddons()
             return
         elif not addonVersionCheck.isAddonTested(bundle):
             addonGui._showAddonTooOldDialog(gui.mainFrame, bundle)
             self.continueUpdatingAddons()
             return
         bundleName = bundle.manifest['name']
         isDisabled = False
         # Optimization (future): it is better to remove would-be add-ons all at once
         # instead of doing it each time a bundle is opened.
         for addon in addonHandler.getAvailableAddons():
             # Check for disabled state first.
             if bundleName == addon.manifest['name']:
                 if addon.isDisabled:
                     isDisabled = True
                 if not addon.isPendingRemove:
                     addon.requestRemove()
                 break
         progressDialog = gui.IndeterminateProgressDialog(
             gui.mainFrame,
             # Translators: The title of the dialog presented while an Addon is being updated.
             _("Updating {name}").format(name=self.addonName),
             # Translators: The message displayed while an addon is being updated.
             _("Please wait while the add-on is being updated."))
         try:
             gui.ExecAndPump(addonHandler.installAddonBundle, bundle)
         except:
             log.error(
                 f"Error installing  addon bundle from {self.destPath}",
                 exc_info=True)
             progressDialog.done()
             progressDialog.Hide()
             progressDialog.Destroy()
             gui.messageBox(
                 # Translators: The message displayed when an error occurs when installing an add-on package.
                 _("Failed to update {name} add-on").format(
                     name=self.addonName),
                 translate("Error"),
                 wx.OK | wx.ICON_ERROR)
             self.continueUpdatingAddons()
             return
         else:
             progressDialog.done()
             progressDialog.Hide()
             progressDialog.Destroy()
             _updatedAddons.append(bundleName)
             if isDisabled:
                 for addon in addonHandler.getAvailableAddons():
                     if bundleName == addon.manifest[
                             'name'] and addon.isPendingInstall:
                         addon.enable(False)
                         break
     finally:
         try:
             os.remove(self.destPath)
         except OSError:
             pass
     self.continueUpdatingAddons()
Esempio n. 14
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)
                gui.messageBox(
                    # Translators: The message displayed when an error occurs when opening an add-on package for adding.
                    _("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

            if not addonVersionCheck.hasAddonGotRequiredSupport(bundle):
                self._showAddonRequiresNVDAUpdateDialog(bundle)
                return

            if not addonVersionCheck.isAddonTested(bundle):
                if wx.YES != self._showAddonUntestedDialog(bundle):
                    return
                AddonCompatibilityState.setAddonCompatibility(
                    addon=bundle,
                    compatibilityStateValue=compatValues.
                    MANUALLY_SET_COMPATIBLE)
            elif wx.YES != self._showConfirmAddonInstallDialog(bundle):
                return

            prevAddon = None
            for addon in self.curAddons:
                if not addon.isPendingRemove and bundle.name == addon.manifest[
                        'name']:
                    prevAddon = addon
                    break
            if prevAddon:
                summary = bundle.manifest["summary"]
                curVersion = prevAddon.manifest["version"]
                newVersion = bundle.manifest["version"]
                if gui.messageBox(
                        # Translators: A message asking if the user wishes to update an add-on with the same version currently installed according to the version number.
                        _("You are about to install version {newVersion} of {summary}, which appears to be already installed. Would you still like to update?"
                          ).format(summary=summary, newVersion=newVersion)
                        if curVersion == newVersion else
                        # Translators: A message asking if the user wishes to update a previously installed add-on with this one.
                        _("A version of this add-on is already installed. Would you like to update {summary} version {curVersion} to version {newVersion}?"
                          ).format(summary=summary,
                                   curVersion=curVersion,
                                   newVersion=newVersion),
                        # 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)
Esempio n. 15
0
def installAddon(storeClient, addon, closeAfter=False, silent=False):
    if silent == False:
        ui.message(_("Downloading %s") % (addon.name))
    data = storeClient.getAddonFile(addon.id, addon.versionId)

    if data is None:
        if silent == False:
            ui.message(_("Unable to download the add-on."))
        return False
    tmp = os.path.join(config.getUserDefaultConfigPath(),
                       "storeDownloadedAddon.nvda-addon")
    logHandler.log.info(u"Saving to %s" % (tmp))
    f = file(tmp, "wb")
    f.write(data)
    f.close()
    path = tmp
    if path is None:
        if silent == False:
            ui.message(_("Unable to download %s") % (addon.name))
        return False
    if silent == False:
        ui.message(_("Installing"))
    try:
        bundle = addonHandler.AddonBundle(path)
    except:
        logHandler.log.error("Error opening addon bundle from %s" % path,
                             exc_info=True)
        # Translators: The message displayed when an error occurs when opening an add-on package for adding.
        if silent == False:
            gui.messageBox(
                _("Failed to open add-on package file at %s - missing file or invalid file format"
                  ) % path,
                # Translators: The title of a dialog presented when an error occurs.
                _("Error"),
                wx.OK | wx.ICON_ERROR)
        return False
    bundleName = bundle.manifest['name']
    prevAddon = None
    for addon in addonHandler.getAvailableAddons():
        if not addon.isPendingRemove and bundleName == addon.manifest['name']:
            prevAddon = addon
            break
    if prevAddon:
        prevAddon.requestRemove()
    if silent is False:
        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:
            logHandler.log.error("Error installing  addon bundle from %s" %
                                 addonPath,
                                 exc_info=True)
            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") % (addon.name),
                # Translators: The title of a dialog presented when an error occurs.
                _("Error"),
                wx.OK | wx.ICON_ERROR)
            return False
        progressDialog.done()
        del progressDialog
    else:
        try:
            addonHandler.installAddonBundle(bundle)
        except:
            return False
    if closeAfter:
        wx.CallLater(1, core.restart)
    return True
    def _downloadSuccess(self):
        def getBundle():
            try:
                bundle = addonHandler.AddonBundle(self.destPath.decode("mbcs"))
            except AttributeError:
                bundle = addonHandler.AddonBundle(self.destPath)
            except Exception:
                log.error("Error opening addon bundle from %s" % self.destPath,
                          exc_info=True)
                # Translators: The message displayed when an error occurs
                # when trying to update an add-on package due to package problems.
                gui.messageBox(
                    # Translators: message to user
                    _("Cannot update {name} - missing file or invalid file format"
                      ).format(name=self.addonName),
                    makeAddonWindowTitle(NVDAString("Error")),
                    wx.OK | wx.ICON_ERROR)
                return None
            return bundle

        self._stopped()
        try:
            bundle = getBundle()
            if bundle is None:
                self.continueUpdatingAddons()
                return
            minimumNVDAVersion = bundle.manifest.get("minimumNVDAVersion",
                                                     None)
            lastTestedNVDAVersion = bundle.manifest.get(
                "lastTestedNVDAVersion", None)
            bundleName = bundle.manifest['name']
            if not checkCompatibility(bundleName, minimumNVDAVersion,
                                      lastTestedNVDAVersion):
                self.continueUpdatingAddons()
                return
            isDisabled = False
            # Optimization (future):
            # it is better to remove would-be add-ons all at once
            # instead of doing it each time a bundle is opened.
            for addon in addonHandler.getAvailableAddons():
                # Check for disabled state first.
                if bundleName == addon.manifest['name']:
                    if addon.isDisabled:
                        isDisabled = True
                    if not addon.isPendingRemove:
                        addon.requestRemove()
                    break
            progressDialog = gui.IndeterminateProgressDialog(
                gui.mainFrame,
                # Translators: The title of the dialog
                # presented while an Addon is being updated.
                makeAddonWindowTitle(_("Updating")),
                # Translators: The message displayed while an addon is being updated.
                _("Please wait while the add-on is being updated."))
            try:
                if self.autoUpdate:
                    extraAppArgs = globalVars.appArgsExtra if hasattr(
                        globalVars,
                        "appArgsExtra") else globalVars.unknownAppArgs
                    extraAppArgs.append("addon-auto-update")
                gui.ExecAndPump(addonHandler.installAddonBundle, bundle)
                if self.autoUpdate:
                    extraAppArgs.remove("addon-auto-update")
            except Exception:
                if self.autoUpdate:
                    extraAppArgs.remove("addon-auto-update")
                log.error("Error installing addon bundle from %s" %
                          self.destPath,
                          exc_info=True)
                progressDialog.done()
                gui.messageBox(
                    # Translators: The message displayed when an error occurs
                    # when installing an add-on package.
                    _("Failed to update {name} add-on").format(
                        name=self.addonName),
                    makeAddonWindowTitle(NVDAString("Error")),
                    wx.OK | wx.ICON_ERROR)
                self.continueUpdatingAddons()
                return
            else:
                progressDialog.done()
                self.addonHasBeenUpdated = True
                if isDisabled:
                    for addon in addonHandler.getAvailableAddons():
                        if bundleName == addon.manifest[
                                'name'] and addon.isPendingInstall:
                            addon.enable(False)
                            break
        finally:
            try:
                os.remove(self.destPath)
            except OSError:
                pass
            if self.addonHasBeenUpdated:
                if gui.messageBox(
                        NVDAString(
                            "Changes were made to add-ons. "
                            "You must restart NVDA for these changes to take effect. Would you like to restart now?"
                        ), NVDAString("Restart NVDA"),
                        wx.YES | wx.NO | wx.ICON_WARNING) == wx.YES:
                    wx.CallAfter(core.restart)
                return
        self.continueUpdatingAddons()
Esempio n. 17
0
 def _downloadSuccess(self):
     self._stopped()
     try:
         try:
             bundle = addonHandler.AddonBundle(self.destPath.decode("mbcs"))
         except AttributeError:
             bundle = addonHandler.AddonBundle(self.destPath)
         except:
             log.error("Error opening addon bundle from %s" % self.destPath,
                       exc_info=True)
             # Translators: The message displayed when an error occurs when trying to update an add-on package due to package problems.
             gui.messageBox(
                 _("Cannot update {name} - missing file or invalid file format"
                   ).format(name=self.addonName), translate("Error"),
                 wx.OK | wx.ICON_ERROR)
             self.continueUpdatingAddons()
             return
         # Check compatibility with NVDA and/or Windows release.
         import versionInfo
         minimumNVDAVersion = bundle.manifest.get("minimumNVDAVersion",
                                                  None)
         if minimumNVDAVersion is None:
             minimumNVDAVersion = [
                 versionInfo.version_year, versionInfo.version_major
             ]
         lastTestedNVDAVersion = bundle.manifest.get(
             "lastTestedNVDAVersion", None)
         if lastTestedNVDAVersion is None:
             lastTestedNVDAVersion = [
                 versionInfo.version_year, versionInfo.version_major
             ]
         # For NVDA version, only version_year.version_major will be checked.
         minimumYear, minimumMajor = minimumNVDAVersion[:2]
         lastTestedYear, lastTestedMajor = lastTestedNVDAVersion[:2]
         if not ((minimumYear, minimumMajor) <=
                 (versionInfo.version_year, versionInfo.version_major) <=
                 (lastTestedYear, lastTestedMajor)):
             # Translators: The message displayed when trying to update an add-on that is not going to be compatible with the current version of NVDA.
             gui.messageBox(
                 _("{name} add-on is not compatible with this version of NVDA. Minimum NVDA version: {minYear}.{minMajor}, last tested: {testedYear}.{testedMajor}."
                   ).format(name=self.addonName,
                            minYear=minimumYear,
                            minMajor=minimumMajor,
                            testedYear=lastTestedYear,
                            testedMajor=lastTestedMajor),
                 translate("Error"), wx.OK | wx.ICON_ERROR)
             self.continueUpdatingAddons()
             return
         # Some add-ons require a specific Windows release or later.
         import winVersion
         minimumWindowsVersion = bundle.manifest.get(
             "minimumWindowsVersion", None)
         if minimumWindowsVersion is None:
             minimumWindowsVersion = winVersion.winVersion[:3]
         else:
             minimumWindowsVersion = [
                 int(data) for data in minimumWindowsVersion.split(".")
             ]
         minimumWinMajor, minimumWinMinor, minimumWinBuild = minimumWindowsVersion
         winMajor, winMinor, winBuild = winVersion.winVersion[:3]
         if (winMajor, winMinor, winBuild) < (
                 minimumWinMajor, minimumWinMinor, minimumWinBuild):
             # Translators: The message displayed when the add-on requires a newer version of Windows.
             gui.messageBox(
                 _("{name} add-on is not compatible with this version of Windows."
                   ).format(name=self.addonName), translate("Error"),
                 wx.OK | wx.ICON_ERROR)
             self.continueUpdatingAddons()
             return
         bundleName = bundle.manifest['name']
         isDisabled = False
         # Optimization (future): it is better to remove would-be add-ons all at once instead of doing it each time a bundle is opened.
         for addon in addonHandler.getAvailableAddons():
             # Check for disabled state first.
             if bundleName == addon.manifest['name']:
                 if addon.isDisabled:
                     isDisabled = True
                 if not addon.isPendingRemove:
                     addon.requestRemove()
                 break
         progressDialog = gui.IndeterminateProgressDialog(
             gui.mainFrame,
             # Translators: The title of the dialog presented while an Addon is being updated.
             _("Updating {name}").format(name=self.addonName),
             # Translators: The message displayed while an addon is being updated.
             _("Please wait while the add-on is being updated."))
         try:
             gui.ExecAndPump(addonHandler.installAddonBundle, bundle)
         except:
             log.error("Error installing  addon bundle from %s" %
                       self.destPath,
                       exc_info=True)
             progressDialog.done()
             progressDialog.Hide()
             progressDialog.Destroy()
             # Translators: The message displayed when an error occurs when installing an add-on package.
             gui.messageBox(
                 _("Failed to update {name} add-on").format(
                     name=self.addonName), translate("Error"),
                 wx.OK | wx.ICON_ERROR)
             self.continueUpdatingAddons()
             return
         else:
             progressDialog.done()
             progressDialog.Hide()
             progressDialog.Destroy()
             _updatedAddons.append(bundleName)
             if isDisabled:
                 for addon in addonHandler.getAvailableAddons():
                     if bundleName == addon.manifest[
                             'name'] and addon.isPendingInstall:
                         addon.enable(False)
                         break
     finally:
         try:
             os.remove(self.destPath)
         except OSError:
             pass
     self.continueUpdatingAddons()
Esempio n. 18
0
 def _downloadSuccess(self):
     self._stopped()
     # Emulate add-on update (don't prompt to install).
     from gui import addonGui
     closeAfter = addonGui.AddonsDialog._instance is None
     try:
         try:
             bundle = addonHandler.AddonBundle(self.destPath.decode("mbcs"))
         except:
             log.error("Error opening addon bundle from %s" % self.destPath,
                       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"
                   ) % self.destPath,
                 # Translators: The title of a dialog presented when an error occurs.
                 _("Error"),
                 wx.OK | wx.ICON_ERROR)
             return
         bundleName = bundle.manifest['name']
         for addon in addonHandler.getAvailableAddons():
             if not addon.isPendingRemove and bundleName == addon.manifest[
                     'name']:
                 addon.requestRemove()
                 break
         progressDialog = gui.IndeterminateProgressDialog(
             gui.mainFrame,
             # Translators: The title of the dialog presented while an Addon is being updated.
             _("Updating Add-on"),
             # Translators: The message displayed while an addon is being updated.
             _("Please wait while the add-on is being updated."))
         try:
             gui.ExecAndPump(addonHandler.installAddonBundle, bundle)
         except:
             log.error("Error installing  addon bundle from %s" %
                       self.destPath,
                       exc_info=True)
             if not closeAfter:
                 addonGui.AddonsDialog(gui.mainFrame).refreshAddonsList()
             progressDialog.done()
             del progressDialog
             # Translators: The message displayed when an error occurs when installing an add-on package.
             gui.messageBox(
                 _("Failed to update add-on  from %s") % self.destPath,
                 # Translators: The title of a dialog presented when an error occurs.
                 _("Error"),
                 wx.OK | wx.ICON_ERROR)
             return
         else:
             if not closeAfter:
                 addonGui.AddonsDialog(
                     gui.mainFrame).refreshAddonsList(activeIndex=-1)
             progressDialog.done()
             del progressDialog
     finally:
         try:
             os.remove(self.destPath)
         except OSError:
             pass
         if closeAfter:
             wx.CallLater(1, addonGui.AddonsDialog(gui.mainFrame).Close)
Esempio n. 19
0
def installAddon(parentWindow, addonPath):
    """ Installs the addon at path. Any error messages / warnings are presented to the user via a GUI message box.
	If attempting to install an addon that is pending removal, it will no longer be pending removal.
	:return True on success or False on failure.
	"""
    try:
        bundle = addonHandler.AddonBundle(addonPath)
    except:
        log.error("Error opening addon bundle from %s" % addonPath,
                  exc_info=True)
        gui.messageBox(
            # Translators: The message displayed when an error occurs when opening an add-on package for adding.
            _("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 False  # Exit early, can't install an invalid bundle

    if not addonVersionCheck.hasAddonGotRequiredSupport(bundle):
        _showAddonRequiresNVDAUpdateDialog(parentWindow, bundle)
        return False  # Exit early, addon does not have required support
    elif not addonVersionCheck.isAddonTested(bundle):
        _showAddonTooOldDialog(parentWindow, bundle)
        return False  # Exit early, addon is not up to date with the latest API version.
    elif wx.YES != _showConfirmAddonInstallDialog(parentWindow, bundle):
        return False  # Exit early, User changed their mind about installation.

    prevAddon = None
    for addon in addonHandler.getAvailableAddons():
        if not addon.isPendingRemove and bundle.name == addon.manifest['name']:
            prevAddon = addon
            break
    if prevAddon:
        summary = bundle.manifest["summary"]
        curVersion = prevAddon.manifest["version"]
        newVersion = bundle.manifest["version"]

        # Translators: A title for the dialog asking if the user wishes to update a previously installed
        # add-on with this one.
        messageBoxTitle = _("Add-on Installation")

        # Translators: A message asking if the user wishes to update an add-on with the same version
        # currently installed according to the version number.
        overwriteExistingAddonInstallationMessage = _(
            "You are about to install version {newVersion} of {summary}, which appears to be already installed. "
            "Would you still like to update?").format(summary=summary,
                                                      newVersion=newVersion)

        # Translators: A message asking if the user wishes to update a previously installed add-on with this one.
        updateAddonInstallationMessage = _(
            "A version of this add-on is already installed. "
            "Would you like to update {summary} version {curVersion} to version {newVersion}?"
        ).format(summary=summary, curVersion=curVersion, newVersion=newVersion)

        if gui.messageBox(
                overwriteExistingAddonInstallationMessage if curVersion
                == newVersion else updateAddonInstallationMessage,
                messageBoxTitle, wx.YES | wx.NO | wx.ICON_WARNING) != wx.YES:
            return False
        prevAddon.requestRemove()

    from contextlib import contextmanager

    @contextmanager
    def doneAndDestroy(window):
        try:
            yield window
        except:
            # pass on any exceptions
            raise
        finally:
            # but ensure that done and Destroy are called.
            window.done()
            window.Destroy()

    #  use a progress dialog so users know that something is happening.
    progressDialog = gui.IndeterminateProgressDialog(
        parentWindow,
        # 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:
        # Use context manager to ensure that `done` and `Destroy` are called on the progress dialog afterwards
        with doneAndDestroy(progressDialog):
            gui.ExecAndPump(addonHandler.installAddonBundle, bundle)
            return True
    except:
        log.error("Error installing  addon bundle from %s" % addonPath,
                  exc_info=True)
        gui.messageBox(
            # Translators: The message displayed when an error occurs when installing an add-on package.
            _("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 False
Esempio n. 20
0
 def _downloadSuccess(self):
     self._stopped()
     try:
         try:
             bundle = addonHandler.AddonBundle(self.destPath)
         except:
             log.error(f"Error opening addon bundle from {self.destPath}",
                       exc_info=True)
             gui.messageBox(
                 # Translators: The message displayed when an error occurs
                 # when trying to update an add-on package due to package problems.
                 _("Cannot update {name} - missing file or invalid file format"
                   ).format(name=self.addonName),
                 translate("Error"),
                 wx.OK | wx.ICON_ERROR)
             self.continueUpdatingAddons()
             return
         # Check compatibility with NVDA and/or Windows release.
         # NVDA itself will check add-on compatibility range.
         # As such, the below fragment was borrowed from NVDA Core (credit: NV Access).
         from addonHandler import addonVersionCheck
         from gui import addonGui
         # Check compatibility with NVDA and/or Windows release.
         if not addonVersionCheck.hasAddonGotRequiredSupport(bundle):
             addonGui._showAddonRequiresNVDAUpdateDialog(
                 gui.mainFrame, bundle)
             self.continueUpdatingAddons()
             return
         elif not addonVersionCheck.isAddonTested(bundle):
             addonGui._showAddonTooOldDialog(gui.mainFrame, bundle)
             self.continueUpdatingAddons()
             return
         # Some add-ons require a specific Windows release or later.
         # Prepare for winVersion.getWinVer function.
         import winVersion
         minimumWindowsVersion = bundle.manifest.get(
             "minimumWindowsVersion", None)
         if hasattr(winVersion, "getWinVer"):
             if minimumWindowsVersion is None:
                 minimumWindowsVersion = winVersion.getWinVer()
             else:
                 minimumWindowsVersion = winVersion.WinVersion.fromVersionText(
                     minimumWindowsVersion)
             winVersionUnsupported = winVersion.getWinVer(
             ) < minimumWindowsVersion
         else:
             if minimumWindowsVersion is None:
                 minimumWindowsVersion = winVersion.winVersion[:3]
             else:
                 minimumWindowsVersion = [
                     int(data) for data in minimumWindowsVersion.split(".")
                 ]
             minimumWinMajor, minimumWinMinor, minimumWinBuild = minimumWindowsVersion
             winMajor, winMinor, winBuild = winVersion.winVersion[:3]
             winVersionUnsupported = (winMajor, winMinor, winBuild) < (
                 minimumWinMajor, minimumWinMinor, minimumWinBuild)
         if winVersionUnsupported:
             gui.messageBox(
                 # Translators: The message displayed when the add-on requires a newer version of Windows.
                 _("{name} add-on is not compatible with this version of Windows."
                   ).format(name=self.addonName),
                 translate("Error"),
                 wx.OK | wx.ICON_ERROR)
             self.continueUpdatingAddons()
             return
         bundleName = bundle.manifest['name']
         isDisabled = False
         # Optimization (future): it is better to remove would-be add-ons all at once
         # instead of doing it each time a bundle is opened.
         for addon in addonHandler.getAvailableAddons():
             # Check for disabled state first.
             if bundleName == addon.manifest['name']:
                 if addon.isDisabled:
                     isDisabled = True
                 if not addon.isPendingRemove:
                     addon.requestRemove()
                 break
         progressDialog = gui.IndeterminateProgressDialog(
             gui.mainFrame,
             # Translators: The title of the dialog presented while an Addon is being updated.
             _("Updating {name}").format(name=self.addonName),
             # Translators: The message displayed while an addon is being updated.
             _("Please wait while the add-on is being updated."))
         try:
             gui.ExecAndPump(addonHandler.installAddonBundle, bundle)
         except:
             log.error(
                 f"Error installing  addon bundle from {self.destPath}",
                 exc_info=True)
             progressDialog.done()
             progressDialog.Hide()
             progressDialog.Destroy()
             gui.messageBox(
                 # Translators: The message displayed when an error occurs when installing an add-on package.
                 _("Failed to update {name} add-on").format(
                     name=self.addonName),
                 translate("Error"),
                 wx.OK | wx.ICON_ERROR)
             self.continueUpdatingAddons()
             return
         else:
             progressDialog.done()
             progressDialog.Hide()
             progressDialog.Destroy()
             _updatedAddons.append(bundleName)
             if isDisabled:
                 for addon in addonHandler.getAvailableAddons():
                     if bundleName == addon.manifest[
                             'name'] and addon.isPendingInstall:
                         addon.enable(False)
                         break
     finally:
         try:
             os.remove(self.destPath)
         except OSError:
             pass
     self.continueUpdatingAddons()