Skip to content

Commit d41062b

Browse files
authored
Merge cf0cc6b into 5c30524
2 parents 5c30524 + cf0cc6b commit d41062b

6 files changed

Lines changed: 66 additions & 1 deletion

File tree

source/addonStore/network.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
_AddonStoreModel,
3434
)
3535
from .models.channel import Channel
36+
from .models.status import AvailableAddonStatus
3637

3738

3839
if TYPE_CHECKING:
@@ -109,7 +110,11 @@ def download(
109110
f.add_done_callback(self._done)
110111

111112
def _done(self, downloadAddonFuture: Future[Optional[os.PathLike]]):
112-
isCancelled = downloadAddonFuture.cancelled() or downloadAddonFuture not in self._pending
113+
isCancelled = (
114+
downloadAddonFuture.cancelled()
115+
or downloadAddonFuture not in self._pending
116+
or self._pending[downloadAddonFuture][0].status != AvailableAddonStatus.DOWNLOADING
117+
)
113118
addonId = "CANCELLED" if isCancelled else self._pending[downloadAddonFuture][0].model.addonId
114119
log.debug(f"Done called for {addonId}")
115120

source/gui/addonStoreGui/controls/actions.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,13 @@ def _actions(self) -> List[BatchAddonActionVM]:
153153
validCheck=lambda aVMs: AddonListValidator(aVMs).canUseUpdateAction(),
154154
actionTarget=self._selectedAddons
155155
),
156+
BatchAddonActionVM(
157+
# Translators: Label for an action that cancel install of the selected add-ons
158+
displayName=pgettext("addonStore", "Ca&ncel install of selected add-ons"),
159+
actionHandler=self._storeVM.cancelInstallAddons,
160+
validCheck=lambda aVMs: AddonListValidator(aVMs).canUseCancelInstallAction(),
161+
actionTarget=self._selectedAddons
162+
),
156163
BatchAddonActionVM(
157164
# Translators: Label for an action that removes the selected add-ons
158165
displayName=pgettext("addonStore", "&Remove selected add-ons"),
@@ -209,6 +216,12 @@ def canUseUpdateAction(self) -> bool:
209216
hasInstallable = True
210217
return hasUpdatable and not hasInstallable
211218

219+
def canUseCancelInstallAction(self) -> bool:
220+
for aVM in self.addonsList:
221+
if aVM.canUseCancelInstallAction():
222+
return True
223+
return False
224+
212225
def canUseRemoveAction(self) -> bool:
213226
for aVM in self.addonsList:
214227
if aVM.canUseRemoveAction():

source/gui/addonStoreGui/viewModels/addonList.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,12 @@ def canUseUpdateOverrideIncompatibilityAction(self) -> bool:
140140
def canUseReplaceAction(self) -> bool:
141141
return self.status == AvailableAddonStatus.REPLACE_SIDE_LOAD
142142

143+
def canUseCancelInstallAction(self) -> bool:
144+
return self.status in (
145+
AvailableAddonStatus.DOWNLOADING,
146+
AvailableAddonStatus.DOWNLOAD_SUCCESS
147+
)
148+
143149
def canUseRemoveAction(self) -> bool:
144150
return (
145151
self.model.isInstalled

source/gui/addonStoreGui/viewModels/store.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,13 @@ def _makeActionsList(self):
147147
validCheck=lambda aVM: aVM.canUseReplaceAction(),
148148
actionTarget=selectedListItem
149149
),
150+
AddonActionVM(
151+
# Translators: Label for an action that cancels the installation of the selected addon
152+
displayName=pgettext("addonStore", "Ca&ncel install"),
153+
actionHandler=self.cancelInstallAddon,
154+
validCheck=lambda aVM: aVM.canUseCancelInstallAction(),
155+
actionTarget=selectedListItem
156+
),
150157
AddonActionVM(
151158
# Translators: Label for an action that disables the selected addon
152159
displayName=pgettext("addonStore", "&Disable"),
@@ -604,6 +611,37 @@ def _getAvailableAddonsInBG(self):
604611
core.callLater(delay=0, callable=self.detailsVM.updated.notify, addonDetailsVM=self.detailsVM)
605612
log.debug("completed refresh")
606613

614+
def cancelInstallAddon(self, listItemVM: AddonListItemVM[_AddonStoreModel]):
615+
log.debug(f"Cancelling install of {listItemVM.Id}")
616+
617+
futuresCopy = self._downloader._pending.copy()
618+
try:
619+
addonDataManager._downloadsPendingCompletion.remove(listItemVM)
620+
for future, addon in futuresCopy.items():
621+
if listItemVM == addon[0] and not future.cancel():
622+
self._downloader.progress.pop(addon[0], None)
623+
listItemVM.status = getStatus(listItemVM.model, self._filteredStatusKey)
624+
return
625+
except KeyError:
626+
log.debug("Download already completed")
627+
628+
pendingInstallCopy = addonDataManager._downloadsPendingInstall.copy()
629+
for addonData, fileDownloaded in pendingInstallCopy:
630+
if addonData == listItemVM:
631+
addonDataManager._downloadsPendingInstall.remove((addonData, fileDownloaded))
632+
# Clean up download file
633+
try:
634+
os.remove(fileDownloaded)
635+
except FileNotFoundError:
636+
pass
637+
638+
listItemVM.status = getStatus(listItemVM.model, self._filteredStatusKey)
639+
640+
def cancelInstallAddons(self, listItemVMs: Iterable[AddonListItemVM[_AddonStoreModel]]):
641+
for aVM in listItemVMs:
642+
if aVM.canUseCancelInstallAction():
643+
self.cancelInstallAddon(aVM)
644+
607645
def cancelDownloads(self):
608646
while addonDataManager._downloadsPendingCompletion:
609647
listItem = addonDataManager._downloadsPendingCompletion.pop()

user_docs/en/changes.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ Unicode CLDR has been updated.
3232
* NVDA will now report figures with no accessible children, but with a label or description. (#14514)
3333
* When reading by line in browse mode, "caption" is no longer reported on each line of a long figure or table caption. (#14874)
3434
* In the Python console, the last unexecuted command will no longer be lost when moving in the input history. (#16653, @CyrilleB79)
35+
* Added an action in the add-on store's updatable/available add-ons list to cancel the install of just downloaded add-on(s). (#15578, @hwf1324)
36+
3537

3638
### Bug Fixes
3739
* Windows 11 fixes:

user_docs/en/userGuide.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3488,6 +3488,7 @@ This could include accessing your personal data or even the entire system.
34883488
You can install and update add-ons by [browsing Available add-ons](#AddonStoreBrowsing).
34893489
Select an add-on from the "Available add-ons" or "Updatable add-ons" tab.
34903490
Then use the update, install, or replace action to start the installation.
3491+
It is also possible to cancel the install just after the download.
34913492

34923493
You can also install multiple add-ons at once.
34933494
This can be done by selecting multiple add-ons in the available add-ons tab, then activating the context menu on the selection and choosing the "Install selected add-ons" action.

0 commit comments

Comments
 (0)