mirror of
https://github.com/spalencsar/bearhub.git
synced 2026-07-10 04:14:16 +02:00
[ui] feature: themes
This commit is contained in:
@@ -2,22 +2,21 @@ import operator
|
||||
import os
|
||||
from functools import reduce
|
||||
from threading import Lock
|
||||
from typing import List
|
||||
from typing import List, Optional
|
||||
|
||||
from PyQt5.QtCore import Qt, QUrl, QSize
|
||||
from PyQt5.QtGui import QPixmap, QIcon, QCursor
|
||||
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply
|
||||
from PyQt5.QtWidgets import QTableWidget, QTableView, QMenu, QAction, QTableWidgetItem, QToolButton, QWidget, \
|
||||
from PyQt5.QtWidgets import QTableWidget, QTableView, QMenu, QToolButton, QWidget, \
|
||||
QHeaderView, QLabel, QHBoxLayout, QToolBar, QSizePolicy
|
||||
|
||||
from bauh.api.abstract.cache import MemoryCache
|
||||
from bauh.api.abstract.model import PackageStatus, CustomSoftwareAction
|
||||
from bauh.commons.html import strip_html, bold
|
||||
from bauh.view.qt import dialog
|
||||
from bauh.view.qt.colors import GREEN, BROWN
|
||||
from bauh.view.qt.components import IconButton
|
||||
from bauh.view.qt.components import IconButton, QCustomMenuAction, QCustomToolbar
|
||||
from bauh.view.qt.dialog import ConfirmationDialog
|
||||
from bauh.view.qt.qt_utils import measure_based_on_height
|
||||
from bauh.view.qt.view_model import PackageView
|
||||
from bauh.view.util import resource
|
||||
from bauh.view.util.translation import I18n
|
||||
|
||||
NAME_MAX_SIZE = 30
|
||||
@@ -25,45 +24,32 @@ DESC_MAX_SIZE = 40
|
||||
PUBLISHER_MAX_SIZE = 25
|
||||
|
||||
|
||||
class UpdateToggleButton(QWidget):
|
||||
class UpgradeToggleButton(QToolButton):
|
||||
|
||||
STYLE_DEFAULT = 'QToolButton { background: ' + GREEN + ' } QToolButton:checked { background: gray } '
|
||||
STYLE_UNCHECKED = 'QToolButton:disabled { background: #d69003 }'
|
||||
|
||||
def __init__(self, pkg: PackageView, root: QWidget, i18n: I18n, checked: bool = True, clickable: bool = True):
|
||||
super(UpdateToggleButton, self).__init__()
|
||||
self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
|
||||
def __init__(self, pkg: Optional[PackageView], root: QWidget, i18n: I18n, checked: bool = True,
|
||||
clickable: bool = True):
|
||||
super(UpgradeToggleButton, self).__init__()
|
||||
self.app_view = pkg
|
||||
self.root = root
|
||||
|
||||
layout = QHBoxLayout()
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
layout.setAlignment(Qt.AlignCenter)
|
||||
self.setLayout(layout)
|
||||
|
||||
self.bt = QToolButton()
|
||||
self.bt.setCursor(QCursor(Qt.PointingHandCursor))
|
||||
self.bt.setCheckable(True)
|
||||
self.bt.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
|
||||
self.setCursor(QCursor(Qt.PointingHandCursor))
|
||||
self.setCheckable(True)
|
||||
|
||||
if clickable:
|
||||
self.bt.clicked.connect(self.change_state)
|
||||
self.clicked.connect(self.change_state)
|
||||
|
||||
self.bt.setStyleSheet(self.STYLE_DEFAULT + (self.STYLE_UNCHECKED if not clickable and not checked else ''))
|
||||
|
||||
layout.addWidget(self.bt)
|
||||
if not clickable and not checked:
|
||||
self.setProperty('enabled', 'false')
|
||||
|
||||
if not checked:
|
||||
self.bt.click()
|
||||
self.click()
|
||||
|
||||
if clickable:
|
||||
self.bt.setIcon(QIcon(resource.get_path('img/app_update.svg')))
|
||||
self.setToolTip('{} {}'.format(i18n['manage_window.apps_table.upgrade_toggle.tooltip'],
|
||||
i18n['manage_window.apps_table.upgrade_toggle.enabled.tooltip']))
|
||||
else:
|
||||
if not checked:
|
||||
self.bt.setIcon(QIcon(resource.get_path('img/exclamation.svg')))
|
||||
self.bt.setEnabled(False)
|
||||
self.setEnabled(False)
|
||||
|
||||
tooltip = i18n['{}.update.disabled.tooltip'.format(pkg.model.gem_name)]
|
||||
|
||||
@@ -73,22 +59,22 @@ class UpdateToggleButton(QWidget):
|
||||
self.setToolTip('{} {}'.format(i18n['manage_window.apps_table.upgrade_toggle.tooltip'],
|
||||
i18n['manage_window.apps_table.upgrade_toggle.disabled.tooltip']))
|
||||
else:
|
||||
self.bt.setIcon(QIcon(resource.get_path('img/app_update.svg')))
|
||||
self.bt.setCheckable(False)
|
||||
self.setCheckable(False)
|
||||
|
||||
def change_state(self, not_checked: bool):
|
||||
self.app_view.update_checked = not not_checked
|
||||
self.setProperty('toggled', str(self.app_view.update_checked).lower())
|
||||
self.root.update_bt_upgrade()
|
||||
self.style().unpolish(self)
|
||||
self.style().polish(self)
|
||||
|
||||
|
||||
class AppsTable(QTableWidget):
|
||||
|
||||
COL_NUMBER = 8
|
||||
STYLE_BT_INSTALL = 'background: {b}; color: white; font-size: 10px; font-weight: bold'.format(b=GREEN)
|
||||
STYLE_BT_UNINSTALL = 'color: {c}; font-size: 10px; font-weight: bold;'.format(c=BROWN)
|
||||
class PackagesTable(QTableWidget):
|
||||
COL_NUMBER = 9
|
||||
|
||||
def __init__(self, parent: QWidget, icon_cache: MemoryCache, download_icons: bool):
|
||||
super(AppsTable, self).__init__()
|
||||
super(PackagesTable, self).__init__()
|
||||
self.setObjectName('table_packages')
|
||||
self.setParent(parent)
|
||||
self.window = parent
|
||||
self.download_icons = download_icons
|
||||
@@ -102,8 +88,8 @@ class AppsTable(QTableWidget):
|
||||
self.setHorizontalHeaderLabels(['' for _ in range(self.columnCount())])
|
||||
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||
self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
|
||||
self.icon_logo = QIcon(resource.get_path('img/logo.svg'))
|
||||
self.pixmap_verified = QIcon(resource.get_path('img/verified.svg')).pixmap(QSize(10, 10))
|
||||
self.horizontalScrollBar().setCursor(QCursor(Qt.PointingHandCursor))
|
||||
self.verticalScrollBar().setCursor(QCursor(Qt.PointingHandCursor))
|
||||
|
||||
self.network_man = QNetworkAccessManager()
|
||||
self.network_man.finished.connect(self._load_icon_and_cache)
|
||||
@@ -114,6 +100,10 @@ class AppsTable(QTableWidget):
|
||||
self.cache_type_icon = {}
|
||||
self.i18n = self.window.i18n
|
||||
|
||||
def icon_size(self) -> QSize:
|
||||
pixels = measure_based_on_height(0.02083)
|
||||
return QSize(pixels, pixels)
|
||||
|
||||
def has_any_settings(self, pkg: PackageView):
|
||||
return pkg.model.has_history() or \
|
||||
pkg.model.can_be_downgraded() or \
|
||||
@@ -122,77 +112,77 @@ class AppsTable(QTableWidget):
|
||||
|
||||
def show_pkg_actions(self, pkg: PackageView):
|
||||
menu_row = QMenu()
|
||||
menu_row.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)
|
||||
menu_row.setObjectName('app_actions')
|
||||
menu_row.setCursor(QCursor(Qt.PointingHandCursor))
|
||||
|
||||
if pkg.model.installed:
|
||||
|
||||
if pkg.model.has_history():
|
||||
action_history = QAction(self.i18n["manage_window.apps_table.row.actions.history"])
|
||||
action_history.setIcon(QIcon(resource.get_path('img/history.svg')))
|
||||
|
||||
def show_history():
|
||||
self.window.begin_show_history(pkg)
|
||||
|
||||
action_history.triggered.connect(show_history)
|
||||
menu_row.addAction(action_history)
|
||||
menu_row.addAction(QCustomMenuAction(parent=menu_row,
|
||||
label=self.i18n["manage_window.apps_table.row.actions.history"],
|
||||
action=show_history,
|
||||
button_name='app_history'))
|
||||
|
||||
if pkg.model.can_be_downgraded():
|
||||
action_downgrade = QAction(self.i18n["manage_window.apps_table.row.actions.downgrade"])
|
||||
|
||||
def downgrade():
|
||||
if dialog.ask_confirmation(
|
||||
title=self.i18n['manage_window.apps_table.row.actions.downgrade'],
|
||||
body=self._parag(self.i18n['manage_window.apps_table.row.actions.downgrade.popup.body'].format(self._bold(str(pkg)))),
|
||||
i18n=self.i18n):
|
||||
if ConfirmationDialog(title=self.i18n['manage_window.apps_table.row.actions.downgrade'],
|
||||
body=self._parag(self.i18n[
|
||||
'manage_window.apps_table.row.actions.downgrade.popup.body'].format(
|
||||
self._bold(str(pkg)))),
|
||||
i18n=self.i18n).ask():
|
||||
self.window.begin_downgrade(pkg)
|
||||
|
||||
action_downgrade.triggered.connect(downgrade)
|
||||
action_downgrade.setIcon(QIcon(resource.get_path('img/downgrade.svg')))
|
||||
menu_row.addAction(action_downgrade)
|
||||
menu_row.addAction(QCustomMenuAction(parent=menu_row,
|
||||
label=self.i18n["manage_window.apps_table.row.actions.downgrade"],
|
||||
action=downgrade,
|
||||
button_name='app_downgrade'))
|
||||
|
||||
if pkg.model.supports_ignored_updates():
|
||||
if pkg.model.is_update_ignored():
|
||||
action_ignore_updates = QAction(
|
||||
self.i18n["manage_window.apps_table.row.actions.ignore_updates_reverse"])
|
||||
action_ignore_updates.setIcon(QIcon(resource.get_path('img/revert_update_ignored.svg')))
|
||||
action_label = self.i18n["manage_window.apps_table.row.actions.ignore_updates_reverse"]
|
||||
button_name = 'revert_ignore_updates'
|
||||
else:
|
||||
action_ignore_updates = QAction(self.i18n["manage_window.apps_table.row.actions.ignore_updates"])
|
||||
action_ignore_updates.setIcon(QIcon(resource.get_path('img/ignore_update.svg')))
|
||||
action_label = self.i18n["manage_window.apps_table.row.actions.ignore_updates"]
|
||||
button_name = 'ignore_updates'
|
||||
|
||||
def ignore_updates():
|
||||
self.window.begin_ignore_updates(pkg)
|
||||
|
||||
action_ignore_updates.triggered.connect(ignore_updates)
|
||||
menu_row.addAction(action_ignore_updates)
|
||||
menu_row.addAction(QCustomMenuAction(parent=menu_row,
|
||||
label=action_label,
|
||||
button_name=button_name,
|
||||
action=ignore_updates))
|
||||
|
||||
if bool(pkg.model.get_custom_supported_actions()):
|
||||
actions = [self._map_custom_action(pkg, a) for a in pkg.model.get_custom_supported_actions()]
|
||||
actions = [self._map_custom_action(pkg, a, menu_row) for a in pkg.model.get_custom_supported_actions()]
|
||||
menu_row.addActions(actions)
|
||||
|
||||
menu_row.adjustSize()
|
||||
menu_row.popup(QCursor.pos())
|
||||
menu_row.exec_()
|
||||
|
||||
def _map_custom_action(self, pkg: PackageView, action: CustomSoftwareAction) -> QAction:
|
||||
item = QAction(self.i18n[action.i18n_label_key])
|
||||
|
||||
if action.icon_path:
|
||||
item.setIcon(QIcon(action.icon_path))
|
||||
|
||||
def _map_custom_action(self, pkg: PackageView, action: CustomSoftwareAction, parent: QWidget) -> QCustomMenuAction:
|
||||
def custom_action():
|
||||
if action.i18n_confirm_key:
|
||||
body = self.i18n[action.i18n_confirm_key].format(bold(pkg.model.name))
|
||||
else:
|
||||
body = '{} ?'.format(self.i18n[action.i18n_label_key])
|
||||
|
||||
if dialog.ask_confirmation(
|
||||
title=self.i18n[action.i18n_label_key],
|
||||
body=self._parag(body),
|
||||
i18n=self.i18n):
|
||||
if ConfirmationDialog(icon=QIcon(pkg.model.get_type_icon_path()),
|
||||
title=self.i18n[action.i18n_label_key],
|
||||
body=self._parag(body),
|
||||
i18n=self.i18n).ask():
|
||||
self.window.begin_execute_custom_action(pkg, action)
|
||||
|
||||
item.triggered.connect(custom_action)
|
||||
return item
|
||||
return QCustomMenuAction(parent=parent,
|
||||
label=self.i18n[action.i18n_label_key],
|
||||
icon=QIcon(action.icon_path) if action.icon_path else None,
|
||||
action=custom_action)
|
||||
|
||||
def refresh(self, pkg: PackageView):
|
||||
self._update_row(pkg, update_check_enabled=False, change_update_col=False)
|
||||
@@ -206,9 +196,11 @@ class AppsTable(QTableWidget):
|
||||
self._update_row(pkg, change_update_col=change_update_col)
|
||||
|
||||
def _uninstall(self, pkg: PackageView):
|
||||
if dialog.ask_confirmation(title=self.i18n['manage_window.apps_table.row.actions.uninstall.popup.title'],
|
||||
body=self._parag(self.i18n['manage_window.apps_table.row.actions.uninstall.popup.body'].format(self._bold(str(pkg)))),
|
||||
i18n=self.i18n):
|
||||
if ConfirmationDialog(title=self.i18n['manage_window.apps_table.row.actions.uninstall.popup.title'],
|
||||
body=self._parag(
|
||||
self.i18n['manage_window.apps_table.row.actions.uninstall.popup.body'].format(
|
||||
self._bold(str(pkg)))),
|
||||
i18n=self.i18n).ask():
|
||||
self.window.begin_uninstall(pkg)
|
||||
|
||||
def _bold(self, text: str) -> str:
|
||||
@@ -224,13 +216,12 @@ class AppsTable(QTableWidget):
|
||||
warning = self.i18n.get('gem.{}.install.warning'.format(pkgv.model.get_type().lower()))
|
||||
|
||||
if warning:
|
||||
body += '<br/><br/> {}'.format('<br/>'.join(('{}.'.format(phrase) for phrase in warning.split('.') if phrase)))
|
||||
|
||||
if dialog.ask_confirmation(
|
||||
title=self.i18n['manage_window.apps_table.row.actions.install.popup.title'],
|
||||
body=self._parag(body),
|
||||
i18n=self.i18n):
|
||||
body += '<br/><br/> {}'.format(
|
||||
'<br/>'.join(('{}.'.format(phrase) for phrase in warning.split('.') if phrase)))
|
||||
|
||||
if ConfirmationDialog(title=self.i18n['manage_window.apps_table.row.actions.install.popup.title'],
|
||||
body=self._parag(body),
|
||||
i18n=self.i18n).ask():
|
||||
self.window.install(pkgv)
|
||||
|
||||
def _load_icon_and_cache(self, http_response: QNetworkReply):
|
||||
@@ -257,18 +248,19 @@ class AppsTable(QTableWidget):
|
||||
if icon_data:
|
||||
for idx, app in enumerate(self.window.pkgs):
|
||||
if app.model.icon_url == icon_url:
|
||||
col_name = self.item(idx, 0)
|
||||
col_name.setIcon(icon_data['icon'])
|
||||
self._update_icon(self.cellWidget(idx, 0), icon_data['icon'])
|
||||
|
||||
if app.model.supports_disk_cache() and app.model.get_disk_icon_path() and icon_data['bytes']:
|
||||
if not icon_was_cached or not os.path.exists(app.model.get_disk_icon_path()):
|
||||
self.window.manager.cache_to_disk(pkg=app.model, icon_bytes=icon_data['bytes'], only_icon=True)
|
||||
self.window.manager.cache_to_disk(pkg=app.model, icon_bytes=icon_data['bytes'],
|
||||
only_icon=True)
|
||||
|
||||
def update_packages(self, pkgs: List[PackageView], update_check_enabled: bool = True):
|
||||
self.setRowCount(0) # removes the overwrite effect when updates the table
|
||||
self.setEnabled(True)
|
||||
|
||||
if pkgs:
|
||||
self.setColumnCount(self.COL_NUMBER if update_check_enabled else self.COL_NUMBER - 1)
|
||||
self.setRowCount(len(pkgs))
|
||||
|
||||
for idx, pkg in enumerate(pkgs):
|
||||
@@ -284,59 +276,49 @@ class AppsTable(QTableWidget):
|
||||
self.scrollToTop()
|
||||
|
||||
def _update_row(self, pkg: PackageView, update_check_enabled: bool = True, change_update_col: bool = True):
|
||||
self._set_col_name(0, pkg)
|
||||
self._set_col_version(1, pkg)
|
||||
self._set_col_description(2, pkg)
|
||||
self._set_col_publisher(3, pkg)
|
||||
self._set_col_type(4, pkg)
|
||||
self._set_col_installed(5, pkg)
|
||||
self._set_col_actions(6, pkg)
|
||||
self._set_col_icon(0, pkg)
|
||||
self._set_col_name(1, pkg)
|
||||
self._set_col_version(2, pkg)
|
||||
self._set_col_description(3, pkg)
|
||||
self._set_col_publisher(4, pkg)
|
||||
self._set_col_type(5, pkg)
|
||||
self._set_col_installed(6, pkg)
|
||||
self._set_col_actions(7, pkg)
|
||||
|
||||
if change_update_col:
|
||||
col_update = None
|
||||
if change_update_col and update_check_enabled:
|
||||
if pkg.model.installed and not pkg.model.is_update_ignored() and pkg.model.update:
|
||||
col_update = QCustomToolbar()
|
||||
col_update.add_space()
|
||||
col_update.add_widget(UpgradeToggleButton(pkg=pkg,
|
||||
root=self.window,
|
||||
i18n=self.i18n,
|
||||
checked=pkg.update_checked if pkg.model.can_be_updated() else False,
|
||||
clickable=pkg.model.can_be_updated()))
|
||||
col_update.add_space()
|
||||
else:
|
||||
col_update = QLabel()
|
||||
|
||||
if update_check_enabled and pkg.model.installed and not pkg.model.is_update_ignored() and pkg.model.update:
|
||||
col_update = QToolBar()
|
||||
col_update.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
|
||||
col_update.addWidget(UpdateToggleButton(pkg=pkg,
|
||||
root=self.window,
|
||||
i18n=self.i18n,
|
||||
checked=pkg.update_checked if pkg.model.can_be_updated() else False,
|
||||
clickable=pkg.model.can_be_updated()))
|
||||
|
||||
self.setCellWidget(pkg.table_index, 7, col_update)
|
||||
|
||||
def _gen_row_button(self, text: str, style: str, callback) -> QWidget:
|
||||
col = QWidget()
|
||||
col.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
|
||||
self.setCellWidget(pkg.table_index, 8, col_update)
|
||||
|
||||
def _gen_row_button(self, text: str, name: str, callback) -> QToolButton:
|
||||
col_bt = QToolButton()
|
||||
col_bt.setProperty('text_only', 'true')
|
||||
col_bt.setObjectName(name)
|
||||
col_bt.setCursor(QCursor(Qt.PointingHandCursor))
|
||||
col_bt.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Preferred)
|
||||
col_bt.setText(text)
|
||||
col_bt.setStyleSheet('QToolButton { ' + style + '}')
|
||||
col_bt.setMinimumWidth(80)
|
||||
col_bt.clicked.connect(callback)
|
||||
|
||||
layout = QHBoxLayout()
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
layout.setAlignment(Qt.AlignCenter)
|
||||
|
||||
layout.addWidget(col_bt)
|
||||
|
||||
col.setLayout(layout)
|
||||
return col
|
||||
return col_bt
|
||||
|
||||
def _set_col_installed(self, col: int, pkg: PackageView):
|
||||
toolbar = QToolBar()
|
||||
toolbar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
|
||||
toolbar = QCustomToolbar()
|
||||
toolbar.add_space()
|
||||
|
||||
if pkg.model.installed:
|
||||
if pkg.model.can_be_uninstalled():
|
||||
def uninstall():
|
||||
self._uninstall(pkg)
|
||||
|
||||
item = self._gen_row_button(self.i18n['uninstall'].capitalize(), self.STYLE_BT_UNINSTALL, uninstall)
|
||||
item = self._gen_row_button(self.i18n['uninstall'].capitalize(), 'bt_uninstall', uninstall)
|
||||
else:
|
||||
item = None
|
||||
|
||||
@@ -344,34 +326,39 @@ class AppsTable(QTableWidget):
|
||||
def install():
|
||||
self._install_app(pkg)
|
||||
|
||||
item = self._gen_row_button(self.i18n['install'].capitalize(), self.STYLE_BT_INSTALL, install)
|
||||
item = self._gen_row_button(self.i18n['install'].capitalize(), 'bt_install', install)
|
||||
else:
|
||||
item = None
|
||||
|
||||
toolbar.addWidget(item)
|
||||
toolbar.add_widget(item)
|
||||
toolbar.add_space()
|
||||
self.setCellWidget(pkg.table_index, col, toolbar)
|
||||
|
||||
def _set_col_type(self, col: int, pkg: PackageView):
|
||||
icon_data = self.cache_type_icon.get(pkg.model.get_type())
|
||||
|
||||
if icon_data is None:
|
||||
pixmap = QIcon(pkg.model.get_type_icon_path()).pixmap(QSize(16, 16))
|
||||
pixmap = QIcon(pkg.model.get_type_icon_path()).pixmap(self.icon_size())
|
||||
icon_data = {'px': pixmap, 'tip': '{}: {}'.format(self.i18n['type'], pkg.get_type_label())}
|
||||
self.cache_type_icon[pkg.model.get_type()] = icon_data
|
||||
|
||||
item = QLabel()
|
||||
item.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)
|
||||
item.setPixmap(icon_data['px'])
|
||||
item.setAlignment(Qt.AlignCenter)
|
||||
|
||||
item.setToolTip(icon_data['tip'])
|
||||
self.setCellWidget(pkg.table_index, col, item)
|
||||
col_type_icon = QLabel()
|
||||
col_type_icon.setCursor(QCursor(Qt.WhatsThisCursor))
|
||||
col_type_icon.setObjectName('app_type')
|
||||
col_type_icon.setProperty('icon', 'true')
|
||||
col_type_icon.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)
|
||||
col_type_icon.setPixmap(icon_data['px'])
|
||||
col_type_icon.setToolTip(icon_data['tip'])
|
||||
self.setCellWidget(pkg.table_index, col, col_type_icon)
|
||||
|
||||
def _set_col_version(self, col: int, pkg: PackageView):
|
||||
label_version = QLabel(str(pkg.model.version if pkg.model.version else '?'))
|
||||
label_version.setObjectName('app_version')
|
||||
label_version.setAlignment(Qt.AlignCenter)
|
||||
|
||||
item = QWidget()
|
||||
item.setProperty('container', 'true')
|
||||
item.setCursor(QCursor(Qt.WhatsThisCursor))
|
||||
item.setLayout(QHBoxLayout())
|
||||
item.layout().addWidget(label_version)
|
||||
|
||||
@@ -381,11 +368,11 @@ class AppsTable(QTableWidget):
|
||||
tooltip = self.i18n['version.unknown']
|
||||
|
||||
if pkg.model.update and not pkg.model.is_update_ignored():
|
||||
label_version.setStyleSheet("color: {}; font-weight: bold".format(GREEN))
|
||||
label_version.setProperty('update', 'true')
|
||||
tooltip = self.i18n['version.installed_outdated']
|
||||
|
||||
if pkg.model.is_update_ignored():
|
||||
label_version.setStyleSheet("color: {}; font-weight: bold".format(BROWN))
|
||||
label_version.setProperty('ignored', 'true')
|
||||
tooltip = self.i18n['version.updates_ignored']
|
||||
|
||||
if pkg.model.installed and pkg.model.update and not pkg.model.is_update_ignored() and pkg.model.version and pkg.model.latest_version and pkg.model.version != pkg.model.latest_version:
|
||||
@@ -395,25 +382,7 @@ class AppsTable(QTableWidget):
|
||||
item.setToolTip(tooltip)
|
||||
self.setCellWidget(pkg.table_index, col, item)
|
||||
|
||||
def _set_col_name(self, col: int, pkg: PackageView):
|
||||
item = QTableWidgetItem()
|
||||
item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
|
||||
|
||||
name = pkg.model.get_display_name()
|
||||
if name:
|
||||
item.setToolTip('{}: {}'.format(self.i18n['app.name'].lower(), pkg.model.get_name_tooltip()))
|
||||
else:
|
||||
name = '...'
|
||||
item.setToolTip(self.i18n['app.name'].lower())
|
||||
|
||||
if len(name) > NAME_MAX_SIZE:
|
||||
name = name[0:NAME_MAX_SIZE - 3] + '...'
|
||||
|
||||
if len(name) < NAME_MAX_SIZE:
|
||||
name = name + ' ' * (NAME_MAX_SIZE-len(name))
|
||||
|
||||
item.setText(name)
|
||||
|
||||
def _set_col_icon(self, col: int, pkg: PackageView):
|
||||
icon_path = pkg.model.get_disk_icon_path()
|
||||
if pkg.model.installed and pkg.model.supports_disk_cache() and icon_path:
|
||||
if icon_path.startswith('/'):
|
||||
@@ -444,11 +413,42 @@ class AppsTable(QTableWidget):
|
||||
icon_data = self.icon_cache.get(pkg.model.icon_url)
|
||||
icon = icon_data['icon'] if icon_data else QIcon(pkg.model.get_default_icon_path())
|
||||
|
||||
item.setIcon(icon)
|
||||
self.setItem(pkg.table_index, col, item)
|
||||
col_icon = QLabel()
|
||||
col_icon.setObjectName('app_icon')
|
||||
col_icon.setProperty('icon', 'true')
|
||||
col_icon.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)
|
||||
self._update_icon(col_icon, icon)
|
||||
self.setCellWidget(pkg.table_index, col, col_icon)
|
||||
|
||||
def _set_col_name(self, col: int, pkg: PackageView):
|
||||
col_name = QLabel()
|
||||
col_name.setObjectName('app_name')
|
||||
col_name.setSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Preferred)
|
||||
col_name.setCursor(QCursor(Qt.WhatsThisCursor))
|
||||
|
||||
name = pkg.model.get_display_name()
|
||||
if name:
|
||||
col_name.setToolTip('{}: {}'.format(self.i18n['app.name'].lower(), pkg.model.get_name_tooltip()))
|
||||
else:
|
||||
name = '...'
|
||||
col_name.setToolTip(self.i18n['app.name'].lower())
|
||||
|
||||
if len(name) > NAME_MAX_SIZE:
|
||||
name = name[0:NAME_MAX_SIZE - 3] + '...'
|
||||
|
||||
if len(name) < NAME_MAX_SIZE:
|
||||
name = name + ' ' * (NAME_MAX_SIZE - len(name))
|
||||
|
||||
col_name.setText(name)
|
||||
self.setCellWidget(pkg.table_index, col, col_name)
|
||||
|
||||
def _update_icon(self, label: QLabel, icon: QIcon):
|
||||
label.setPixmap(icon.pixmap(QSize(self.icon_size())))
|
||||
|
||||
def _set_col_description(self, col: int, pkg: PackageView):
|
||||
item = QLabel()
|
||||
item.setObjectName('app_description')
|
||||
item.setCursor(QCursor(Qt.WhatsThisCursor))
|
||||
|
||||
if pkg.model.description is not None or not pkg.model.is_application() or pkg.model.status == PackageStatus.READY:
|
||||
desc = pkg.model.description.split('\n')[0] if pkg.model.description else pkg.model.description
|
||||
@@ -478,21 +478,27 @@ class AppsTable(QTableWidget):
|
||||
if len(publisher) > PUBLISHER_MAX_SIZE:
|
||||
publisher = full_publisher[0: PUBLISHER_MAX_SIZE - 3] + '...'
|
||||
|
||||
lb_name = QLabel()
|
||||
lb_name.setObjectName('app_publisher')
|
||||
lb_name.setCursor(QCursor(Qt.WhatsThisCursor))
|
||||
|
||||
if not publisher:
|
||||
if not pkg.model.installed:
|
||||
item.setStyleSheet('QLabel { color: red; }')
|
||||
lb_name.setProperty('publisher_known', 'false')
|
||||
|
||||
publisher = self.i18n['unknown']
|
||||
|
||||
lb_name = QLabel(' {}'.format(publisher))
|
||||
lb_name.setText(' {}'.format(publisher))
|
||||
item.addWidget(lb_name)
|
||||
|
||||
if publisher and full_publisher:
|
||||
lb_name.setToolTip(self.i18n['publisher'].capitalize() + ((': ' + full_publisher) if full_publisher else ''))
|
||||
lb_name.setToolTip(
|
||||
self.i18n['publisher'].capitalize() + ((': ' + full_publisher) if full_publisher else ''))
|
||||
|
||||
if pkg.model.is_trustable():
|
||||
lb_verified = QLabel()
|
||||
lb_verified.setPixmap(self.pixmap_verified)
|
||||
lb_verified.setObjectName('icon_publisher_verified')
|
||||
lb_verified.setCursor(QCursor(Qt.WhatsThisCursor))
|
||||
lb_verified.setToolTip(self.i18n['publisher.verified'].capitalize())
|
||||
item.addWidget(lb_verified)
|
||||
else:
|
||||
@@ -501,49 +507,63 @@ class AppsTable(QTableWidget):
|
||||
self.setCellWidget(pkg.table_index, col, item)
|
||||
|
||||
def _set_col_actions(self, col: int, pkg: PackageView):
|
||||
item = QToolBar()
|
||||
item.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
|
||||
toolbar = QCustomToolbar()
|
||||
toolbar.setObjectName('app_actions')
|
||||
toolbar.add_space()
|
||||
|
||||
if pkg.model.installed:
|
||||
def run():
|
||||
self.window.begin_launch_package(pkg)
|
||||
|
||||
bt = IconButton(QIcon(resource.get_path('img/app_play.svg')), i18n=self.i18n, action=run, tooltip=self.i18n['action.run.tooltip'])
|
||||
bt.setEnabled(pkg.model.can_be_run())
|
||||
item.addWidget(bt)
|
||||
bt = IconButton(i18n=self.i18n, action=run, tooltip=self.i18n['action.run.tooltip'])
|
||||
bt.setObjectName('app_run')
|
||||
|
||||
def handle_click():
|
||||
self.show_pkg_actions(pkg)
|
||||
if not pkg.model.can_be_run():
|
||||
bt.setEnabled(False)
|
||||
bt.setProperty('_enabled', 'false')
|
||||
|
||||
toolbar.layout().addWidget(bt)
|
||||
|
||||
settings = self.has_any_settings(pkg)
|
||||
|
||||
if pkg.model.installed:
|
||||
bt = IconButton(QIcon(resource.get_path('img/app_actions.svg')), i18n=self.i18n, action=handle_click, tooltip=self.i18n['action.settings.tooltip'])
|
||||
def handle_custom_actions():
|
||||
self.show_pkg_actions(pkg)
|
||||
|
||||
bt = IconButton(i18n=self.i18n, action=handle_custom_actions, tooltip=self.i18n['action.settings.tooltip'])
|
||||
bt.setObjectName('app_actions')
|
||||
bt.setEnabled(bool(settings))
|
||||
item.addWidget(bt)
|
||||
toolbar.layout().addWidget(bt)
|
||||
|
||||
if not pkg.model.installed:
|
||||
def show_screenshots():
|
||||
self.window.begin_show_screenshots(pkg)
|
||||
|
||||
bt = IconButton(QIcon(resource.get_path('img/camera.svg')), i18n=self.i18n, action=show_screenshots,
|
||||
bt = IconButton(i18n=self.i18n, action=show_screenshots,
|
||||
tooltip=self.i18n['action.screenshots.tooltip'])
|
||||
bt.setEnabled(bool(pkg.model.has_screenshots()))
|
||||
item.addWidget(bt)
|
||||
bt.setObjectName('app_screenshots')
|
||||
|
||||
if not pkg.model.has_screenshots():
|
||||
bt.setEnabled(False)
|
||||
bt.setProperty('_enabled', 'false')
|
||||
|
||||
toolbar.layout().addWidget(bt)
|
||||
|
||||
def show_info():
|
||||
self.window.begin_show_info(pkg)
|
||||
|
||||
bt = IconButton(QIcon(resource.get_path('img/app_info.svg')), i18n=self.i18n, action=show_info, tooltip=self.i18n['action.info.tooltip'])
|
||||
bt = IconButton(i18n=self.i18n, action=show_info, tooltip=self.i18n['action.info.tooltip'])
|
||||
bt.setObjectName('app_info')
|
||||
bt.setEnabled(bool(pkg.model.has_info()))
|
||||
item.addWidget(bt)
|
||||
toolbar.layout().addWidget(bt)
|
||||
|
||||
self.setCellWidget(pkg.table_index, col, item)
|
||||
self.setCellWidget(pkg.table_index, col, toolbar)
|
||||
|
||||
def change_headers_policy(self, policy: QHeaderView = QHeaderView.ResizeToContents, maximized: bool = False):
|
||||
header_horizontal = self.horizontalHeader()
|
||||
for i in range(self.columnCount()):
|
||||
if maximized:
|
||||
if i not in (3, 4, 7):
|
||||
if i not in (4, 5, 8):
|
||||
header_horizontal.setSectionResizeMode(i, QHeaderView.ResizeToContents)
|
||||
else:
|
||||
header_horizontal.setSectionResizeMode(i, QHeaderView.Stretch)
|
||||
|
||||
Reference in New Issue
Block a user