diff --git a/source/gui/addonStoreGui/controls/actions.py b/source/gui/addonStoreGui/controls/actions.py index a712c428625..527355ad43e 100644 --- a/source/gui/addonStoreGui/controls/actions.py +++ b/source/gui/addonStoreGui/controls/actions.py @@ -154,6 +154,13 @@ def _actions(self) -> List[BatchAddonActionVM]: validCheck=lambda aVMs: AddonListValidator(aVMs).canUseUpdateAction(), actionTarget=self._selectedAddons, ), + BatchAddonActionVM( + # Translators: Label for an action that retries the selected add-ons + displayName=pgettext("addonStore", "Re&try installing selected add-ons"), + actionHandler=self._storeVM.getAddons, + validCheck=lambda aVMs: AddonListValidator(aVMs).canUseRetryAction(), + actionTarget=self._selectedAddons, + ), BatchAddonActionVM( # Translators: Label for an action that cancel install of the selected add-ons displayName=pgettext("addonStore", "Ca&ncel install of selected add-ons"), @@ -218,6 +225,9 @@ def canUseUpdateAction(self) -> bool: hasInstallable = True return hasUpdatable and not hasInstallable + def canUseRetryAction(self) -> bool: + return any(aVM.canUseRetryAction() for aVM in self.addonsList) + def canUseCancelInstallAction(self) -> bool: for aVM in self.addonsList: if aVM.canUseCancelInstallAction(): diff --git a/source/gui/addonStoreGui/viewModels/addonList.py b/source/gui/addonStoreGui/viewModels/addonList.py index fb2d41aa352..ef0cc5028b7 100644 --- a/source/gui/addonStoreGui/viewModels/addonList.py +++ b/source/gui/addonStoreGui/viewModels/addonList.py @@ -140,6 +140,9 @@ def canUseUpdateOverrideIncompatibilityAction(self) -> bool: def canUseReplaceAction(self) -> bool: return self.status == AvailableAddonStatus.REPLACE_SIDE_LOAD + def canUseRetryAction(self) -> bool: + return self.status in {AvailableAddonStatus.DOWNLOAD_FAILED, AvailableAddonStatus.INSTALL_FAILED} + def canUseCancelInstallAction(self) -> bool: return self.status in (AvailableAddonStatus.DOWNLOADING, AvailableAddonStatus.DOWNLOAD_SUCCESS) diff --git a/source/gui/addonStoreGui/viewModels/store.py b/source/gui/addonStoreGui/viewModels/store.py index 759be36fc59..99f804a8f22 100644 --- a/source/gui/addonStoreGui/viewModels/store.py +++ b/source/gui/addonStoreGui/viewModels/store.py @@ -140,6 +140,13 @@ def _makeActionsList(self): validCheck=lambda aVM: aVM.canUseUpdateOverrideIncompatibilityAction(), actionTarget=selectedListItem, ), + AddonActionVM( + # Translators: Label for an action that retries the selected addon + displayName=pgettext("addonStore", "Re&try install"), + actionHandler=self.getAddon, + validCheck=lambda aVM: aVM.canUseRetryAction(), + actionTarget=selectedListItem, + ), AddonActionVM( # Translators: Label for an action that replaces the selected addon with # an add-on store version. @@ -671,6 +678,9 @@ def cancelInstallForAddon(self, listItemVM: AddonListItemVM[_AddonStoreModel]): self._cancelPendingInstallForAddon(listItemVM) log.debug(f"Completed cancelling install of {listItemVM.Id}") + addonHandler.state[addonHandler.AddonStateCategory.PENDING_OVERRIDE_COMPATIBILITY].discard( + listItemVM.model.name, + ) listItemVM.status = getStatus(listItemVM.model, self._filteredStatusKey) def cancelInstallForAddons(self, listItemVMs: Iterable[AddonListItemVM[_AddonStoreModel]]): diff --git a/user_docs/en/changes.md b/user_docs/en/changes.md index ba47ed3f1f2..f81ba99f7ed 100644 --- a/user_docs/en/changes.md +++ b/user_docs/en/changes.md @@ -13,12 +13,13 @@ In order to use this feature, the application volume adjuster needs to be enable * In Mozilla Firefox, NVDA will report the highlighted text when a URL containing a text fragment is visited. (#16910, @jcsteh) * NVDA can now report when a link destination points to the current page. (#141, @LeonarddeR, @nvdaes) * Added an action in the Add-on Store to cancel the install of add-ons. (#15578, @hwf1324) +* Added an action in the Add-on Store to retry the installation if the download/installation of an add-on fails. (#17090, @hwf1324) * It is now possible to specify a mirror URL to use for the Add-on Store. (#14974) ### Changes * The Report link destination, Character formatting information, and Speak selection dialogs, now include "Close" and "Copy" buttons for user convenience. (#17018, @XLTechie) -* The exit dialog now allows you to restart NVDA with add-ons disabled and debug logging enabled simultaneously. (#11538, @CyrilleB79)r +* The exit dialog now allows you to restart NVDA with add-ons disabled and debug logging enabled simultaneously. (#11538, @CyrilleB79) * Unicode Normalization is now enabled by default for speech output. (#17017, @LeonarddeR). * You can still disable this functionality in the Speech category of the NVDA Settings dialog. diff --git a/user_docs/en/userGuide.md b/user_docs/en/userGuide.md index d018475a2f3..0646220df45 100644 --- a/user_docs/en/userGuide.md +++ b/user_docs/en/userGuide.md @@ -3653,6 +3653,7 @@ This could include accessing your personal data or even the entire system. You can install and update add-ons by [browsing Available add-ons](#AddonStoreBrowsing). Select an add-on from the "Available add-ons" or "Updatable add-ons" tab. Then use the update, install, or replace action to start the installation. +If the download or installation fails you can retry the installation. It is also possible to cancel the install before exiting the Add-on Store. You can also install multiple add-ons at once.