mirror of
https://github.com/spalencsar/bearhub.git
synced 2026-07-10 15:34:15 +02:00
[ui] feature: themes
This commit is contained in:
@@ -1,16 +1,15 @@
|
||||
import logging
|
||||
import logging
|
||||
import operator
|
||||
import time
|
||||
import traceback
|
||||
from pathlib import Path
|
||||
from typing import List, Type, Set, Tuple
|
||||
from typing import List, Type, Set, Tuple, Optional
|
||||
|
||||
from PyQt5.QtCore import QEvent, Qt, QSize, pyqtSignal
|
||||
from PyQt5.QtCore import QEvent, Qt, pyqtSignal
|
||||
from PyQt5.QtGui import QIcon, QWindowStateChangeEvent, QCursor
|
||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QCheckBox, QHeaderView, QToolBar, \
|
||||
QLabel, QPlainTextEdit, QLineEdit, QProgressBar, QPushButton, QComboBox, QApplication, QListView, QSizePolicy, \
|
||||
QMenu, QAction
|
||||
QLabel, QPlainTextEdit, QProgressBar, QPushButton, QComboBox, QApplication, QListView, QSizePolicy, \
|
||||
QMenu, QHBoxLayout
|
||||
|
||||
from bauh import LOGS_PATH
|
||||
from bauh.api.abstract.cache import MemoryCache
|
||||
@@ -21,16 +20,20 @@ from bauh.api.abstract.view import MessageType
|
||||
from bauh.api.http import HttpClient
|
||||
from bauh.commons import user
|
||||
from bauh.commons.html import bold
|
||||
from bauh.context import set_theme
|
||||
from bauh.stylesheet import read_all_themes_metadata, ThemeMetadata
|
||||
from bauh.view.core.config import read_config
|
||||
from bauh.view.core.tray_client import notify_tray
|
||||
from bauh.view.qt import dialog, commons, qt_utils, root, styles
|
||||
from bauh.view.qt import dialog, commons, qt_utils
|
||||
from bauh.view.qt.about import AboutDialog
|
||||
from bauh.view.qt.apps_table import AppsTable, UpdateToggleButton
|
||||
from bauh.view.qt.colors import GREEN
|
||||
from bauh.view.qt.components import new_spacer, InputFilter, IconButton, QtComponentsManager
|
||||
from bauh.view.qt.confirmation import ConfirmationDialog
|
||||
from bauh.view.qt.apps_table import PackagesTable, UpgradeToggleButton
|
||||
from bauh.view.qt.commons import sum_updates_displayed
|
||||
from bauh.view.qt.components import new_spacer, IconButton, QtComponentsManager, to_widget, QSearchBar, \
|
||||
QCustomMenuAction
|
||||
from bauh.view.qt.dialog import ConfirmationDialog
|
||||
from bauh.view.qt.history import HistoryDialog
|
||||
from bauh.view.qt.info import InfoDialog
|
||||
from bauh.view.qt.root import ask_root_password
|
||||
from bauh.view.qt.root import RootDialog
|
||||
from bauh.view.qt.screenshots import ScreenshotsDialog
|
||||
from bauh.view.qt.settings import SettingsWindow
|
||||
from bauh.view.qt.thread import UpgradeSelected, RefreshApps, UninstallPackage, DowngradePackage, ShowPackageInfo, \
|
||||
@@ -38,7 +41,7 @@ from bauh.view.qt.thread import UpgradeSelected, RefreshApps, UninstallPackage,
|
||||
ListWarnings, \
|
||||
AsyncAction, LaunchPackage, ApplyFilters, CustomSoftwareAction, ShowScreenshots, CustomAction, \
|
||||
NotifyInstalledLoaded, \
|
||||
IgnorePackageUpdates
|
||||
IgnorePackageUpdates, SaveTheme
|
||||
from bauh.view.qt.view_model import PackageView, PackageViewStatus
|
||||
from bauh.view.util import util, resource
|
||||
from bauh.view.util.translation import I18n
|
||||
@@ -46,19 +49,6 @@ from bauh.view.util.translation import I18n
|
||||
DARK_ORANGE = '#FF4500'
|
||||
|
||||
|
||||
def toolbar_button_style(bg: str = None, color: str = None):
|
||||
style = 'QPushButton { font-weight: 500;'
|
||||
|
||||
if bg:
|
||||
style += 'background: {};'.format(bg)
|
||||
|
||||
if color:
|
||||
style += 'color: {};'.format(color)
|
||||
|
||||
style += ' }'
|
||||
return style
|
||||
|
||||
|
||||
# action ids
|
||||
ACTION_APPLY_FILTERS = 1
|
||||
ACTION_SEARCH = 2
|
||||
@@ -84,10 +74,11 @@ CHECK_APPS = 7
|
||||
COMBO_TYPES = 8
|
||||
COMBO_CATEGORIES = 9
|
||||
INP_NAME = 10
|
||||
CHECK_CONSOLE = 11
|
||||
CHECK_DETAILS = 11
|
||||
BT_SETTINGS = 12
|
||||
BT_CUSTOM_ACTIONS = 13
|
||||
BT_ABOUT = 14
|
||||
BT_THEMES = 15
|
||||
|
||||
# component groups ids
|
||||
GROUP_FILTERS = 1
|
||||
@@ -99,13 +90,14 @@ GROUP_LOWER_BTS = 5
|
||||
|
||||
class ManageWindow(QWidget):
|
||||
signal_user_res = pyqtSignal(bool)
|
||||
signal_root_password = pyqtSignal(str, bool)
|
||||
signal_root_password = pyqtSignal(bool, str)
|
||||
signal_table_update = pyqtSignal()
|
||||
signal_stop_notifying = pyqtSignal()
|
||||
|
||||
def __init__(self, i18n: I18n, icon_cache: MemoryCache, manager: SoftwareManager, screen_size, config: dict,
|
||||
context: ApplicationContext, http_client: HttpClient, logger: logging.Logger, icon: QIcon):
|
||||
super(ManageWindow, self).__init__()
|
||||
self.setObjectName('manage_window')
|
||||
self.comp_manager = QtComponentsManager()
|
||||
self.i18n = i18n
|
||||
self.logger = logger
|
||||
@@ -127,95 +119,56 @@ class ManageWindow(QWidget):
|
||||
self.layout = QVBoxLayout()
|
||||
self.setLayout(self.layout)
|
||||
|
||||
self.toolbar_top = QToolBar()
|
||||
self.toolbar_top.addWidget(new_spacer())
|
||||
self.toolbar_status = QToolBar()
|
||||
self.toolbar_status.setObjectName('toolbar_status')
|
||||
self.toolbar_status.addWidget(new_spacer())
|
||||
|
||||
self.label_status = QLabel()
|
||||
self.label_status.setObjectName('label_status')
|
||||
self.label_status.setText('')
|
||||
self.label_status.setStyleSheet("font-weight: bold")
|
||||
self.toolbar_top.addWidget(self.label_status)
|
||||
self.toolbar_status.addWidget(self.label_status)
|
||||
|
||||
self.search_bar = QToolBar()
|
||||
self.search_bar.setStyleSheet("spacing: 0px;")
|
||||
self.search_bar.setContentsMargins(0, 0, 0, 0)
|
||||
self.search_bar = QSearchBar(search_callback=self.search)
|
||||
self.search_bar.set_placeholder(i18n['window_manage.search_bar.placeholder'] + "...")
|
||||
self.search_bar.set_tooltip(i18n['window_manage.search_bar.tooltip'])
|
||||
self.search_bar.set_button_tooltip(i18n['window_manage.search_bar.button_tooltip'])
|
||||
self.comp_manager.register_component(SEARCH_BAR, self.search_bar, self.toolbar_status.addWidget(self.search_bar))
|
||||
|
||||
self.inp_search = QLineEdit()
|
||||
self.inp_search.setFrame(False)
|
||||
self.inp_search.setPlaceholderText(self.i18n['window_manage.input_search.placeholder'] + "...")
|
||||
self.inp_search.setToolTip(self.i18n['window_manage.input_search.tooltip'])
|
||||
self.inp_search.setStyleSheet("""QLineEdit {
|
||||
color: grey;
|
||||
spacing: 0;
|
||||
height: 30px;
|
||||
font-size: 12px;
|
||||
width: 300px;
|
||||
border-bottom: 1px solid lightgrey;
|
||||
border-top: 1px solid lightgrey;
|
||||
}
|
||||
""")
|
||||
self.inp_search.returnPressed.connect(self.search)
|
||||
search_background_color = self.inp_search.palette().color(self.inp_search.backgroundRole()).name()
|
||||
self.toolbar_status.addWidget(new_spacer())
|
||||
self.layout.addWidget(self.toolbar_status)
|
||||
|
||||
label_pre_search = QLabel()
|
||||
label_pre_search.setStyleSheet("""
|
||||
border-top-left-radius: 5px;
|
||||
border-bottom-left-radius: 5px;
|
||||
border-left: 1px solid lightgrey;
|
||||
border-top: 1px solid lightgrey;
|
||||
border-bottom: 1px solid lightgrey;
|
||||
background: %s;
|
||||
""" % search_background_color)
|
||||
|
||||
self.search_bar.addWidget(label_pre_search)
|
||||
|
||||
self.search_bar.addWidget(self.inp_search)
|
||||
|
||||
label_pos_search = QLabel()
|
||||
label_pos_search.setPixmap(QIcon(resource.get_path('img/search.svg')).pixmap(QSize(10, 10)))
|
||||
label_pos_search.setStyleSheet("""
|
||||
padding-right: 10px;
|
||||
border-top-right-radius: 5px;
|
||||
border-bottom-right-radius: 5px;
|
||||
border-right: 1px solid lightgrey;
|
||||
border-top: 1px solid lightgrey;
|
||||
border-bottom: 1px solid lightgrey;
|
||||
background: %s;
|
||||
""" % search_background_color)
|
||||
|
||||
self.search_bar.addWidget(label_pos_search)
|
||||
|
||||
self.comp_manager.register_component(SEARCH_BAR, self.search_bar, self.toolbar_top.addWidget(self.search_bar))
|
||||
|
||||
self.toolbar_top.addWidget(new_spacer())
|
||||
self.layout.addWidget(self.toolbar_top)
|
||||
|
||||
self.toolbar = QToolBar()
|
||||
self.toolbar.setStyleSheet('QToolBar {spacing: 4px; margin-top: 15px;}')
|
||||
self.toolbar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
|
||||
self.toolbar.setContentsMargins(0, 0, 0, 0)
|
||||
self.toolbar_filters = QWidget()
|
||||
self.toolbar_filters.setObjectName('table_filters')
|
||||
self.toolbar_filters.setLayout(QHBoxLayout())
|
||||
self.toolbar_filters.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
|
||||
self.toolbar_filters.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.check_updates = QCheckBox()
|
||||
self.check_updates.setObjectName('check_updates')
|
||||
self.check_updates.setCursor(QCursor(Qt.PointingHandCursor))
|
||||
self.check_updates.setText(self.i18n['updates'].capitalize())
|
||||
self.check_updates.stateChanged.connect(self._handle_updates_filter)
|
||||
self.check_updates.sizePolicy().setRetainSizeWhenHidden(True)
|
||||
self.comp_manager.register_component(CHECK_UPDATES, self.check_updates, self.toolbar.addWidget(self.check_updates))
|
||||
self.toolbar_filters.layout().addWidget(self.check_updates)
|
||||
self.comp_manager.register_component(CHECK_UPDATES, self.check_updates)
|
||||
|
||||
self.check_apps = QCheckBox()
|
||||
self.check_apps.setObjectName('check_apps')
|
||||
self.check_apps.setCursor(QCursor(Qt.PointingHandCursor))
|
||||
self.check_apps.setText(self.i18n['manage_window.checkbox.only_apps'])
|
||||
self.check_apps.setChecked(True)
|
||||
self.check_apps.stateChanged.connect(self._handle_filter_only_apps)
|
||||
self.check_apps.sizePolicy().setRetainSizeWhenHidden(True)
|
||||
self.comp_manager.register_component(CHECK_APPS, self.check_apps, self.toolbar.addWidget(self.check_apps))
|
||||
self.toolbar_filters.layout().addWidget(self.check_apps)
|
||||
self.comp_manager.register_component(CHECK_APPS, self.check_apps)
|
||||
|
||||
self.any_type_filter = 'any'
|
||||
self.cache_type_filter_icons = {}
|
||||
self.combo_filter_type = QComboBox()
|
||||
self.combo_filter_type.setObjectName('combo_types')
|
||||
self.combo_filter_type.setCursor(QCursor(Qt.PointingHandCursor))
|
||||
self.combo_filter_type.setView(QListView())
|
||||
self.combo_filter_type.setStyleSheet('QLineEdit { height: 2px; }')
|
||||
self.combo_filter_type.setIconSize(QSize(14, 14))
|
||||
self.combo_filter_type.view().setCursor(QCursor(Qt.PointingHandCursor))
|
||||
self.combo_filter_type.setSizeAdjustPolicy(QComboBox.AdjustToContents)
|
||||
self.combo_filter_type.setEditable(True)
|
||||
self.combo_filter_type.lineEdit().setReadOnly(True)
|
||||
@@ -223,78 +176,73 @@ class ManageWindow(QWidget):
|
||||
self.combo_filter_type.activated.connect(self._handle_type_filter)
|
||||
self.combo_filter_type.addItem('--- {} ---'.format(self.i18n['type'].capitalize()), self.any_type_filter)
|
||||
self.combo_filter_type.sizePolicy().setRetainSizeWhenHidden(True)
|
||||
self.comp_manager.register_component(COMBO_TYPES, self.combo_filter_type, self.toolbar.addWidget(self.combo_filter_type))
|
||||
self.toolbar_filters.layout().addWidget(self.combo_filter_type)
|
||||
self.comp_manager.register_component(COMBO_TYPES, self.combo_filter_type)
|
||||
|
||||
self.any_category_filter = 'any'
|
||||
self.combo_categories = QComboBox()
|
||||
self.combo_categories.setObjectName('combo_categories')
|
||||
self.combo_categories.setCursor(QCursor(Qt.PointingHandCursor))
|
||||
self.combo_categories.setStyleSheet('QLineEdit { height: 2px; }')
|
||||
self.combo_categories.setSizeAdjustPolicy(QComboBox.AdjustToContents)
|
||||
self.combo_categories.view().setCursor(QCursor(Qt.PointingHandCursor))
|
||||
self.combo_categories.setEditable(True)
|
||||
self.combo_categories.lineEdit().setReadOnly(True)
|
||||
self.combo_categories.lineEdit().setAlignment(Qt.AlignCenter)
|
||||
self.combo_categories.activated.connect(self._handle_category_filter)
|
||||
self.combo_categories.sizePolicy().setRetainSizeWhenHidden(True)
|
||||
self.combo_categories.addItem('--- {} ---'.format(self.i18n['category'].capitalize()), self.any_category_filter)
|
||||
self.comp_manager.register_component(COMBO_CATEGORIES, self.combo_categories, self.toolbar.addWidget(self.combo_categories))
|
||||
self.toolbar_filters.layout().addWidget(self.combo_categories)
|
||||
self.comp_manager.register_component(COMBO_CATEGORIES, self.combo_categories)
|
||||
|
||||
self.input_name = InputFilter(self.begin_apply_filters)
|
||||
self.input_name.setPlaceholderText(self.i18n['manage_window.name_filter.placeholder'] + '...')
|
||||
self.input_name.setToolTip(self.i18n['manage_window.name_filter.tooltip'])
|
||||
self.input_name.setStyleSheet("QLineEdit { color: grey; }")
|
||||
self.input_name.setFixedWidth(130)
|
||||
self.input_name = QSearchBar(search_callback=self.begin_apply_filters)
|
||||
self.input_name.palette().swap(self.combo_categories.palette())
|
||||
self.input_name.setObjectName('name_filter')
|
||||
self.input_name.set_placeholder(self.i18n['manage_window.name_filter.placeholder'] + '...')
|
||||
self.input_name.set_tooltip(self.i18n['manage_window.name_filter.tooltip'])
|
||||
self.input_name.set_button_tooltip(self.i18n['manage_window.name_filter.button_tooltip'])
|
||||
self.input_name.sizePolicy().setRetainSizeWhenHidden(True)
|
||||
self.comp_manager.register_component(INP_NAME, self.input_name, self.toolbar.addWidget(self.input_name))
|
||||
self.toolbar_filters.layout().addWidget(self.input_name)
|
||||
self.comp_manager.register_component(INP_NAME, self.input_name)
|
||||
|
||||
self.toolbar.addWidget(new_spacer())
|
||||
self.toolbar_filters.layout().addWidget(new_spacer())
|
||||
|
||||
toolbar_bts = []
|
||||
|
||||
if config['suggestions']['enabled']:
|
||||
bt_sugs = QPushButton()
|
||||
bt_sugs.setCursor(QCursor(Qt.PointingHandCursor))
|
||||
bt_sugs.setToolTip(self.i18n['manage_window.bt.suggestions.tooltip'])
|
||||
bt_sugs.setText(self.i18n['manage_window.bt.suggestions.text'].capitalize())
|
||||
bt_sugs.setIcon(QIcon(resource.get_path('img/suggestions.svg')))
|
||||
bt_sugs.setStyleSheet(toolbar_button_style())
|
||||
bt_sugs.clicked.connect(lambda: self._begin_load_suggestions(filter_installed=True))
|
||||
bt_sugs.sizePolicy().setRetainSizeWhenHidden(True)
|
||||
ref_bt_sugs = self.toolbar.addWidget(bt_sugs)
|
||||
toolbar_bts.append(bt_sugs)
|
||||
self.comp_manager.register_component(BT_SUGGESTIONS, bt_sugs, ref_bt_sugs)
|
||||
|
||||
bt_inst = QPushButton()
|
||||
bt_inst.setObjectName('bt_installed')
|
||||
bt_inst.setProperty('root', 'true')
|
||||
bt_inst.setCursor(QCursor(Qt.PointingHandCursor))
|
||||
bt_inst.setToolTip(self.i18n['manage_window.bt.installed.tooltip'])
|
||||
bt_inst.setIcon(QIcon(resource.get_path('img/disk.svg')))
|
||||
bt_inst.setText(self.i18n['manage_window.bt.installed.text'].capitalize())
|
||||
bt_inst.clicked.connect(self._begin_loading_installed)
|
||||
bt_inst.setStyleSheet(toolbar_button_style())
|
||||
bt_inst.sizePolicy().setRetainSizeWhenHidden(True)
|
||||
toolbar_bts.append(bt_inst)
|
||||
self.comp_manager.register_component(BT_INSTALLED, bt_inst, self.toolbar.addWidget(bt_inst))
|
||||
self.toolbar_filters.layout().addWidget(bt_inst)
|
||||
self.comp_manager.register_component(BT_INSTALLED, bt_inst)
|
||||
|
||||
bt_ref = QPushButton()
|
||||
bt_ref.setObjectName('bt_refresh')
|
||||
bt_ref.setProperty('root', 'true')
|
||||
bt_ref.setCursor(QCursor(Qt.PointingHandCursor))
|
||||
bt_ref.setToolTip(i18n['manage_window.bt.refresh.tooltip'])
|
||||
bt_ref.setIcon(QIcon(resource.get_path('img/refresh.svg')))
|
||||
bt_ref.setText(self.i18n['manage_window.bt.refresh.text'])
|
||||
bt_ref.setStyleSheet(toolbar_button_style())
|
||||
bt_ref.clicked.connect(self.begin_refresh_packages)
|
||||
bt_ref.sizePolicy().setRetainSizeWhenHidden(True)
|
||||
toolbar_bts.append(bt_ref)
|
||||
self.comp_manager.register_component(BT_REFRESH, bt_ref, self.toolbar.addWidget(bt_ref))
|
||||
self.toolbar_filters.layout().addWidget(bt_ref)
|
||||
self.comp_manager.register_component(BT_REFRESH, bt_ref)
|
||||
|
||||
self.bt_upgrade = QPushButton()
|
||||
self.bt_upgrade.setProperty('root', 'true')
|
||||
self.bt_upgrade.setObjectName('bt_upgrade')
|
||||
self.bt_upgrade.setCursor(QCursor(Qt.PointingHandCursor))
|
||||
self.bt_upgrade.setToolTip(i18n['manage_window.bt.upgrade.tooltip'])
|
||||
self.bt_upgrade.setIcon(QIcon(resource.get_path('img/app_update.svg')))
|
||||
self.bt_upgrade.setText(i18n['manage_window.bt.upgrade.text'])
|
||||
self.bt_upgrade.setStyleSheet(toolbar_button_style(GREEN, 'white'))
|
||||
self.bt_upgrade.clicked.connect(self.upgrade_selected)
|
||||
self.bt_upgrade.sizePolicy().setRetainSizeWhenHidden(True)
|
||||
toolbar_bts.append(self.bt_upgrade)
|
||||
self.comp_manager.register_component(BT_UPGRADE, self.bt_upgrade, self.toolbar.addWidget(self.bt_upgrade))
|
||||
self.toolbar_filters.layout().addWidget(self.bt_upgrade)
|
||||
self.comp_manager.register_component(BT_UPGRADE, self.bt_upgrade)
|
||||
|
||||
# setting all buttons to the same size:
|
||||
bt_biggest_size = 0
|
||||
@@ -308,44 +256,59 @@ class ManageWindow(QWidget):
|
||||
if bt_biggest_size > bt_width:
|
||||
bt.setFixedWidth(bt_biggest_size)
|
||||
|
||||
self.layout.addWidget(self.toolbar)
|
||||
self.layout.addWidget(self.toolbar_filters)
|
||||
|
||||
self.table_container = QWidget()
|
||||
self.table_container.setObjectName('table_container')
|
||||
self.table_container.setContentsMargins(0, 0, 0, 0)
|
||||
self.table_container.setLayout(QVBoxLayout())
|
||||
self.table_container.layout().setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.table_apps = AppsTable(self, self.icon_cache, download_icons=bool(self.config['download']['icons']))
|
||||
self.table_apps = PackagesTable(self, self.icon_cache, download_icons=bool(self.config['download']['icons']))
|
||||
self.table_apps.change_headers_policy()
|
||||
self.table_container.layout().addWidget(self.table_apps)
|
||||
|
||||
self.layout.addWidget(self.table_container)
|
||||
|
||||
toolbar_console = QToolBar()
|
||||
self.toolbar_console = QWidget()
|
||||
self.toolbar_console.setObjectName('console_toolbar')
|
||||
self.toolbar_console.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
|
||||
self.toolbar_console.setLayout(QHBoxLayout())
|
||||
self.toolbar_console.setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.check_console = QCheckBox()
|
||||
self.check_console.setCursor(QCursor(Qt.PointingHandCursor))
|
||||
self.check_console.setText(self.i18n['manage_window.checkbox.show_details'])
|
||||
self.check_console.stateChanged.connect(self._handle_console)
|
||||
self.comp_manager.register_component(CHECK_CONSOLE, self.check_console, toolbar_console.addWidget(self.check_console))
|
||||
self.check_details = QCheckBox()
|
||||
self.check_details.setObjectName('check_details')
|
||||
self.check_details.setCursor(QCursor(Qt.PointingHandCursor))
|
||||
self.check_details.setText(self.i18n['manage_window.checkbox.show_details'])
|
||||
self.check_details.stateChanged.connect(self._handle_console)
|
||||
self.toolbar_console.layout().addWidget(self.check_details)
|
||||
self.comp_manager.register_component(CHECK_DETAILS, self.check_details)
|
||||
|
||||
toolbar_console.addWidget(new_spacer())
|
||||
self.toolbar_console.layout().addWidget(new_spacer())
|
||||
|
||||
self.label_displayed = QLabel()
|
||||
toolbar_console.addWidget(self.label_displayed)
|
||||
self.label_displayed.setObjectName('apps_displayed')
|
||||
self.label_displayed.setCursor(QCursor(Qt.WhatsThisCursor))
|
||||
self.label_displayed.setToolTip(self.i18n['manage_window.label.apps_displayed.tip'])
|
||||
self.toolbar_console.layout().addWidget(self.label_displayed)
|
||||
self.label_displayed.hide()
|
||||
|
||||
self.layout.addWidget(toolbar_console)
|
||||
self.layout.addWidget(self.toolbar_console)
|
||||
|
||||
self.textarea_output = QPlainTextEdit(self)
|
||||
self.textarea_output.resize(self.table_apps.size())
|
||||
self.textarea_output.setStyleSheet("background: black; color: white;")
|
||||
self.layout.addWidget(self.textarea_output)
|
||||
self.textarea_output.setVisible(False)
|
||||
self.textarea_output.setReadOnly(True)
|
||||
self.textarea_details = QPlainTextEdit(self)
|
||||
self.textarea_details.setObjectName('textarea_details')
|
||||
self.textarea_details.setProperty('console', 'true')
|
||||
self.textarea_details.resize(self.table_apps.size())
|
||||
self.layout.addWidget(self.textarea_details)
|
||||
self.textarea_details.setVisible(False)
|
||||
self.textarea_details.setReadOnly(True)
|
||||
|
||||
self.toolbar_substatus = QToolBar()
|
||||
self.toolbar_substatus.setObjectName('toolbar_substatus')
|
||||
self.toolbar_substatus.addWidget(new_spacer())
|
||||
|
||||
self.label_substatus = QLabel()
|
||||
self.label_substatus.setObjectName('label_substatus')
|
||||
self.label_substatus.setCursor(QCursor(Qt.WaitCursor))
|
||||
self.toolbar_substatus.addWidget(self.label_substatus)
|
||||
self.toolbar_substatus.addWidget(new_spacer())
|
||||
@@ -383,43 +346,65 @@ class ManageWindow(QWidget):
|
||||
self.thread_ignore_updates = IgnorePackageUpdates(manager=self.manager)
|
||||
self._bind_async_action(self.thread_ignore_updates, finished_call=self.finish_ignore_updates)
|
||||
|
||||
self.toolbar_bottom = QToolBar()
|
||||
self.toolbar_bottom.setIconSize(QSize(16, 16))
|
||||
self.toolbar_bottom.setStyleSheet('QToolBar { spacing: 3px }')
|
||||
self.container_bottom = QWidget()
|
||||
self.container_bottom.setObjectName('container_bottom')
|
||||
self.container_bottom.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Fixed)
|
||||
self.container_bottom.setLayout(QHBoxLayout())
|
||||
self.setContentsMargins(0, 0, 0, 0)
|
||||
self.container_bottom.layout().setContentsMargins(0, 0, 0, 0)
|
||||
|
||||
self.toolbar_bottom.addWidget(new_spacer())
|
||||
self.container_bottom.layout().addWidget(new_spacer())
|
||||
|
||||
self.progress_bar = QProgressBar()
|
||||
self.progress_bar.setObjectName('progress_manage')
|
||||
self.progress_bar.setCursor(QCursor(Qt.WaitCursor))
|
||||
self.progress_bar.setStyleSheet(styles.PROGRESS_BAR)
|
||||
self.progress_bar.setMaximumHeight(10 if QApplication.instance().style().objectName().lower() == 'windows' else 4)
|
||||
|
||||
self.progress_bar.setTextVisible(False)
|
||||
self.ref_progress_bar = self.toolbar_bottom.addWidget(self.progress_bar)
|
||||
self.container_bottom.layout().addWidget(self.progress_bar)
|
||||
|
||||
self.toolbar_bottom.addWidget(new_spacer())
|
||||
self.container_bottom.layout().addWidget(new_spacer())
|
||||
|
||||
if config['suggestions']['enabled']:
|
||||
bt_sugs = IconButton(action=lambda: self._begin_load_suggestions(filter_installed=True),
|
||||
i18n=i18n,
|
||||
tooltip=self.i18n['manage_window.bt.suggestions.tooltip'])
|
||||
bt_sugs.setObjectName('suggestions')
|
||||
self.container_bottom.layout().addWidget(bt_sugs)
|
||||
self.comp_manager.register_component(BT_SUGGESTIONS, bt_sugs)
|
||||
|
||||
bt_themes = IconButton(self.show_themes,
|
||||
i18n=self.i18n,
|
||||
tooltip=self.i18n['manage_window.bt_themes.tip'])
|
||||
bt_themes.setObjectName('themes')
|
||||
self.container_bottom.layout().addWidget(bt_themes)
|
||||
self.comp_manager.register_component(BT_THEMES, bt_themes)
|
||||
|
||||
self.custom_actions = manager.get_custom_actions()
|
||||
bt_custom_actions = IconButton(QIcon(resource.get_path('img/custom_actions.svg')),
|
||||
action=self.show_custom_actions,
|
||||
bt_custom_actions = IconButton(action=self.show_custom_actions,
|
||||
i18n=self.i18n,
|
||||
tooltip=self.i18n['manage_window.bt_custom_actions.tip'])
|
||||
bt_custom_actions.setVisible(bool(self.custom_actions))
|
||||
self.comp_manager.register_component(BT_CUSTOM_ACTIONS, bt_custom_actions, self.toolbar_bottom.addWidget(bt_custom_actions))
|
||||
bt_custom_actions.setObjectName('custom_actions')
|
||||
|
||||
bt_settings = IconButton(QIcon(resource.get_path('img/settings.svg')),
|
||||
action=self.show_settings,
|
||||
bt_custom_actions.setVisible(bool(self.custom_actions))
|
||||
self.container_bottom.layout().addWidget(bt_custom_actions)
|
||||
self.comp_manager.register_component(BT_CUSTOM_ACTIONS, bt_custom_actions)
|
||||
|
||||
bt_settings = IconButton(action=self.show_settings,
|
||||
i18n=self.i18n,
|
||||
tooltip=self.i18n['manage_window.bt_settings.tooltip'])
|
||||
self.comp_manager.register_component(BT_SETTINGS, bt_settings, self.toolbar_bottom.addWidget(bt_settings))
|
||||
bt_settings.setObjectName('settings')
|
||||
self.container_bottom.layout().addWidget(bt_settings)
|
||||
self.comp_manager.register_component(BT_SETTINGS, bt_settings)
|
||||
|
||||
bt_about = IconButton(QIcon(resource.get_path('img/info.svg')),
|
||||
action=self._show_about,
|
||||
bt_about = IconButton(action=self._show_about,
|
||||
i18n=self.i18n,
|
||||
tooltip=self.i18n['manage_window.settings.about'])
|
||||
self.comp_manager.register_component(BT_ABOUT, bt_about, self.toolbar_bottom.addWidget(bt_about))
|
||||
bt_about.setObjectName('about')
|
||||
self.container_bottom.layout().addWidget(bt_about)
|
||||
self.comp_manager.register_component(BT_ABOUT, bt_about)
|
||||
|
||||
self.layout.addWidget(self.toolbar_bottom)
|
||||
self.layout.addWidget(self.container_bottom)
|
||||
|
||||
qt_utils.centralize(self)
|
||||
|
||||
@@ -442,6 +427,8 @@ class ManageWindow(QWidget):
|
||||
self.settings_window = None
|
||||
self.search_performed = False
|
||||
|
||||
self.thread_save_theme = SaveTheme(theme_key='')
|
||||
|
||||
self.thread_load_installed = NotifyInstalledLoaded()
|
||||
self.thread_load_installed.signal_loaded.connect(self._finish_loading_installed)
|
||||
self.setMinimumHeight(int(screen_size.height() * 0.5))
|
||||
@@ -457,14 +444,14 @@ class ManageWindow(QWidget):
|
||||
BT_INSTALLED, BT_SUGGESTIONS) # buttons
|
||||
|
||||
self.comp_manager.register_group(GROUP_VIEW_INSTALLED, False,
|
||||
BT_SUGGESTIONS, BT_REFRESH, BT_UPGRADE, # buttons
|
||||
BT_REFRESH, BT_UPGRADE, # buttons
|
||||
*filters)
|
||||
|
||||
self.comp_manager.register_group(GROUP_UPPER_BAR, False,
|
||||
CHECK_APPS, CHECK_UPDATES, COMBO_CATEGORIES, COMBO_TYPES, INP_NAME,
|
||||
BT_INSTALLED, BT_SUGGESTIONS, BT_REFRESH, BT_UPGRADE)
|
||||
|
||||
self.comp_manager.register_group(GROUP_LOWER_BTS, False, BT_ABOUT, BT_SETTINGS, BT_CUSTOM_ACTIONS)
|
||||
self.comp_manager.register_group(GROUP_LOWER_BTS, False, BT_SUGGESTIONS, BT_THEMES, BT_CUSTOM_ACTIONS, BT_SETTINGS, BT_ABOUT)
|
||||
|
||||
def update_custom_actions(self):
|
||||
self.custom_actions = self.manager.get_custom_actions()
|
||||
@@ -540,26 +527,27 @@ class ManageWindow(QWidget):
|
||||
|
||||
def _ask_confirmation(self, msg: dict):
|
||||
self.thread_animate_progress.pause()
|
||||
extra_widgets = [to_widget(comp=c, i18n=self.i18n) for c in msg['components']] if msg.get('components') else None
|
||||
diag = ConfirmationDialog(title=msg['title'],
|
||||
body=msg['body'],
|
||||
i18n=self.i18n,
|
||||
components=msg['components'],
|
||||
widgets=extra_widgets,
|
||||
confirmation_label=msg['confirmation_label'],
|
||||
deny_label=msg['deny_label'],
|
||||
deny_button=msg['deny_button'],
|
||||
window_cancel=msg['window_cancel'],
|
||||
confirmation_button=msg.get('confirmation_button', True),
|
||||
screen_size=self.screen_size)
|
||||
res = diag.is_confirmed()
|
||||
confirmation_button=msg.get('confirmation_button', True))
|
||||
diag.ask()
|
||||
res = diag.confirmed
|
||||
self.thread_animate_progress.animate()
|
||||
self.signal_user_res.emit(res)
|
||||
|
||||
def _pause_and_ask_root_password(self):
|
||||
self.thread_animate_progress.pause()
|
||||
password, valid = root.ask_root_password(self.context, i18n=self.i18n, comp_manager=self.comp_manager)
|
||||
valid, password = RootDialog.ask_password(self.context, i18n=self.i18n, comp_manager=self.comp_manager)
|
||||
|
||||
self.thread_animate_progress.animate()
|
||||
self.signal_root_password.emit(password, valid)
|
||||
self.signal_root_password.emit(valid, password)
|
||||
|
||||
def _show_message(self, msg: dict):
|
||||
self.thread_animate_progress.pause()
|
||||
@@ -582,8 +570,8 @@ class ManageWindow(QWidget):
|
||||
self.thread_warnings.start()
|
||||
|
||||
def _begin_loading_installed(self):
|
||||
self.inp_search.setText('')
|
||||
self.input_name.setText('')
|
||||
self.search_bar.clear()
|
||||
self.input_name.set_text('')
|
||||
self._begin_action(self.i18n['manage_window.status.installed'])
|
||||
self._handle_console_option(False)
|
||||
self.comp_manager.set_components_visible(False)
|
||||
@@ -666,20 +654,20 @@ class ManageWindow(QWidget):
|
||||
|
||||
def _handle_console(self, checked: bool):
|
||||
if checked:
|
||||
self.textarea_output.show()
|
||||
self.textarea_details.show()
|
||||
else:
|
||||
self.textarea_output.hide()
|
||||
self.textarea_details.hide()
|
||||
|
||||
def _handle_console_option(self, enable: bool):
|
||||
if enable:
|
||||
self.textarea_output.clear()
|
||||
self.textarea_details.clear()
|
||||
|
||||
self.comp_manager.set_component_visible(CHECK_CONSOLE, enable)
|
||||
self.check_console.setChecked(False)
|
||||
self.textarea_output.hide()
|
||||
self.comp_manager.set_component_visible(CHECK_DETAILS, enable)
|
||||
self.check_details.setChecked(False)
|
||||
self.textarea_details.hide()
|
||||
|
||||
def begin_refresh_packages(self, pkg_types: Set[Type[SoftwarePackage]] = None):
|
||||
self.inp_search.clear()
|
||||
self.search_bar.clear()
|
||||
|
||||
self._begin_action(self.i18n['manage_window.status.refreshing'])
|
||||
self.comp_manager.set_components_visible(False)
|
||||
@@ -710,7 +698,7 @@ class ManageWindow(QWidget):
|
||||
self.types_changed = False
|
||||
|
||||
def _begin_load_suggestions(self, filter_installed: bool):
|
||||
self.inp_search.clear()
|
||||
self.search_bar.clear()
|
||||
self._begin_action(self.i18n['manage_window.status.suggestions'])
|
||||
self._handle_console_option(False)
|
||||
self.comp_manager.set_components_visible(False)
|
||||
@@ -825,15 +813,21 @@ class ManageWindow(QWidget):
|
||||
def _update_table(self, pkgs_info: dict, signal: bool = False):
|
||||
self.pkgs = pkgs_info['pkgs_displayed']
|
||||
|
||||
self.table_apps.update_packages(self.pkgs, update_check_enabled=pkgs_info['not_installed'] == 0)
|
||||
if pkgs_info['not_installed'] == 0:
|
||||
update_check = sum_updates_displayed(pkgs_info) > 0
|
||||
else:
|
||||
update_check = False
|
||||
|
||||
self.table_apps.update_packages(self.pkgs, update_check_enabled=update_check)
|
||||
|
||||
if not self._maximized:
|
||||
self.label_displayed.show()
|
||||
self.table_apps.change_headers_policy(QHeaderView.Stretch)
|
||||
self.table_apps.change_headers_policy()
|
||||
self._resize(accept_lower_width=len(self.pkgs) > 0)
|
||||
self.label_displayed.setText('{} / {}'.format(len(self.pkgs), len(self.pkgs_available)))
|
||||
else:
|
||||
self.label_displayed.setText('')
|
||||
self.label_displayed.hide()
|
||||
|
||||
if signal:
|
||||
self.signal_table_update.emit()
|
||||
@@ -887,12 +881,12 @@ class ManageWindow(QWidget):
|
||||
'type': self.type_filter,
|
||||
'category': self.category_filter,
|
||||
'updates': False if ignore_updates else self.filter_updates,
|
||||
'name': self.input_name.get_text().lower() if self.input_name.get_text() else None,
|
||||
'name': self.input_name.text().lower() if self.input_name.text() else None,
|
||||
'display_limit': None if self.filter_updates else self.display_limit
|
||||
}
|
||||
|
||||
def update_pkgs(self, new_pkgs: List[SoftwarePackage], as_installed: bool, types: Set[type] = None, ignore_updates: bool = False, keep_filters: bool = False) -> bool:
|
||||
self.input_name.setText('')
|
||||
self.input_name.set_text('')
|
||||
pkgs_info = commons.new_pkgs_info()
|
||||
filters = self._gen_filters(ignore_updates=ignore_updates)
|
||||
|
||||
@@ -1053,8 +1047,8 @@ class ManageWindow(QWidget):
|
||||
|
||||
def _resize(self, accept_lower_width: bool = True):
|
||||
table_width = self.table_apps.get_width()
|
||||
toolbar_width = self.toolbar.sizeHint().width()
|
||||
topbar_width = self.toolbar_top.sizeHint().width()
|
||||
toolbar_width = self.toolbar_filters.sizeHint().width()
|
||||
topbar_width = self.toolbar_status.sizeHint().width()
|
||||
|
||||
new_width = max(table_width, toolbar_width, topbar_width)
|
||||
new_width *= 1.05 # this extra size is not because of the toolbar button, but the table upgrade buttons
|
||||
@@ -1066,13 +1060,14 @@ class ManageWindow(QWidget):
|
||||
self.progress_controll_enabled = enabled
|
||||
|
||||
def upgrade_selected(self):
|
||||
if dialog.ask_confirmation(title=self.i18n['manage_window.upgrade_all.popup.title'],
|
||||
body=self.i18n['manage_window.upgrade_all.popup.body'],
|
||||
i18n=self.i18n,
|
||||
widgets=[UpdateToggleButton(pkg=None,
|
||||
root=self,
|
||||
i18n=self.i18n,
|
||||
clickable=False)]):
|
||||
body = QWidget()
|
||||
body.setLayout(QHBoxLayout())
|
||||
body.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)
|
||||
body.layout().addWidget(QLabel(self.i18n['manage_window.upgrade_all.popup.body']))
|
||||
body.layout().addWidget(UpgradeToggleButton(pkg=None, root=self, i18n=self.i18n, clickable=False))
|
||||
if ConfirmationDialog(title=self.i18n['manage_window.upgrade_all.popup.title'],
|
||||
i18n=self.i18n, body=None,
|
||||
widgets=[body]).ask():
|
||||
|
||||
self._begin_action(action_label=self.i18n['manage_window.status.upgrading'],
|
||||
action_id=ACTION_UPGRADE)
|
||||
@@ -1085,7 +1080,7 @@ class ManageWindow(QWidget):
|
||||
self._finish_action()
|
||||
|
||||
if res.get('id'):
|
||||
output = self.textarea_output.toPlainText()
|
||||
output = self.textarea_details.toPlainText()
|
||||
|
||||
if output:
|
||||
try:
|
||||
@@ -1094,8 +1089,8 @@ class ManageWindow(QWidget):
|
||||
with open(logs_path, 'w+') as f:
|
||||
f.write(output)
|
||||
|
||||
self.textarea_output.appendPlainText('\n*Upgrade summary generated at: {}'.format(UpgradeSelected.SUMMARY_FILE.format(res['id'])))
|
||||
self.textarea_output.appendPlainText('*Upgrade logs generated at: {}'.format(logs_path))
|
||||
self.textarea_details.appendPlainText('\n*Upgrade summary generated at: {}'.format(UpgradeSelected.SUMMARY_FILE.format(res['id'])))
|
||||
self.textarea_details.appendPlainText('*Upgrade logs generated at: {}'.format(logs_path))
|
||||
except:
|
||||
traceback.print_exc()
|
||||
|
||||
@@ -1118,19 +1113,19 @@ class ManageWindow(QWidget):
|
||||
self.update_custom_actions()
|
||||
|
||||
def _show_console_errors(self):
|
||||
if self.textarea_output.toPlainText():
|
||||
self.check_console.setChecked(True)
|
||||
if self.textarea_details.toPlainText():
|
||||
self.check_details.setChecked(True)
|
||||
else:
|
||||
self._handle_console_option(False)
|
||||
self.comp_manager.set_component_visible(CHECK_CONSOLE, False)
|
||||
self.comp_manager.set_component_visible(CHECK_DETAILS, False)
|
||||
|
||||
def _update_action_output(self, output: str):
|
||||
self.textarea_output.appendPlainText(output)
|
||||
self.textarea_details.appendPlainText(output)
|
||||
|
||||
def _begin_action(self, action_label: str, action_id: int = None):
|
||||
self.thread_animate_progress.stop = False
|
||||
self.thread_animate_progress.start()
|
||||
self.ref_progress_bar.setVisible(True)
|
||||
self.progress_bar.setVisible(True)
|
||||
|
||||
if action_id is not None:
|
||||
self.comp_manager.save_states(action_id, only_visible=True)
|
||||
@@ -1149,7 +1144,7 @@ class ManageWindow(QWidget):
|
||||
self.thread_animate_progress.stop = True
|
||||
self.thread_animate_progress.wait(msecs=1000)
|
||||
|
||||
self.ref_progress_bar.setVisible(False)
|
||||
self.progress_bar.setVisible(False)
|
||||
self.progress_bar.setValue(0)
|
||||
self.progress_bar.setTextVisible(False)
|
||||
|
||||
@@ -1246,8 +1241,8 @@ class ManageWindow(QWidget):
|
||||
|
||||
if res.get('error'):
|
||||
self._handle_console_option(True)
|
||||
self.textarea_output.appendPlainText(res['error'])
|
||||
self.check_console.setChecked(True)
|
||||
self.textarea_details.appendPlainText(res['error'])
|
||||
self.check_details.setChecked(True)
|
||||
elif not res['history'].history:
|
||||
dialog.show_message(title=self.i18n['action.history.no_history.title'],
|
||||
body=self.i18n['action.history.no_history.body'].format(bold(res['history'].pkg.name)),
|
||||
@@ -1261,7 +1256,7 @@ class ManageWindow(QWidget):
|
||||
self._begin_action('{} {}'.format(self.i18n['manage_window.status.searching'], word if word else ''), action_id=action_id)
|
||||
|
||||
def search(self):
|
||||
word = self.inp_search.text().strip()
|
||||
word = self.search_bar.text().strip()
|
||||
if word:
|
||||
self._handle_console(False)
|
||||
self._begin_search(word, action_id=ACTION_SEARCH)
|
||||
@@ -1284,13 +1279,13 @@ class ManageWindow(QWidget):
|
||||
self.comp_manager.restore_state(ACTION_SEARCH)
|
||||
dialog.show_message(title=self.i18n['warning'].capitalize(), body=self.i18n[res['error']], type_=MessageType.WARNING)
|
||||
|
||||
def _ask_root_password(self, action: str, pkg: PackageView) -> Tuple[str, bool]:
|
||||
def _ask_root_password(self, action: str, pkg: PackageView) -> Tuple[Optional[str], bool]:
|
||||
pwd = None
|
||||
requires_root = self.manager.requires_root(action, pkg.model)
|
||||
|
||||
if not user.is_root() and requires_root:
|
||||
pwd, ok = ask_root_password(self.context, i18n=self.i18n, comp_manager=self.comp_manager)
|
||||
if not ok:
|
||||
valid, pwd = RootDialog.ask_password(self.context, i18n=self.i18n, comp_manager=self.comp_manager)
|
||||
if not valid:
|
||||
return pwd, False
|
||||
|
||||
return pwd, True
|
||||
@@ -1312,7 +1307,7 @@ class ManageWindow(QWidget):
|
||||
def _finish_install(self, res: dict):
|
||||
self._finish_action(action_id=ACTION_INSTALL)
|
||||
|
||||
console_output = self.textarea_output.toPlainText()
|
||||
console_output = self.textarea_details.toPlainText()
|
||||
|
||||
if console_output:
|
||||
log_path = '{}/install/{}/{}'.format(LOGS_PATH, res['pkg'].model.get_type(), res['pkg'].model.name)
|
||||
@@ -1323,9 +1318,9 @@ class ManageWindow(QWidget):
|
||||
with open(log_file, 'w+') as f:
|
||||
f.write(console_output)
|
||||
|
||||
self.textarea_output.appendPlainText(self.i18n['console.install_logs.path'].format('"{}"'.format(log_file)))
|
||||
self.textarea_details.appendPlainText(self.i18n['console.install_logs.path'].format('"{}"'.format(log_file)))
|
||||
except:
|
||||
self.textarea_output.appendPlainText("[warning] Could not write install log file to '{}'".format(log_path))
|
||||
self.textarea_details.appendPlainText("[warning] Could not write install log file to '{}'".format(log_path))
|
||||
|
||||
if res['success']:
|
||||
if self._can_notify_user():
|
||||
@@ -1385,6 +1380,9 @@ class ManageWindow(QWidget):
|
||||
self.pkgs_installed.insert(idx, PackageView(model, self.i18n))
|
||||
|
||||
self.update_custom_actions()
|
||||
self.table_apps.change_headers_policy(policy=QHeaderView.Stretch, maximized=self._maximized)
|
||||
self.table_apps.change_headers_policy(policy=QHeaderView.ResizeToContents, maximized=self._maximized)
|
||||
self._resize(accept_lower_width=False)
|
||||
else:
|
||||
self._show_console_errors()
|
||||
if self._can_notify_user():
|
||||
@@ -1393,19 +1391,19 @@ class ManageWindow(QWidget):
|
||||
def _update_progress(self, value: int):
|
||||
self.progress_bar.setValue(value)
|
||||
|
||||
def begin_execute_custom_action(self, pkg: PackageView, action: CustomSoftwareAction):
|
||||
if pkg is None and not dialog.ask_confirmation(title=self.i18n['confirmation'].capitalize(),
|
||||
body=self.i18n['custom_action.proceed_with'].capitalize().format('"{}"'.format(self.i18n[action.i18n_label_key])),
|
||||
icon=QIcon(action.icon_path) if action.icon_path else QIcon(resource.get_path('img/logo.svg')),
|
||||
i18n=self.i18n):
|
||||
def begin_execute_custom_action(self, pkg: Optional[PackageView], action: CustomSoftwareAction):
|
||||
if pkg is None and not ConfirmationDialog(title=self.i18n['confirmation'].capitalize(),
|
||||
body='<p>{}</p>'.format(self.i18n['custom_action.proceed_with'].capitalize().format(bold(self.i18n[action.i18n_label_key]))),
|
||||
icon=QIcon(action.icon_path) if action.icon_path else QIcon(resource.get_path('img/logo.svg')),
|
||||
i18n=self.i18n).ask():
|
||||
return False
|
||||
|
||||
pwd = None
|
||||
|
||||
if not user.is_root() and action.requires_root:
|
||||
pwd, ok = ask_root_password(self.context, i18n=self.i18n, comp_manager=self.comp_manager)
|
||||
valid, pwd = RootDialog.ask_password(self.context, i18n=self.i18n, comp_manager=self.comp_manager)
|
||||
|
||||
if not ok:
|
||||
if not valid:
|
||||
return
|
||||
|
||||
self._begin_action(action_label='{}{}'.format(self.i18n[action.i18n_status_key], ' {}'.format(pkg.model.name) if pkg else ''),
|
||||
@@ -1434,10 +1432,10 @@ class ManageWindow(QWidget):
|
||||
self._show_console_errors()
|
||||
|
||||
def _show_console_checkbox_if_output(self):
|
||||
if self.textarea_output.toPlainText():
|
||||
self.comp_manager.set_component_visible(CHECK_CONSOLE, True)
|
||||
if self.textarea_details.toPlainText():
|
||||
self.comp_manager.set_component_visible(CHECK_DETAILS, True)
|
||||
else:
|
||||
self.comp_manager.set_component_visible(CHECK_CONSOLE, False)
|
||||
self.comp_manager.set_component_visible(CHECK_DETAILS, False)
|
||||
|
||||
def show_settings(self):
|
||||
if self.settings_window:
|
||||
@@ -1450,8 +1448,7 @@ class ManageWindow(QWidget):
|
||||
qt_utils.centralize(self.settings_window)
|
||||
self.settings_window.show()
|
||||
|
||||
def _map_custom_action(self, action: CustomSoftwareAction) -> QAction:
|
||||
custom_action = QAction(self.i18n[action.i18n_label_key])
|
||||
def _map_custom_action(self, action: CustomSoftwareAction, parent: QWidget) -> QCustomMenuAction:
|
||||
|
||||
if action.icon_path:
|
||||
try:
|
||||
@@ -1459,20 +1456,21 @@ class ManageWindow(QWidget):
|
||||
icon = QIcon(action.icon_path)
|
||||
else:
|
||||
icon = QIcon.fromTheme(action.icon_path)
|
||||
|
||||
custom_action.setIcon(icon)
|
||||
|
||||
except:
|
||||
pass
|
||||
icon = None
|
||||
else:
|
||||
icon = None
|
||||
|
||||
custom_action.triggered.connect(lambda: self.begin_execute_custom_action(None, action))
|
||||
return custom_action
|
||||
return QCustomMenuAction(parent=parent,
|
||||
label=self.i18n[action.i18n_label_key],
|
||||
action=lambda: self.begin_execute_custom_action(None, action),
|
||||
icon=icon)
|
||||
|
||||
def show_custom_actions(self):
|
||||
if self.custom_actions:
|
||||
menu_row = QMenu()
|
||||
menu_row.setCursor(QCursor(Qt.PointingHandCursor))
|
||||
actions = [self._map_custom_action(a) for a in self.custom_actions]
|
||||
actions = [self._map_custom_action(a, menu_row) for a in self.custom_actions]
|
||||
menu_row.addActions(actions)
|
||||
menu_row.adjustSize()
|
||||
menu_row.popup(QCursor.pos())
|
||||
@@ -1547,3 +1545,48 @@ class ManageWindow(QWidget):
|
||||
self.__add_category(cat)
|
||||
else:
|
||||
self._update_categories(pkg_categories)
|
||||
|
||||
def _map_theme_action(self, theme: ThemeMetadata, menu: QMenu) -> QCustomMenuAction:
|
||||
def _change_theme():
|
||||
set_theme(theme_key=theme.key, app=QApplication.instance(), logger=self.context.logger)
|
||||
self.thread_save_theme.theme_key = theme.key
|
||||
self.thread_save_theme.start()
|
||||
|
||||
return QCustomMenuAction(label=theme.get_i18n_name(self.i18n),
|
||||
action=_change_theme,
|
||||
parent=menu,
|
||||
tooltip=theme.get_i18n_description(self.i18n))
|
||||
|
||||
def show_themes(self):
|
||||
menu_row = QMenu()
|
||||
menu_row.setCursor(QCursor(Qt.PointingHandCursor))
|
||||
menu_row.addActions(self._map_theme_actions(menu_row))
|
||||
menu_row.adjustSize()
|
||||
menu_row.popup(QCursor.pos())
|
||||
menu_row.exec_()
|
||||
|
||||
def _map_theme_actions(self, menu: QMenu) -> List[QCustomMenuAction]:
|
||||
core_config = read_config()
|
||||
|
||||
current_theme_key, current_action = core_config['ui']['theme'], None
|
||||
|
||||
actions = []
|
||||
|
||||
for t in read_all_themes_metadata():
|
||||
if not t.abstract:
|
||||
action = self._map_theme_action(t, menu)
|
||||
|
||||
if current_action is None and current_theme_key is not None and current_theme_key == t.key:
|
||||
action.button.setProperty('current', 'true')
|
||||
current_action = action
|
||||
else:
|
||||
actions.append(action)
|
||||
|
||||
if not current_action:
|
||||
invalid_action = QCustomMenuAction(label=self.i18n['manage_window.bt_themes.option.invalid'], parent=menu)
|
||||
invalid_action.button.setProperty('current', 'true')
|
||||
current_action = invalid_action
|
||||
|
||||
actions.sort(key=lambda a: a.get_label())
|
||||
actions.insert(0, current_action)
|
||||
return actions
|
||||
|
||||
Reference in New Issue
Block a user