[improvement][ui] big refactoring regarding the components states

This commit is contained in:
Vinicius Moreira
2020-06-22 17:00:32 -03:00
parent e852224637
commit dab70cdfb8
17 changed files with 868 additions and 473 deletions

View File

@@ -365,7 +365,12 @@ class GenericSoftwareManager(SoftwareManager):
return history
def get_managed_types(self) -> Set[Type[SoftwarePackage]]:
pass
available_types = set()
for man in self.get_working_managers():
available_types.update(man.get_managed_types())
return available_types
def is_enabled(self):
return True

View File

@@ -128,7 +128,7 @@ class AppsTable(QTableWidget):
action_history.setIcon(QIcon(resource.get_path('img/history.svg')))
def show_history():
self.window.get_app_history(pkg)
self.window.begin_show_history(pkg)
action_history.triggered.connect(show_history)
menu_row.addAction(action_history)
@@ -141,7 +141,7 @@ class AppsTable(QTableWidget):
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):
self.window.downgrade(pkg)
self.window.begin_downgrade(pkg)
action_downgrade.triggered.connect(downgrade)
action_downgrade.setIcon(QIcon(resource.get_path('img/downgrade.svg')))
@@ -157,7 +157,7 @@ class AppsTable(QTableWidget):
action_ignore_updates.setIcon(QIcon(resource.get_path('img/ignore_update.svg')))
def ignore_updates():
self.window.ignore_updates(pkg)
self.window.begin_ignore_updates(pkg)
action_ignore_updates.triggered.connect(ignore_updates)
menu_row.addAction(action_ignore_updates)
@@ -174,7 +174,7 @@ class AppsTable(QTableWidget):
title=self.i18n[action.i18_label_key],
body=self._parag('{} {} ?'.format(self.i18n[action.i18_label_key], self._bold(str(pkg)))),
i18n=self.i18n):
self.window.execute_custom_action(pkg, action)
self.window.begin_execute_custom_action(pkg, action)
item.triggered.connect(custom_action)
menu_row.addAction(item)
@@ -198,7 +198,7 @@ class AppsTable(QTableWidget):
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):
self.window.uninstall_package(pkg)
self.window.begin_uninstall(pkg)
def _bold(self, text: str) -> str:
return '<span style="font-weight: bold">{}</span>'.format(text)
@@ -495,7 +495,7 @@ class AppsTable(QTableWidget):
if pkg.model.installed:
def run():
self.window.run_app(pkg)
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())
@@ -511,18 +511,18 @@ class AppsTable(QTableWidget):
item.addWidget(bt)
if not pkg.model.installed:
def get_screenshots():
self.window.get_screenshots(pkg)
def show_screenshots():
self.window.begin_show_screenshots(pkg)
bt = IconButton(QIcon(resource.get_path('img/camera.svg')), i18n=self.i18n, action=get_screenshots,
bt = IconButton(QIcon(resource.get_path('img/camera.svg')), i18n=self.i18n, action=show_screenshots,
tooltip=self.i18n['action.screenshots.tooltip'])
bt.setEnabled(bool(pkg.model.has_screenshots()))
item.addWidget(bt)
def get_info():
self.window.get_app_info(pkg)
def show_info():
self.window.begin_show_info(pkg)
bt = IconButton(QIcon(resource.get_path('img/app_info.svg')), i18n=self.i18n, action=get_info, tooltip=self.i18n['action.info.tooltip'])
bt = IconButton(QIcon(resource.get_path('img/app_info.svg')), i18n=self.i18n, action=show_info, tooltip=self.i18n['action.info.tooltip'])
bt.setEnabled(bool(pkg.model.has_info()))
item.addWidget(bt)

View File

@@ -41,21 +41,25 @@ def update_info(pkgv: PackageView, pkgs_info: dict):
pkgs_info['not_installed'] += 1 if not pkgv.model.installed else 0
def apply_filters(pkgv: PackageView, filters: dict, info: dict, limit: bool = True):
def apply_filters(pkg: PackageView, filters: dict, info: dict, limit: bool = True):
if not limit or not filters['display_limit'] or len(info['pkgs_displayed']) < filters['display_limit']:
hidden = filters['only_apps'] and pkgv.model.installed and not pkgv.model.is_application()
if not is_package_hidden(pkg, filters):
info['pkgs_displayed'].append(pkg)
if not hidden and filters['updates']:
hidden = not pkgv.model.update or pkgv.model.is_update_ignored()
if not hidden and filters['type'] is not None and filters['type'] != 'any':
hidden = pkgv.model.get_type() != filters['type']
def is_package_hidden(pkg: PackageView, filters: dict) -> bool:
hidden = filters['only_apps'] and pkg.model.installed and not pkg.model.is_application()
if not hidden and filters['category'] is not None and filters['category'] != 'any':
hidden = not pkgv.model.categories or not [c for c in pkgv.model.categories if c.lower() == filters['category']]
if not hidden and filters['updates']:
hidden = not pkg.model.update or pkg.model.is_update_ignored()
if not hidden and filters['name']:
hidden = not filters['name'] in pkgv.model.name.lower()
if not hidden and filters['type'] is not None and filters['type'] != 'any':
hidden = pkg.model.get_type() != filters['type']
if not hidden:
info['pkgs_displayed'].append(pkgv)
if not hidden and filters['category'] is not None and filters['category'] != 'any':
hidden = not pkg.model.categories or not [c for c in pkg.model.categories if c.lower() == filters['category']]
if not hidden and filters['name']:
hidden = not filters['name'] in pkg.model.name.lower()
return hidden

View File

@@ -3,13 +3,13 @@ import time
import traceback
from pathlib import Path
from threading import Thread
from typing import Tuple
from typing import Tuple, Dict, Optional, Set
from PyQt5.QtCore import Qt, QSize
from PyQt5.QtGui import QIcon, QPixmap, QIntValidator, QCursor
from PyQt5.QtWidgets import QRadioButton, QGroupBox, QCheckBox, QComboBox, QGridLayout, QWidget, \
QLabel, QSizePolicy, QLineEdit, QToolButton, QHBoxLayout, QFormLayout, QFileDialog, QTabWidget, QVBoxLayout, \
QSlider, QScrollArea, QFrame
QSlider, QScrollArea, QFrame, QAction
from bauh.api.abstract.view import SingleSelectComponent, InputOption, MultipleSelectComponent, SelectViewType, \
TextInputComponent, FormComponent, FileChooserComponent, ViewComponent, TabGroupComponent, PanelComponent, \
@@ -20,6 +20,247 @@ from bauh.view.util import resource
from bauh.view.util.translation import I18n
class QtComponentsManager:
def __init__(self):
self.components = {}
self.groups = {}
self.group_of_groups = {}
self._saved_states = {}
def register_component(self, component_id: int, instance: QWidget, action: QAction = None):
comp = (instance, action, {'v': True, 'e': True, 'r': False})
self.components[component_id] = comp
self._save_state(comp)
def register_group(self, group_id: int, subgroups: bool, *ids: int):
if not subgroups:
self.groups[group_id] = {*ids}
else:
self.group_of_groups[group_id] = {*ids}
def get_subgroups(self, root_group: int) -> Set[str]:
return self.group_of_groups.get(root_group, set())
def set_components_visible(self, visible: bool, *ids: int):
if ids:
for cid in ids:
self.set_component_visible(cid, visible)
else:
for cid in self.components:
self.set_component_visible(cid, visible)
def set_component_visible(self, cid: int, visible: bool):
comp = self.components.get(cid)
if comp and self._is_visible(comp) != visible:
self._save_state(comp)
self._set_visible(comp, visible)
def set_component_enabled(self, cid: int, enabled: bool):
comp = self.components.get(cid)
if comp and self._is_enabled(comp) != enabled:
self._save_state(comp)
self._set_enabled(comp, enabled)
def set_component_read_only(self, cid: int, read_only: bool):
comp = self.components.get(cid)
if comp and self._supports_read_only(comp) and self._is_read_only(comp) != read_only:
self._save_state(comp)
self._set_read_only(comp, read_only)
def set_components_enabled(self, enabled: bool, *ids: int):
if ids:
for cid in ids:
self.set_component_enabled(cid, enabled)
else:
for cid in self.components:
self.set_component_enabled(cid, enabled)
def restore_previous_states(self, *ids: int):
if ids:
for cid in ids:
self.restore_previous_state(cid)
else:
for cid in self.components:
self.restore_previous_state(cid)
def restore_previous_group_state(self, group_id: int):
ids = self.groups.get(group_id)
if ids:
self.restore_previous_states(*ids)
def restore_previous_groups_states(self, *groups: int):
if groups:
for group in groups:
self.restore_previous_group_state(group)
def set_group_visible(self, group_id: int, visible: bool):
ids = self.groups.get(group_id)
if ids:
self.set_components_visible(visible, *ids)
def set_groups_visible(self, visible: bool, *groups: int):
if groups:
for group in groups:
self.set_group_visible(group, visible)
def set_group_enabled(self, group_id: int, enabled: bool):
ids = self.groups.get(group_id)
if ids:
self.set_components_enabled(enabled, *ids)
def restore_previous_state(self, cid: int):
comp = self.components.get(cid)
if comp:
previous_state = {**comp[2]}
self._restore_state(comp, previous_state)
def _set_visible(self, comp: Tuple[QWidget, Optional[QAction], Dict[str, bool]], visible: bool):
if comp[1]:
comp[1].setVisible(visible)
else:
comp[0].setVisible(visible)
def _set_enabled(self, comp: Tuple[QWidget, Optional[QAction], Dict[str, bool]], enabled: bool):
comp[0].setEnabled(enabled)
def _set_read_only(self, comp: Tuple[QWidget, Optional[QAction], Dict[str, bool]], read_only: bool):
comp[0].setReadOnly(read_only)
def _supports_read_only(self, comp: Tuple[QWidget, Optional[QAction], Dict[str, bool]]) -> bool:
return isinstance(comp, QLineEdit)
def is_visible(self, cid: int) -> bool:
comp = self.components.get(cid)
return self._is_visible(comp) if comp else False
def _is_visible(self, comp: Tuple[QWidget, Optional[QAction], Dict[str, bool]]) -> bool:
return comp[1].isVisible() if comp[1] else comp[0].isVisible()
def _is_enabled(self, comp: Tuple[QWidget, Optional[QAction], Dict[str, bool]]) -> bool:
return comp[0].isEnabled()
def _is_read_only(self, comp: Tuple[QWidget, Optional[QAction], Dict[str, bool]]) -> bool:
return comp[0].isReadOnly() if self._supports_read_only(comp) else False
def _save_state(self, comp: Tuple[QWidget, Optional[QAction], Dict[str, bool]]):
comp[2]['v'] = self._is_visible(comp)
comp[2]['e'] = self._is_enabled(comp)
comp[2]['r'] = self._is_read_only(comp)
def list_visible_from_group(self, group_id: int) -> Set[str]:
ids = self.groups.get(group_id)
if ids:
return {cid for cid in ids if self.is_visible(cid)}
def disable_visible_from_groups(self, *groups):
if groups:
for group in groups:
ids = self.list_visible_from_group(group)
if ids:
self.set_components_enabled(False, *ids)
def disable_visible(self):
self.set_components_enabled(False, *{cid for cid in self.components if self.is_visible(cid)})
def enable_visible(self):
self.set_components_enabled(True, *{cid for cid in self.components if self.is_visible(cid)})
def enable_visible_from_groups(self, *groups):
if groups:
for group in groups:
ids = self.list_visible_from_group(group)
if ids:
self.set_components_enabled(True, *ids)
def save_state(self, cid: int, state_id: int):
comp = self.components.get(cid)
if comp:
self._save_state(comp)
states = self._saved_states.get(state_id)
if states is None:
states = {}
self._saved_states[state_id] = states
states[cid] = {**comp[2]}
def save_states(self, state_id: int, *ids, only_visible: bool = False):
for cid in (ids if ids else self.components):
if not only_visible or self.is_visible(cid):
self.save_state(cid, state_id)
def save_group_state(self, group_id: int, state_id: int):
ids = self.groups.get(group_id)
if ids:
self.save_states(state_id, *ids)
def save_groups_states(self, state_id: int, *group_ids):
if group_ids:
for group_id in group_ids:
self.save_group_state(group_id, state_id)
def _restore_state(self, comp: Tuple[QWidget, Optional[QAction], Dict[str, bool]], state: Dict[str, bool]):
self._save_state(comp)
if state['v'] != self._is_visible(comp):
self._set_visible(comp, state['v'])
if state['e'] != self._is_enabled(comp):
self._set_enabled(comp, state['e'])
if state['r'] != self._is_read_only(comp):
self._set_read_only(comp, state['r'])
def restore_group_state(self, group_id: int, state_id: int):
states = self._saved_states.get(state_id)
if states:
ids = self.groups.get(group_id)
if ids:
for cid in ids:
comp_state = states.get(cid)
if comp_state:
comp = self.components.get(cid)
if comp:
self._restore_state(comp, comp_state)
def restore_groups_state(self, state_id: int, *group_ids):
if group_ids:
for group_id in group_ids:
self.restore_group_state(group_id, state_id)
def restore_state(self, state_id: int):
state = self._saved_states.get(state_id)
if state:
for cid, cstate in state.items():
comp = self.components.get(cid)
if comp:
self._restore_state(comp, cstate)
del self._saved_states[state_id]
def clear_saved_states(self):
self._saved_states.clear()
def remove_saved_state(self, state_id: int):
if state_id in self._saved_states:
del self._saved_states[state_id]
class RadioButtonQt(QRadioButton):
def __init__(self, model: InputOption, model_parent: SingleSelectComponent):

View File

@@ -96,7 +96,7 @@ class GemSelectorPanel(QWidget):
self.manager.prepare()
self.window.verify_warnings()
self.window.types_changed = True
self.window.refresh_packages()
self.window.begin_refresh_packages()
self.close()
def exit(self):

View File

@@ -12,9 +12,9 @@ IGNORED_ATTRS = {'name', '__app__'}
class InfoDialog(QDialog):
def __init__(self, app: dict, icon_cache: MemoryCache, i18n: I18n, screen_size: QSize):
def __init__(self, pkg_info: dict, icon_cache: MemoryCache, i18n: I18n, screen_size: QSize):
super(InfoDialog, self).__init__(flags=Qt.CustomizeWindowHint | Qt.WindowTitleHint)
self.setWindowTitle(str(app['__app__']))
self.setWindowTitle(str(pkg_info['__app__']))
self.screen_size = screen_size
self.i18n = i18n
layout = QVBoxLayout()
@@ -44,17 +44,17 @@ class InfoDialog(QDialog):
#
# if icon_data and icon_data.get('icon'):
# self.setWindowIcon(icon_data.get('icon'))
self.setWindowIcon(QIcon(app['__app__'].model.get_type_icon_path()))
self.setWindowIcon(QIcon(pkg_info['__app__'].model.get_type_icon_path()))
for idx, attr in enumerate(sorted(app.keys())):
if attr not in IGNORED_ATTRS and app[attr]:
i18n_key = app['__app__'].model.gem_name + '.info.' + attr.lower()
for idx, attr in enumerate(sorted(pkg_info.keys())):
if attr not in IGNORED_ATTRS and pkg_info[attr]:
i18n_key = pkg_info['__app__'].model.gem_name + '.info.' + attr.lower()
if isinstance(app[attr], list):
val = ' '.join([str(e).strip() for e in app[attr] if e])
show_val = '\n'.join(['* ' + str(e).strip() for e in app[attr] if e])
if isinstance(pkg_info[attr], list):
val = ' '.join([str(e).strip() for e in pkg_info[attr] if e])
show_val = '\n'.join(['* ' + str(e).strip() for e in pkg_info[attr] if e])
else:
val = str(app[attr]).strip()
val = str(pkg_info[attr]).strip()
show_val = val
i18n_val = i18n.get('{}.{}'.format(i18n_key, val.lower()))
@@ -90,7 +90,7 @@ class InfoDialog(QDialog):
bt_close = QPushButton(self.i18n['close'].capitalize())
bt_close.setCursor(QCursor(Qt.PointingHandCursor))
bt_close.clicked.connect(lambda: self.close())
bt_close.clicked.connect(self.close)
lower_bar.addWidget(bt_close)
layout.addWidget(lower_bar)

View File

@@ -393,7 +393,7 @@ class PreparePanel(QWidget, TaskManager):
def finish(self):
if self.isVisible():
self.manage_window.refresh_packages()
self.manage_window.begin_refresh_packages()
self.manage_window.show()
self.self_close = True
self.close()

View File

@@ -1,5 +1,9 @@
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtWidgets import QWidget, QApplication
from bauh.view.util import resource
def centralize(widget: QWidget):
geo = widget.frameGeometry()
@@ -7,3 +11,11 @@ def centralize(widget: QWidget):
center_point = QApplication.desktop().screenGeometry(screen).center()
geo.moveCenter(center_point)
widget.move(geo.topLeft())
def load_icon(path: str, width: int, height: int = None) -> QIcon:
return QIcon(QPixmap(path).scaled(width, height if height else width, Qt.KeepAspectRatio, Qt.SmoothTransformation))
def load_resource_icon(path: str, width: int, height: int = None) -> QIcon:
return load_icon(resource.get_path(path), width, height)

View File

@@ -3,23 +3,28 @@ from typing import Tuple
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QCursor, QIcon
from PyQt5.QtWidgets import QInputDialog, QLineEdit, QDialogButtonBox
from PyQt5.QtWidgets import QInputDialog, QLineEdit, QDialogButtonBox, QApplication
from bauh.api.abstract.context import ApplicationContext
from bauh.api.abstract.view import MessageType
from bauh.commons.system import new_subprocess
from bauh.view.core.config import read_config
from bauh.view.qt import css
from bauh.view.qt.components import QtComponentsManager
from bauh.view.qt.dialog import show_message
from bauh.view.util import util
from bauh.view.util.translation import I18n
ACTION_ASK_ROOT = 99
def is_root():
return os.getuid() == 0
def ask_root_password(context: ApplicationContext, i18n: I18n, app_config: dict = None) -> Tuple[str, bool]:
def ask_root_password(context: ApplicationContext, i18n: I18n,
app_config: dict = None,
comp_manager: QtComponentsManager = None) -> Tuple[str, bool]:
cur_config = read_config() if not app_config else app_config
store_password = bool(cur_config['store_root_password'])
@@ -48,13 +53,20 @@ def ask_root_password(context: ApplicationContext, i18n: I18n, app_config: dict
diag.resize(400, 200)
if comp_manager:
comp_manager.save_states(state_id=ACTION_ASK_ROOT, only_visible=True)
comp_manager.disable_visible()
for attempt in range(3):
ok = diag.exec_()
if ok:
if not validate_password(diag.textValue()):
QApplication.setOverrideCursor(QCursor(Qt.WaitCursor))
valid = validate_password(diag.textValue())
QApplication.restoreOverrideCursor()
if not valid:
body = i18n['popup.root.bad_password.body']
if attempt == 2:
@@ -70,10 +82,16 @@ def ask_root_password(context: ApplicationContext, i18n: I18n, app_config: dict
if store_password:
context.root_password = diag.textValue()
if comp_manager:
comp_manager.restore_state(ACTION_ASK_ROOT)
return diag.textValue(), ok
else:
break
if comp_manager:
comp_manager.restore_state(ACTION_ASK_ROOT)
return '', False

View File

@@ -18,7 +18,7 @@ from bauh.view.util.translation import I18n
class SettingsWindow(QWidget):
def __init__(self, manager: SoftwareManager, i18n: I18n, screen_size: QSize, window: QWidget, parent: QWidget = None):
super(SettingsWindow, self).__init__(parent=parent)
super(SettingsWindow, self).__init__(parent=parent, flags=Qt.CustomizeWindowHint | Qt.WindowTitleHint)
self.setWindowTitle('{} ({})'.format(i18n['settings'].capitalize(), __app_name__))
self.setLayout(QVBoxLayout())
self.manager = manager
@@ -96,7 +96,7 @@ class SettingsWindow(QWidget):
self.window.update_custom_actions()
self.window.verify_warnings()
self.window.types_changed = True
self.window.refresh_packages()
self.window.begin_refresh_packages()
self.close()
else:
msg = StringIO()

View File

@@ -22,7 +22,7 @@ from bauh.context import generate_i18n
from bauh.view.core.tray_client import TRAY_CHECK_FILE
from bauh.view.core.update import check_for_update
from bauh.view.qt.about import AboutDialog
from bauh.view.qt.view_utils import load_resource_icon
from bauh.view.qt.qt_utils import load_resource_icon
from bauh.view.util import util, resource
from bauh.view.util.translation import I18n

View File

@@ -1,15 +1,14 @@
import os
import re
import requests
import time
import traceback
from PyQt5.QtCore import QThread, pyqtSignal
from datetime import datetime, timedelta
from io import StringIO
from pathlib import Path
from typing import List, Type, Set, Tuple
import requests
from PyQt5.QtCore import QThread, pyqtSignal
from bauh import LOGS_PATH
from bauh.api.abstract.cache import MemoryCache
from bauh.api.abstract.controller import SoftwareManager, UpgradeRequirement, UpgradeRequirements
@@ -83,7 +82,7 @@ class AsyncAction(QThread, ProcessWatcher):
def show_message(self, title: str, body: str, type_: MessageType = MessageType.INFO):
self.signal_message.emit({'title': title, 'body': body, 'type': type_})
def notify_finished(self, res: object):
def notify_finished(self, res: object = None):
self.signal_finished.emit(res)
def change_status(self, status: str):
@@ -534,68 +533,68 @@ class UninstallPackage(AsyncAction):
self.root_pwd = None
class DowngradeApp(AsyncAction):
class DowngradePackage(AsyncAction):
def __init__(self, manager: SoftwareManager, i18n: I18n, app: PackageView = None):
super(DowngradeApp, self).__init__()
def __init__(self, manager: SoftwareManager, i18n: I18n, pkg: PackageView = None):
super(DowngradePackage, self).__init__()
self.manager = manager
self.app = app
self.pkg = pkg
self.i18n = i18n
self.root_pwd = None
def run(self):
if self.app:
if self.pkg:
success = False
if self.app.model.supports_backup():
if self.pkg.model.supports_backup():
if not self.request_backup(read_config(), 'downgrade', self.i18n, self.root_pwd):
self.notify_finished({'app': self.app, 'success': success})
self.app = None
self.notify_finished({'app': self.pkg, 'success': success})
self.pkg = None
self.root_pwd = None
return
try:
success = self.manager.downgrade(self.app.model, self.root_pwd, self)
success = self.manager.downgrade(self.pkg.model, self.root_pwd, self)
except (requests.exceptions.ConnectionError, NoInternetException) as e:
success = False
self.print(self.i18n['internet.required'])
finally:
self.notify_finished({'app': self.app, 'success': success})
self.app = None
self.notify_finished({'app': self.pkg, 'success': success})
self.pkg = None
self.root_pwd = None
class GetAppInfo(AsyncAction):
class ShowPackageInfo(AsyncAction):
def __init__(self, manager: SoftwareManager, app: PackageView = None):
super(GetAppInfo, self).__init__()
self.app = app
def __init__(self, manager: SoftwareManager, pkg: PackageView = None):
super(ShowPackageInfo, self).__init__()
self.pkg = pkg
self.manager = manager
def run(self):
if self.app:
info = {'__app__': self.app}
info.update(self.manager.get_info(self.app.model))
if self.pkg:
info = {'__app__': self.pkg}
info.update(self.manager.get_info(self.pkg.model))
self.notify_finished(info)
self.app = None
self.pkg = None
class GetAppHistory(AsyncAction):
class ShowPackageHistory(AsyncAction):
def __init__(self, manager: SoftwareManager, i18n: I18n, app: PackageView = None):
super(GetAppHistory, self).__init__()
self.app = app
def __init__(self, manager: SoftwareManager, i18n: I18n, pkg: PackageView = None):
super(ShowPackageHistory, self).__init__()
self.pkg = pkg
self.manager = manager
self.i18n = i18n
def run(self):
if self.app:
if self.pkg:
try:
self.notify_finished({'history': self.manager.get_history(self.app.model)})
self.notify_finished({'history': self.manager.get_history(self.pkg.model)})
except (requests.exceptions.ConnectionError, NoInternetException) as e:
self.notify_finished({'error': self.i18n['internet.required']})
finally:
self.app = None
self.pkg = None
class SearchPackages(AsyncAction):
@@ -816,21 +815,22 @@ class ListWarnings(QThread):
self.signal_warnings.emit(warnings)
class LaunchApp(AsyncAction):
class LaunchPackage(AsyncAction):
def __init__(self, manager: SoftwareManager, app: PackageView = None):
super(LaunchApp, self).__init__()
self.app = app
def __init__(self, manager: SoftwareManager, pkg: PackageView = None):
super(LaunchPackage, self).__init__()
self.pkg = pkg
self.manager = manager
def run(self):
if self.app:
if self.pkg:
try:
time.sleep(0.25)
self.manager.launch(self.app.model)
self.manager.launch(self.pkg.model)
self.notify_finished(True)
except:
traceback.print_exc()
finally:
self.notify_finished(False)
@@ -910,7 +910,7 @@ class ApplyFilters(AsyncAction):
while self.wait_table_update:
time.sleep(0.005)
self.notify_finished(True)
self.notify_finished()
class CustomAction(AsyncAction):
@@ -948,10 +948,10 @@ class CustomAction(AsyncAction):
self.root_pwd = None
class GetScreenshots(AsyncAction):
class ShowScreenshots(AsyncAction):
def __init__(self, manager: SoftwareManager, pkg: PackageView = None):
super(GetScreenshots, self).__init__()
super(ShowScreenshots, self).__init__()
self.pkg = pkg
self.manager = manager

View File

@@ -1,12 +0,0 @@
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon, QPixmap
from bauh.view.util import resource
def load_icon(path: str, width: int, height: int = None) -> QIcon:
return QIcon(QPixmap(path).scaled(width, height if height else width, Qt.KeepAspectRatio, Qt.SmoothTransformation))
def load_resource_icon(path: str, width: int, height: int = None) -> QIcon:
return load_icon(resource.get_path(path), width, height)

File diff suppressed because it is too large Load Diff