From b933d46dcdc2077174d5f049acab8f4f1dff312c Mon Sep 17 00:00:00 2001 From: Chris Hennes Date: Wed, 11 Jan 2023 21:55:37 -0600 Subject: [PATCH] Addon Manager: Set parent for most modals --- src/Mod/AddonManager/AddonManager.py | 1 + .../addonmanager_installer_gui.py | 19 +++++++++++-------- .../addonmanager_uninstaller_gui.py | 8 +++++--- .../addonmanager_update_all_gui.py | 1 + .../AddonManager/addonmanager_utilities.py | 17 +++++++++++++++++ 5 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/Mod/AddonManager/AddonManager.py b/src/Mod/AddonManager/AddonManager.py index 0554b3e787..6ad8778316 100644 --- a/src/Mod/AddonManager/AddonManager.py +++ b/src/Mod/AddonManager/AddonManager.py @@ -169,6 +169,7 @@ class CommandAddonManager: self.dialog = FreeCADGui.PySideUic.loadUi( os.path.join(os.path.dirname(__file__), "AddonManager.ui") ) + self.dialog.setObjectName("AddonManager_Main_Window") # self.dialog.setWindowFlag(QtCore.Qt.WindowStaysOnTopHint, True) # cleanup the leftovers from previous runs diff --git a/src/Mod/AddonManager/addonmanager_installer_gui.py b/src/Mod/AddonManager/addonmanager_installer_gui.py index 40f50fa6db..a75303b29f 100644 --- a/src/Mod/AddonManager/addonmanager_installer_gui.py +++ b/src/Mod/AddonManager/addonmanager_installer_gui.py @@ -159,7 +159,7 @@ class AddonInstallerGUI(QtCore.QObject): message += "" message += "To ignore this error and install anyway, press OK." r = QtWidgets.QMessageBox.critical( - None, + utils.get_main_am_window(), translate("AddonsInstaller", "Missing Requirement"), message, QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel, @@ -205,7 +205,7 @@ class AddonInstallerGUI(QtCore.QObject): message += "" message += translate("AddonsInstaller", "Press OK to install anyway.") r = QtWidgets.QMessageBox.critical( - None, + utils.get_main_am_window(), translate("AddonsInstaller", "Missing Requirement"), message, QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel, @@ -249,7 +249,7 @@ class AddonInstallerGUI(QtCore.QObject): if sys.version_info.minor < minor_required: # pylint: disable=line-too-long QtWidgets.QMessageBox.critical( - None, + utils.get_main_am_window(), translate("AddonsInstaller", "Incompatible Python version"), translate( "AddonsInstaller", @@ -326,6 +326,7 @@ class AddonInstallerGUI(QtCore.QObject): translate("AddonsInstaller", "Installing dependencies"), translate("AddonsInstaller", "Installing dependencies") + "...", QtWidgets.QMessageBox.Cancel, + parent=utils.get_main_am_window() ) self.dependency_installation_dialog.rejected.connect( self._cancel_dependency_installation @@ -345,7 +346,7 @@ class AddonInstallerGUI(QtCore.QObject): self.dependency_installation_dialog.hide() # pylint: disable=line-too-long result = QtWidgets.QMessageBox.critical( - None, + utils.get_main_am_window(), translate("AddonsInstaller", "Cannot execute Python"), translate( "AddonsInstaller", @@ -369,7 +370,7 @@ class AddonInstallerGUI(QtCore.QObject): self.dependency_installation_dialog.hide() # pylint: disable=line-too-long result = QtWidgets.QMessageBox.critical( - None, + utils.get_main_am_window(), translate("AddonsInstaller", "Cannot execute pip"), translate( "AddonsInstaller", @@ -397,7 +398,7 @@ class AddonInstallerGUI(QtCore.QObject): ) FreeCAD.Console.PrintError(details + "\n") result = QtWidgets.QMessageBox.critical( - None, + utils.get_main_am_window(), translate("AddonsInstaller", "Package installation failed"), short_message + "\n\n" @@ -449,6 +450,7 @@ class AddonInstallerGUI(QtCore.QObject): self.addon_to_install.display_name ), QtWidgets.QMessageBox.Cancel, + parent=utils.get_main_am_window() ) self.installing_dialog.rejected.connect(self._cancel_addon_installation) self.installer.finished.connect(self.installing_dialog.hide) @@ -462,6 +464,7 @@ class AddonInstallerGUI(QtCore.QObject): self.addon_to_install.display_name ), QtWidgets.QMessageBox.NoButton, + parent=utils.get_main_am_window() ) dlg.show() if self.worker_thread.isRunning(): @@ -483,7 +486,7 @@ class AddonInstallerGUI(QtCore.QObject): def _installation_succeeded(self): """Called if the installation was successful.""" QtWidgets.QMessageBox.information( - None, + utils.get_main_am_window(), translate("AddonsInstaller", "Success"), translate("AddonsInstaller", "{} was installed successfully").format( self.addon_to_install.name @@ -496,7 +499,7 @@ class AddonInstallerGUI(QtCore.QObject): def _installation_failed(self, addon, message): """Called if the installation failed.""" QtWidgets.QMessageBox.critical( - None, + utils.get_main_am_window(), translate("AddonsInstaller", "Installation Failed"), translate("AddonsInstaller", "Failed to install {}").format(addon.name) + "\n" diff --git a/src/Mod/AddonManager/addonmanager_uninstaller_gui.py b/src/Mod/AddonManager/addonmanager_uninstaller_gui.py index d76d2cd0b3..9f77488932 100644 --- a/src/Mod/AddonManager/addonmanager_uninstaller_gui.py +++ b/src/Mod/AddonManager/addonmanager_uninstaller_gui.py @@ -28,6 +28,7 @@ import FreeCADGui from PySide import QtCore, QtWidgets from addonmanager_uninstaller import AddonUninstaller, MacroUninstaller +import addonmanager_utilities as utils translate = FreeCAD.Qt.translate @@ -78,7 +79,7 @@ class AddonUninstallerGUI(QtCore.QObject): """Present a modal dialog asking the user if they really want to uninstall. Returns True to continue with the uninstallation, or False to stop the process.""" confirm = QtWidgets.QMessageBox.question( - None, + utils.get_main_am_window(), translate("AddonsInstaller", "Confirm remove"), translate( "AddonsInstaller", "Are you sure you want to uninstall {}?" @@ -96,6 +97,7 @@ class AddonUninstallerGUI(QtCore.QObject): ) + "...", QtWidgets.QMessageBox.Cancel, + parent = utils.get_main_am_window() ) self.progress_dialog.rejected.connect(self._cancel_removal) self.progress_dialog.show() @@ -114,7 +116,7 @@ class AddonUninstallerGUI(QtCore.QObject): if self.progress_dialog: self.progress_dialog.hide() QtWidgets.QMessageBox.information( - None, + utils.get_main_am_window(), translate("AddonsInstaller", "Uninstall complete"), translate("AddonInstaller", "Finished removing {}").format( addon.display_name @@ -128,7 +130,7 @@ class AddonUninstallerGUI(QtCore.QObject): if self.progress_dialog: self.progress_dialog.hide() QtWidgets.QMessageBox.critical( - None, + utils.get_main_am_window(), translate("AddonsInstaller", "Uninstall failed"), translate("AddonInstaller", "Failed to remove some files") + ":\n" diff --git a/src/Mod/AddonManager/addonmanager_update_all_gui.py b/src/Mod/AddonManager/addonmanager_update_all_gui.py index dc7025bdb0..b82bddca81 100644 --- a/src/Mod/AddonManager/addonmanager_update_all_gui.py +++ b/src/Mod/AddonManager/addonmanager_update_all_gui.py @@ -89,6 +89,7 @@ class UpdateAllGUI(QtCore.QObject): self.dialog = FreeCADGui.PySideUic.loadUi( os.path.join(os.path.dirname(__file__), "update_all.ui") ) + self.dialog.setWindowFlag(QtCore.Qt.WindowStaysOnTopHint, True) self.row_map = {} self.in_process_row = None self.active_installer = None diff --git a/src/Mod/AddonManager/addonmanager_utilities.py b/src/Mod/AddonManager/addonmanager_utilities.py index 6378a0bb0f..53203c208b 100644 --- a/src/Mod/AddonManager/addonmanager_utilities.py +++ b/src/Mod/AddonManager/addonmanager_utilities.py @@ -451,3 +451,20 @@ def run_interruptable_subprocess(args) -> object: if return_code is None or return_code != 0: raise subprocess.CalledProcessError(return_code, args, stdout, stderr) return subprocess.CompletedProcess(args, return_code, stdout, stderr) + +def get_main_am_window(): + windows = QtWidgets.QApplication.topLevelWidgets() + for widget in windows: + if widget.objectName() == "AddonManager_Main_Window": + return widget + # If there is no main AM window, we may be running unit tests: see if the Test Runner window + # exists: + for widget in windows: + if widget.objectName() == "TestGui__UnitTest": + return widget + # If we still didn't find it, try to locate the main FreeCAD window: + for widget in windows: + if hasattr(widget, "centralWidget"): + return widget.centralWidget() + # Why is this code even getting called? + return None