Skip to content

Commit dac694c

Browse files
authored
Merge 04c92d2 into 9fb9559
2 parents 9fb9559 + 04c92d2 commit dac694c

7 files changed

Lines changed: 62 additions & 23 deletions

File tree

source/gui/_addonStoreGui/controls/messageDialogs.py

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
ButtonHelper,
2525
SPACE_BETWEEN_VERTICAL_DIALOG_ITEMS,
2626
)
27-
from gui.message import messageBox
27+
from gui.message import displayDialogAsModal, messageBox
2828
import windowUtils
2929

3030
if TYPE_CHECKING:
@@ -81,13 +81,14 @@ def _shouldProceedWhenInstalledAddonVersionUnknown(
8181
lastTestedNVDAVersion=addonAPIVersion.formatForGUI(addon.lastTestedNVDAVersion),
8282
NVDAVersion=addonAPIVersion.formatForGUI(addonAPIVersion.CURRENT)
8383
)
84-
return ErrorAddonInstallDialogWithYesNoButtons(
84+
res = displayDialogAsModal(ErrorAddonInstallDialogWithYesNoButtons(
8585
parent=parent,
8686
# Translators: The title of a dialog presented when an error occurs.
8787
title=pgettext("addonStore", "Add-on not compatible"),
8888
message=incompatibleMessage,
8989
showAddonInfoFunction=lambda: _showAddonInfo(addon)
90-
).ShowModal() == wx.YES
90+
))
91+
return res == wx.YES
9192

9293

9394
def _shouldProceedToRemoveAddonDialog(
@@ -127,13 +128,14 @@ def _shouldInstallWhenAddonTooOldDialog(
127128
lastTestedNVDAVersion=addonAPIVersion.formatForGUI(addon.lastTestedNVDAVersion),
128129
NVDAVersion=addonAPIVersion.formatForGUI(addonAPIVersion.CURRENT)
129130
)
130-
return ErrorAddonInstallDialogWithYesNoButtons(
131+
res = displayDialogAsModal(ErrorAddonInstallDialogWithYesNoButtons(
131132
parent=parent,
132133
# Translators: The title of a dialog presented when an error occurs.
133134
title=pgettext("addonStore", "Add-on not compatible"),
134135
message=incompatibleMessage,
135136
showAddonInfoFunction=lambda: _showAddonInfo(addon)
136-
).ShowModal() == wx.YES
137+
))
138+
return res == wx.YES
137139

138140

139141
def _shouldEnableWhenAddonTooOldDialog(
@@ -156,13 +158,14 @@ def _shouldEnableWhenAddonTooOldDialog(
156158
lastTestedNVDAVersion=addonAPIVersion.formatForGUI(addon.lastTestedNVDAVersion),
157159
NVDAVersion=addonAPIVersion.formatForGUI(addonAPIVersion.CURRENT)
158160
)
159-
return ErrorAddonInstallDialogWithYesNoButtons(
161+
res = displayDialogAsModal(ErrorAddonInstallDialogWithYesNoButtons(
160162
parent=parent,
161163
# Translators: The title of a dialog presented when an error occurs.
162164
title=pgettext("addonStore", "Add-on not compatible"),
163165
message=incompatibleMessage,
164166
showAddonInfoFunction=lambda: _showAddonInfo(addon)
165-
).ShowModal() == wx.YES
167+
))
168+
return res == wx.YES
166169

167170

168171
def _showAddonInfo(addon: _AddonGUIModel) -> None:

source/gui/_addonStoreGui/controls/storeDialog.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
guiHelper,
2929
addonGui,
3030
)
31-
from gui.message import DisplayableError
31+
from gui.message import DisplayableError, displayDialogAsModal
3232
from gui.settingsDialogs import SettingsDialog
3333
from logHandler import log
3434

@@ -53,7 +53,7 @@ def __init__(self, parent: wx.Window, storeVM: AddonStoreVM):
5353
self._actionsContextMenu = _ActionsContextMenu(self._storeVM)
5454
super().__init__(parent, resizeable=True, buttons={wx.CLOSE})
5555
if config.conf["addonStore"]["showWarning"]:
56-
_SafetyWarningDialog(parent).ShowModal()
56+
displayDialogAsModal(_SafetyWarningDialog(parent))
5757
self.Maximize()
5858

5959
def _enterActivatesOk_ctrlSActivatesApply(self, evt: wx.KeyEvent):
@@ -367,7 +367,7 @@ def openExternalInstall(self, evt: wx.EVT_BUTTON):
367367
defaultDir="c:",
368368
style=wx.FD_OPEN,
369369
)
370-
if fd.ShowModal() != wx.ID_OK:
370+
if displayDialogAsModal(fd) != wx.ID_OK:
371371
return
372372
addonPath = fd.GetPath()
373373
try:

source/gui/addonGui.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import globalVars
2424
from . import guiHelper
2525
from . import nvdaControls
26+
from .message import displayDialogAsModal
2627
from .dpiScalingHelper import DpiScalingHelperMixinWithoutInit
2728
import gui.contextHelp
2829

@@ -269,7 +270,7 @@ def onAddClick(self, evt: wx.EVT_BUTTON):
269270
# Translators: the label for the NVDA add-on package file type in the Choose add-on dialog.
270271
wildcard=(_("NVDA Add-on Package (*.{ext})")+"|*.{ext}").format(ext=addonHandler.BUNDLE_EXTENSION),
271272
defaultDir="c:", style=wx.FD_OPEN)
272-
if fd.ShowModal() != wx.ID_OK:
273+
if displayDialogAsModal(fd) != wx.ID_OK:
273274
return
274275
addonPath = fd.GetPath()
275276
if installAddon(self, addonPath):
@@ -446,10 +447,10 @@ def onGetAddonsClick(self, evt):
446447
os.startfile(ADDONS_URL)
447448

448449
def onIncompatAddonsShowClick(self, evt):
449-
IncompatibleAddonsDialog(
450+
displayDialogAsModal(IncompatibleAddonsDialog(
450451
parent=self,
451452
# the defaults from the addon GUI are fine. We are testing against the running version.
452-
).ShowModal()
453+
))
453454

454455

455456
# C901 'installAddon' is too complex (16)
@@ -601,13 +602,13 @@ def _showAddonRequiresNVDAUpdateDialog(
601602
NVDAVersion=addonAPIVersion.formatForGUI(addonAPIVersion.CURRENT)
602603
)
603604
from gui._addonStoreGui.controls.messageDialogs import _showAddonInfo
604-
ErrorAddonInstallDialog(
605+
displayDialogAsModal(ErrorAddonInstallDialog(
605606
parent=parent,
606607
# Translators: The title of a dialog presented when an error occurs.
607608
title=_("Add-on not compatible"),
608609
message=incompatibleMessage,
609610
showAddonInfoFunction=lambda: _showAddonInfo(bundle._addonGuiModel)
610-
).ShowModal()
611+
))
611612

612613

613614
def _showConfirmAddonInstallDialog(
@@ -622,13 +623,13 @@ def _showConfirmAddonInstallDialog(
622623
).format(**bundle.manifest)
623624

624625
from gui._addonStoreGui.controls.messageDialogs import _showAddonInfo
625-
return ConfirmAddonInstallDialog(
626+
return displayDialogAsModal(ConfirmAddonInstallDialog(
626627
parent=parent,
627628
# Translators: Title for message asking if the user really wishes to install an Addon.
628629
title=_("Add-on Installation"),
629630
message=confirmInstallMessage,
630631
showAddonInfoFunction=lambda: _showAddonInfo(bundle._addonGuiModel)
631-
).ShowModal()
632+
))
632633

633634

634635
class IncompatibleAddonsDialog(

source/gui/exit.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# A part of NonVisual Desktop Access (NVDA)
2-
# Copyright (C) 2006-2022 NV Access Limited, Peter Vágner, Aleksey Sadovoy, Mesar Hameed, Joseph Lee,
2+
# Copyright (C) 2006-2023 NV Access Limited, Peter Vágner, Aleksey Sadovoy, Mesar Hameed, Joseph Lee,
33
# Thomas Stivers, Babbage B.V., Accessolutions, Julien Cochuyt, Cyrille Bougot
44
# This file may be used under the terms of the GNU General Public License, version 2 or later.
55
# For more details see: https://www.gnu.org/licenses/gpl-2.0.html
@@ -18,6 +18,7 @@
1818
import wx
1919

2020
from . import guiHelper
21+
from .message import displayDialogAsModal
2122
from .startupDialogs import WelcomeDialog
2223

2324

@@ -150,7 +151,7 @@ def onOk(self, evt):
150151
apiVersion=apiVersion,
151152
backCompatTo=backCompatTo
152153
)
153-
confirmUpdateDialog.ShowModal()
154+
displayDialogAsModal(confirmUpdateDialog)
154155
else:
155156
updateCheck.executePendingUpdate()
156157
wx.CallAfter(self.Destroy)

source/gui/installerGui.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
import os
88

9-
import shellapi
109
import winUser
1110
import wx
1211
import config
@@ -20,6 +19,7 @@
2019
from gui.dpiScalingHelper import DpiScalingHelperMixinWithoutInit
2120
import systemUtils
2221
from NVDAState import WritePaths
22+
from .message import displayDialogAsModal
2323

2424

2525
def _canPortableConfigBeCopied() -> bool:
@@ -274,7 +274,7 @@ def onReviewAddons(self, evt):
274274
parent=self,
275275
# the defaults from the installer are fine. We are testing against the running version.
276276
)
277-
incompatibleAddons.ShowModal()
277+
displayDialogAsModal(incompatibleAddons)
278278

279279

280280
class InstallingOverNewerVersionDialog(

source/gui/message.py

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,39 @@ def isModalMessageBoxActive() -> bool:
3636
return _messageBoxCounter != 0
3737

3838

39+
def displayDialogAsModal(dialog: wx.Dialog) -> int:
40+
"""Display a dialog as modal.
41+
@return: Same as for wx.MessageBox.
42+
43+
`displayDialogAsModal` is a function which blocks the calling thread,
44+
until a user responds to the modal dialog.
45+
This function should be used when an answer is required before proceeding.
46+
47+
It's possible for multiple message boxes to be open at a time.
48+
Before opening a new messageBox, use `isModalMessageBoxActive`
49+
to check if another messageBox modal response is still pending.
50+
51+
Because an answer is required to continue after a modal messageBox is opened,
52+
some actions such as shutting down are prevented while NVDA is in a possibly uncertain state.
53+
"""
54+
from gui import mainFrame
55+
global _messageBoxCounter
56+
with _messageBoxCounterLock:
57+
_messageBoxCounter += 1
58+
59+
try:
60+
if not dialog.GetParent():
61+
mainFrame.prePopup()
62+
res = dialog.ShowModal()
63+
finally:
64+
if not dialog.GetParent():
65+
mainFrame.postPopup()
66+
with _messageBoxCounterLock:
67+
_messageBoxCounter -= 1
68+
69+
return res
70+
71+
3972
def messageBox(
4073
message: str,
4174
caption: str = wx.MessageBoxCaptionStr,

source/updateCheck.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import braille
4949
import gui
5050
from gui import guiHelper
51+
from gui.message import displayDialogAsModal # noqa: E402
5152
from addonHandler import getCodeAddon, AddonError, getIncompatibleAddons
5253
from _addonStore.models.version import ( # noqa: E402
5354
getAddonCompatibilityMessage,
@@ -464,7 +465,7 @@ def onReviewAddonsButton(self, evt):
464465
APIVersion=self.apiVersion,
465466
APIBackwardsCompatToVersion=self.backCompatTo
466467
)
467-
incompatibleAddons.ShowModal()
468+
displayDialogAsModal(incompatibleAddons)
468469

469470

470471
class UpdateAskInstallDialog(
@@ -540,7 +541,7 @@ def onReviewAddonsButton(self, evt):
540541
APIVersion=self.apiVersion,
541542
APIBackwardsCompatToVersion=self.backCompatTo
542543
)
543-
incompatibleAddons.ShowModal()
544+
displayDialogAsModal(incompatibleAddons)
544545

545546
def onInstallButton(self, evt):
546547
_executeUpdate(self.destPath)

0 commit comments

Comments
 (0)