From 0201bda2b763e82299d4b2b875f44c639913ee6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vin=C3=ADcius=20Moreira?= Date: Fri, 7 Feb 2020 15:23:01 -0300 Subject: [PATCH] [ui][settings] available as a tray action --- CHANGELOG.md | 4 +++- bauh/app.py | 2 ++ bauh/view/core/controller.py | 10 ++++------ bauh/view/qt/settings.py | 35 +++++++++++++++++++++++++++++------ bauh/view/qt/systray.py | 34 +++++++++++++++++++++++++++------- bauh/view/qt/window.py | 21 +++++++++++---------- 6 files changed, 76 insertions(+), 30 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 38673191..6b68a660 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,12 +4,14 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). -## [0.8.3] +## [0.8.3] - 2020 ### Improvements - New update lifecycle: - now every package manager must provide the best upgrade order for all the selected packages ( can be disabled through the settings file **~/.config/bauh/config.yml** or the UI ) - AUR - allowing the user to bypass checksum errors when installing / upgrading / downgrading packages +- UI: + - **Settings** available as a tray action as well ## [0.8.2] - 2020-01-31 ### Features diff --git a/bauh/app.py b/bauh/app.py index 8a27c9b0..734aa8b2 100755 --- a/bauh/app.py +++ b/bauh/app.py @@ -76,6 +76,7 @@ def main(): manager.prepare() app = QApplication(sys.argv) + app.setQuitOnLastWindowClosed(False) app.setApplicationName(__app_name__) app.setApplicationVersion(__version__) app_icon = util.get_default_icon()[1] @@ -101,6 +102,7 @@ def main(): tray_icon = TrayIcon(i18n=i18n, manager=manager, manage_window=manage_window, + screen_size=app.primaryScreen().size(), config=local_config) manage_window.set_tray_icon(tray_icon) tray_icon.show() diff --git a/bauh/view/core/controller.py b/bauh/view/core/controller.py index 5f23bf27..b0673521 100755 --- a/bauh/view/core/controller.py +++ b/bauh/view/core/controller.py @@ -409,16 +409,14 @@ class GenericSoftwareManager(SoftwareManager): working_managers=self.working_managers, logger=self.logger, i18n=self.i18n) + else: + self.settings_manager.managers = self.managers + self.settings_manager.working_managers = self.working_managers return self.settings_manager.get_settings(screen_width=screen_width, screen_height=screen_height) def save_settings(self, component: TabGroupComponent) -> Tuple[bool, List[str]]: - res = self.settings_manager.save_settings(component) - - if res[0]: - self.settings_manager = None - - return res + return self.settings_manager.save_settings(component) def sort_update_order(self, pkgs: List[SoftwarePackage]) -> List[SoftwarePackage]: by_manager = {} diff --git a/bauh/view/qt/settings.py b/bauh/view/qt/settings.py index 2ce98fa2..4cb70c9b 100644 --- a/bauh/view/qt/settings.py +++ b/bauh/view/qt/settings.py @@ -1,6 +1,8 @@ +import gc from io import StringIO -from PyQt5.QtCore import QSize +from PyQt5 import sip +from PyQt5.QtCore import QSize, Qt from PyQt5.QtWidgets import QWidget, QVBoxLayout, QToolBar, QSizePolicy, QPushButton from bauh.api.abstract.controller import SoftwareManager @@ -14,7 +16,7 @@ from bauh.view.util.translation import I18n class SettingsWindow(QWidget): - def __init__(self, manager: SoftwareManager, i18n: I18n, screen_size: QSize, tray: bool, window: QWidget, parent: QWidget = None): + def __init__(self, manager: SoftwareManager, i18n: I18n, screen_size: QSize, tray, window: QWidget, parent: QWidget = None): super(SettingsWindow, self).__init__(parent=parent) self.setWindowTitle(i18n['settings'].capitalize()) self.setLayout(QVBoxLayout()) @@ -48,6 +50,25 @@ class SettingsWindow(QWidget): self.layout().addWidget(action_bar) + def closeEvent(self, event): + if self.window and self.window.settings_window == self: + sip.delete(self.window.settings_window) + self.window.settings_window = None + elif self.tray and self.tray.settings_window == self: + sip.delete(self.tray.settings_window) + self.tray.settings_window = None + + gc.collect() + event.accept() + + def handle_display(self): + if self.isMinimized(): + self.setWindowState(Qt.WindowNoState) + elif self.isHidden(): + self.show() + else: + self.setWindowState(self.windowState() and Qt.WindowMinimized or Qt.WindowActive) + def _save_settings(self): success, warnings = self.manager.save_settings(self.settings_model) @@ -58,15 +79,17 @@ class SettingsWindow(QWidget): body="

{}

{}

".format(self.i18n['settings.changed.success.warning'], self.i18n['settings.changed.success.reboot']), i18n=self.i18n): - util.restart_app(self.tray) + util.restart_app(self.window and self.window.isVisible()) else: if isinstance(self.manager, GenericSoftwareManager): self.manager.reset_cache() self.manager.prepare() - self.window.verify_warnings() - self.window.types_changed = True - self.window.refresh_apps() + + if self.window and self.window.isVisible(): + self.window.verify_warnings() + self.window.types_changed = True + self.window.refresh_apps() self.close() else: msg = StringIO() diff --git a/bauh/view/qt/systray.py b/bauh/view/qt/systray.py index 461ba3ad..c5f9dec7 100755 --- a/bauh/view/qt/systray.py +++ b/bauh/view/qt/systray.py @@ -1,20 +1,21 @@ -import os import time from io import StringIO from threading import Lock, Thread from typing import List -from PyQt5.QtCore import QThread, pyqtSignal, QCoreApplication, Qt +from PyQt5.QtCore import QThread, pyqtSignal, QCoreApplication, Qt, QSize from PyQt5.QtGui import QIcon -from PyQt5.QtWidgets import QSystemTrayIcon, QMenu +from PyQt5.QtWidgets import QSystemTrayIcon, QMenu, QWidget, QSizePolicy from bauh import __app_name__ from bauh.api.abstract.controller import SoftwareManager from bauh.api.abstract.model import PackageUpdate -from bauh.view.qt.view_utils import load_resource_icon -from bauh.view.util import util, resource +from bauh.view.qt import qt_utils from bauh.view.qt.about import AboutDialog +from bauh.view.qt.settings import SettingsWindow +from bauh.view.qt.view_utils import load_resource_icon from bauh.view.qt.window import ManageWindow +from bauh.view.util import util from bauh.view.util.translation import I18n @@ -37,10 +38,11 @@ class UpdateCheck(QThread): class TrayIcon(QSystemTrayIcon): - def __init__(self, i18n: I18n, manager: SoftwareManager, manage_window: ManageWindow, config: dict): + def __init__(self, i18n: I18n, manager: SoftwareManager, manage_window: ManageWindow, config: dict, screen_size: QSize): super(TrayIcon, self).__init__() self.i18n = i18n self.manager = manager + self.screen_size = screen_size if config['ui']['tray']['default_icon']: self.icon_default = QIcon(config['ui']['tray']['default_icon']) @@ -65,6 +67,9 @@ class TrayIcon(QSystemTrayIcon): self.action_manage = self.menu.addAction(self.i18n['tray.action.manage']) self.action_manage.triggered.connect(self.show_manage_window) + self.action_settings = self.menu.addAction(self.i18n['settings'].capitalize()) + self.action_settings.triggered.connect(self.show_settings_window) + self.action_about = self.menu.addAction(self.i18n['tray.action.about']) self.action_about.triggered.connect(self.show_about) @@ -75,6 +80,8 @@ class TrayIcon(QSystemTrayIcon): self.manage_window = None self.dialog_about = None + self.settings_window = None + self.check_thread = UpdateCheck(check_interval=int(config['updates']['check_interval']), manager=self.manager) self.check_thread.signal.connect(self.notify_updates) self.check_thread.start() @@ -154,8 +161,21 @@ class TrayIcon(QSystemTrayIcon): self.manage_window.refresh_apps() self.manage_window.show() - def show_about(self): + def show_settings_window(self): + if self.settings_window: + self.settings_window.handle_display() + else: + self.settings_window = SettingsWindow(manager=self.manager, + i18n=self.i18n, + screen_size=self.screen_size, + tray=self, + window=self.manage_window) + self.settings_window.setMinimumWidth(int(self.screen_size.width() / 4)) + self.settings_window.adjustSize() + qt_utils.centralize(self.settings_window) + self.settings_window.show() + def show_about(self): if self.dialog_about is None: self.dialog_about = AboutDialog(self.i18n) diff --git a/bauh/view/qt/window.py b/bauh/view/qt/window.py index ba529114..3da039dc 100755 --- a/bauh/view/qt/window.py +++ b/bauh/view/qt/window.py @@ -30,7 +30,6 @@ from bauh.view.qt.thread import UpdateSelectedApps, RefreshApps, UninstallApp, D GetAppHistory, SearchPackages, InstallPackage, AnimateProgress, VerifyModels, FindSuggestions, ListWarnings, \ AsyncAction, LaunchApp, ApplyFilters, CustomAction, GetScreenshots from bauh.view.qt.view_model import PackageView -from bauh.view.qt.view_utils import load_icon from bauh.view.util import util, resource from bauh.view.util.translation import I18n @@ -316,7 +315,7 @@ class ManageWindow(QWidget): self.toolbar_bottom.addWidget(new_spacer()) bt_settings = IconButton(QIcon(resource.get_path('img/app_settings.svg')), - action=self._show_settings, + action=self.show_settings, background='#12ABAB', i18n=self.i18n, tooltip=self.i18n['manage_window.bt_settings.tooltip']) @@ -501,7 +500,6 @@ class ManageWindow(QWidget): self.table_apps.change_headers_policy(policy) def closeEvent(self, event): - if self.tray_icon: event.ignore() self.hide() @@ -1169,10 +1167,13 @@ class ManageWindow(QWidget): else: self.checkbox_console.setChecked(True) - def _show_settings(self): - self.settings_window = SettingsWindow(self.manager, self.i18n, self.screen_size, bool(self.tray_icon), self) - self.settings_window.setMinimumWidth(int(self.screen_size.width() / 4)) - self.settings_window.resize(self.size()) - self.settings_window.adjustSize() - qt_utils.centralize(self.settings_window) - self.settings_window.show() + def show_settings(self): + if self.settings_window: + self.settings_window.handle_display() + else: + self.settings_window = SettingsWindow(self.manager, self.i18n, self.screen_size, self.tray_icon, self) + self.settings_window.setMinimumWidth(int(self.screen_size.width() / 4)) + self.settings_window.resize(self.size()) + self.settings_window.adjustSize() + qt_utils.centralize(self.settings_window) + self.settings_window.show()