|
19 | 19 | platform: ``QSystemTrayIcon`` makes this essentially free, and it is the only |
20 | 20 | way to see/exercise this daemon's UI outside of a Windows box. |
21 | 21 |
|
22 | | -Deferred to a follow-up issue (menu item is present but disabled): the |
23 | | -Exceptions dialog. The Windows device/process hot-plug monitoring thread |
24 | | -(``_check_display_conf_thread``) is also not ported; this Qt build instead |
| 22 | +The Windows device/process hot-plug monitoring thread |
| 23 | +(``_check_display_conf_thread``) is not ported; this Qt build instead |
25 | 24 | triggers an immediate (backgrounded) re-apply whenever the |
26 | 25 | ``apply-profiles``/``reset-vcgt`` IPC command or a tray double-click asks for |
27 | 26 | one, rather than only flipping a flag for a poller to notice later. Profile |
|
35 | 34 |
|
36 | 35 | from __future__ import annotations |
37 | 36 |
|
| 37 | +import os |
38 | 38 | import sys |
39 | 39 | import threading |
40 | 40 |
|
@@ -306,8 +306,7 @@ def _rebuild_menu(self) -> None: # noqa: C901 |
306 | 306 | menu.addSeparator() |
307 | 307 |
|
308 | 308 | exceptions_action = menu.addAction(lang.getstr("exceptions")) |
309 | | - exceptions_action.setEnabled(False) |
310 | | - exceptions_action.setToolTip(_NOT_AVAILABLE_TOOLTIP) |
| 309 | + exceptions_action.triggered.connect(pl.set_exceptions) |
311 | 310 |
|
312 | 311 | menu.addSeparator() |
313 | 312 |
|
@@ -621,6 +620,40 @@ def _set_profile_associations(self, event: object = None) -> None: |
621 | 620 | dlg = ProfileAssociationsDialog(self) |
622 | 621 | dlg.exec() |
623 | 622 |
|
| 623 | + def set_exceptions(self, event: object = None) -> None: |
| 624 | + """Open the Qt exceptions dialog and persist any changes. |
| 625 | +
|
| 626 | + Mirrors wx's ``TaskBarIcon.set_exceptions``. |
| 627 | +
|
| 628 | + Args: |
| 629 | + event: Unused; kept for interface parity with the wx override. |
| 630 | + """ |
| 631 | + print("Menu command: Set exceptions") |
| 632 | + from DisplayCAL.ui.tools.profile_loader_exceptions import ( |
| 633 | + ProfileLoaderExceptionsDialog, |
| 634 | + ) |
| 635 | + |
| 636 | + dlg = ProfileLoaderExceptionsDialog(self._exceptions, self._known_apps) |
| 637 | + result = dlg.exec() |
| 638 | + if result == QDialog.DialogCode.Accepted: |
| 639 | + exceptions = [] |
| 640 | + for key in dlg._exceptions: |
| 641 | + enabled, reset, path = dlg._exceptions[key] |
| 642 | + exceptions.append(f"{enabled:d}:{reset:d}:{path}") |
| 643 | + print( |
| 644 | + f"Enabled={bool(enabled)}", |
| 645 | + "Action={}".format((reset and "Reset") or "Disable"), |
| 646 | + path, |
| 647 | + ) |
| 648 | + if not exceptions: |
| 649 | + print("Clearing exceptions") |
| 650 | + setcfg("profile_loader.exceptions", ";".join(exceptions)) |
| 651 | + self._exceptions = dlg._exceptions |
| 652 | + self._exception_names = {os.path.basename(key) for key in dlg._exceptions} |
| 653 | + self.writecfg() |
| 654 | + else: |
| 655 | + print("Cancelled setting exceptions") |
| 656 | + |
624 | 657 | def _toggle_fix_profile_associations( |
625 | 658 | self, event: object, parent: QWidget | None = None |
626 | 659 | ) -> bool: |
|
0 commit comments