diff --git a/bauh/core/controller.py b/bauh/core/controller.py index 48a9aac2..1e8e21d3 100755 --- a/bauh/core/controller.py +++ b/bauh/core/controller.py @@ -1,10 +1,10 @@ from argparse import Namespace from threading import Thread -from typing import List, Dict, Set +from typing import List, Set from bauh_api.abstract.controller import ApplicationManager, SearchResult from bauh_api.abstract.handler import ProcessWatcher -from bauh_api.abstract.model import Application, ApplicationUpdate, ApplicationHistory +from bauh_api.abstract.model import SoftwarePackage, PackageUpdate, PackageHistory from bauh_api.util.disk import DiskCacheLoader from bauh_api.util.disk import DiskCacheLoaderFactory @@ -23,7 +23,7 @@ class GenericApplicationManager(ApplicationManager): self._enabled_map = {} if app_args.check_packaging_once else None self.thread_prepare = None - def _sort(self, apps: List[Application], word: str) -> List[Application]: + def _sort(self, apps: List[SoftwarePackage], word: str) -> List[SoftwarePackage]: exact_name_matches, contains_name_matches, others = [], [], [] @@ -96,7 +96,7 @@ class GenericApplicationManager(ApplicationManager): self.thread_prepare.join() self.thread_prepare = None - def read_installed(self, disk_loader: DiskCacheLoader = None) -> List[Application]: + def read_installed(self, disk_loader: DiskCacheLoader = None) -> List[SoftwarePackage]: self._wait_to_be_ready() installed = [] @@ -119,7 +119,7 @@ class GenericApplicationManager(ApplicationManager): return installed - def downgrade_app(self, app: Application, root_password: str, handler: ProcessWatcher) -> bool: + def downgrade_app(self, app: SoftwarePackage, root_password: str, handler: ProcessWatcher) -> bool: man = self._get_manager_for(app) if man and app.can_be_downgraded(): @@ -127,37 +127,37 @@ class GenericApplicationManager(ApplicationManager): else: raise Exception("downgrade is not possible for {}".format(app.__class__.__name__)) - def clean_cache_for(self, app: Application): + def clean_cache_for(self, app: SoftwarePackage): man = self._get_manager_for(app) if man: return man.clean_cache_for(app) - def update(self, app: Application, root_password: str, handler: ProcessWatcher) -> bool: + def update(self, app: SoftwarePackage, root_password: str, handler: ProcessWatcher) -> bool: man = self._get_manager_for(app) if man: return man.update(app, root_password, handler) - def uninstall(self, app: Application, root_password: str, handler: ProcessWatcher) -> bool: + def uninstall(self, app: SoftwarePackage, root_password: str, handler: ProcessWatcher) -> bool: man = self._get_manager_for(app) if man: return man.uninstall(app, root_password, handler) - def install(self, app: Application, root_password: str, handler: ProcessWatcher) -> bool: + def install(self, app: SoftwarePackage, root_password: str, handler: ProcessWatcher) -> bool: man = self._get_manager_for(app) if man: return man.install(app, root_password, handler) - def get_info(self, app: Application): + def get_info(self, app: SoftwarePackage): man = self._get_manager_for(app) if man: return man.get_info(app) - def get_history(self, app: Application) -> ApplicationHistory: + def get_history(self, app: SoftwarePackage) -> PackageHistory: man = self._get_manager_for(app) if man: @@ -169,24 +169,24 @@ class GenericApplicationManager(ApplicationManager): def is_enabled(self): return True - def _get_manager_for(self, app: Application) -> ApplicationManager: + def _get_manager_for(self, app: SoftwarePackage) -> ApplicationManager: man = self.map[app.__class__] return man if man and self._is_enabled(man) else None - def cache_to_disk(self, app: Application, icon_bytes: bytes, only_icon: bool): + def cache_to_disk(self, app: SoftwarePackage, icon_bytes: bytes, only_icon: bool): if self.disk_loader_factory.disk_cache and app.supports_disk_cache(): man = self._get_manager_for(app) if man: return man.cache_to_disk(app, icon_bytes=icon_bytes, only_icon=only_icon) - def requires_root(self, action: str, app: Application): + def requires_root(self, action: str, app: SoftwarePackage): man = self._get_manager_for(app) if man: return man.requires_root(action, app) - def refresh(self, app: Application, root_password: str, watcher: ProcessWatcher) -> bool: + def refresh(self, app: SoftwarePackage, root_password: str, watcher: ProcessWatcher) -> bool: self._wait_to_be_ready() man = self._get_manager_for(app) @@ -204,7 +204,7 @@ class GenericApplicationManager(ApplicationManager): self.thread_prepare = Thread(target=self._prepare) self.thread_prepare.start() - def list_updates(self) -> List[ApplicationUpdate]: + def list_updates(self) -> List[PackageUpdate]: self._wait_to_be_ready() updates = [] @@ -242,7 +242,7 @@ class GenericApplicationManager(ApplicationManager): if man_sugs: suggestions.extend(man_sugs) - def list_suggestions(self, limit: int) -> List[Application]: + def list_suggestions(self, limit: int) -> List[SoftwarePackage]: if self.managers: suggestions, threads = [], [] for man in self.managers: diff --git a/bauh/resources/img/disk.png b/bauh/resources/img/disk.png new file mode 100755 index 00000000..c9c5d790 Binary files /dev/null and b/bauh/resources/img/disk.png differ diff --git a/bauh/resources/locale/en b/bauh/resources/locale/en index a1e452db..528bc857 100644 --- a/bauh/resources/locale/en +++ b/bauh/resources/locale/en @@ -30,6 +30,8 @@ manage_window.bt.refresh.text=Refresh manage_window.bt.refresh.tooltip=Reload the data about installed applications manage_window.bt.upgrade.text=Upgrade manage_window.bt.upgrade.tooltip=Upgrade all checked applications +manage_window.bt.installed.text=installed +manage_window.bt.installed.tooltip=Click here to show the installed applications manage_window.checkbox.show_details=Show details popup.root.title=Requires root privileges popup.root.password=Password diff --git a/bauh/resources/locale/es b/bauh/resources/locale/es index 8335af55..b99e1422 100644 --- a/bauh/resources/locale/es +++ b/bauh/resources/locale/es @@ -32,6 +32,8 @@ manage_window.bt.refresh.text=Recargar manage_window.bt.refresh.tooltip=Recarga los datos sobre los aplicativos instalados manage_window.bt.upgrade.text=Actualizar manage_window.bt.upgrade.tooltip=Actualiza todos los aplicativos marcados +manage_window.bt.installed.text=instalados +manage_window.bt.installed.tooltip==Haces clic aqui para mostrar los aplicativos instalados manage_window.checkbox.show_details=Mostrar detalles popup.root.title=Requiere privilegios de root popup.root.password=Contraseña diff --git a/bauh/resources/locale/pt b/bauh/resources/locale/pt index ae2ccb6e..08c134ba 100644 --- a/bauh/resources/locale/pt +++ b/bauh/resources/locale/pt @@ -32,6 +32,8 @@ manage_window.bt.refresh.text=Recarregar manage_window.bt.refresh.tooltip=Recarrega os dados sobre os aplicativos instalados manage_window.bt.upgrade.text=Atualizar manage_window.bt.upgrade.tooltip=Atualiza todos os aplicativos marcados +manage_window.bt.installed.text=instalados +manage_window.bt.installed.tooltip=Clique aqui para exibir os aplicativos instalados manage_window.checkbox.show_details=Mostrar detalhes popup.root.title=Requer privilégios de root popup.root.password=Senha diff --git a/bauh/view/qt/apps_table.py b/bauh/view/qt/apps_table.py index 42cc6690..569b72e6 100644 --- a/bauh/view/qt/apps_table.py +++ b/bauh/view/qt/apps_table.py @@ -7,13 +7,13 @@ from PyQt5.QtGui import QPixmap, QIcon, QCursor from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest from PyQt5.QtWidgets import QTableWidget, QTableView, QMenu, QAction, QTableWidgetItem, QToolButton, QWidget, \ QHeaderView, QLabel, QHBoxLayout, QPushButton, QToolBar -from bauh_api.abstract.model import ApplicationStatus +from bauh_api.abstract.model import PackageStatus from bauh_api.util.cache import Cache from bauh.core import resource from bauh.util import util from bauh.view.qt import dialog -from bauh.view.qt.view_model import ApplicationView, ApplicationViewStatus +from bauh.view.qt.view_model import PackageView, PackageViewStatus INSTALL_BT_STYLE = 'background: {back}; color: white; font-size: 10px; font-weight: bold' @@ -41,7 +41,7 @@ class IconButton(QWidget): class UpdateToggleButton(QWidget): - def __init__(self, app_view: ApplicationView, root: QWidget, locale_keys: dict, checked: bool = True, clickable: bool = True): + def __init__(self, app_view: PackageView, root: QWidget, locale_keys: dict, checked: bool = True, clickable: bool = True): super(UpdateToggleButton, self).__init__() self.app_view = app_view @@ -100,12 +100,12 @@ class AppsTable(QTableWidget): self.lock_async_data = Lock() self.setRowHeight(80,80) - def has_any_settings(self, app_v: ApplicationView): + def has_any_settings(self, app_v: PackageView): return app_v.model.can_be_refreshed() or \ app_v.model.has_history() or \ app_v.model.can_be_downgraded() - def show_app_settings(self, app: ApplicationView): + def show_app_settings(self, app: PackageView): menu_row = QMenu() if app.model.installed: @@ -148,11 +148,11 @@ class AppsTable(QTableWidget): menu_row.exec_() def fill_async_data(self): - if self.window.apps: + if self.window.pkgs: - for idx, app_v in enumerate(self.window.apps): + for idx, app_v in enumerate(self.window.pkgs): - if app_v.visible and app_v.status == ApplicationViewStatus.LOADING and app_v.model.status == ApplicationStatus.READY: + if app_v.visible and app_v.status == PackageViewStatus.LOADING and app_v.model.status == PackageStatus.READY: if self.download_icons: self.network_man.get(QNetworkRequest(QUrl(app_v.model.base_data.icon_url))) @@ -165,17 +165,17 @@ class AppsTable(QTableWidget): self._set_col_version(idx, app_v) self._set_col_description(idx, app_v) self._set_col_settings(idx, app_v) - app_v.status = ApplicationViewStatus.READY + app_v.status = PackageViewStatus.READY self.window.resize_and_center() - def get_selected_app(self) -> ApplicationView: - return self.window.apps[self.currentRow()] + def get_selected_app(self) -> PackageView: + return self.window.pkgs[self.currentRow()] def get_selected_app_icon(self) -> QIcon: return self.item(self.currentRow(), 0).icon() - def _uninstall_app(self, app_v: ApplicationView): + def _uninstall_app(self, app_v: PackageView): if dialog.ask_confirmation(title=self.window.locale_keys['manage_window.apps_table.row.actions.uninstall.popup.title'], body=self._parag(self.window.locale_keys['manage_window.apps_table.row.actions.uninstall.popup.body'].format(self._bold(str(app_v)))), locale_keys=self.window.locale_keys): @@ -196,7 +196,7 @@ class AppsTable(QTableWidget): def _get_app_history(self): self.window.get_app_history(self.get_selected_app()) - def _install_app(self, app_v: ApplicationView): + def _install_app(self, app_v: PackageView): if dialog.ask_confirmation( title=self.window.locale_keys['manage_window.apps_table.row.actions.install.popup.title'], @@ -225,7 +225,7 @@ class AppsTable(QTableWidget): icon_data = {'icon': icon, 'bytes': icon_bytes} self.icon_cache.add(icon_url, icon_data) - for idx, app in enumerate(self.window.apps): + for idx, app in enumerate(self.window.pkgs): if app.model.base_data.icon_url == icon_url: col_name = self.item(idx, 0) col_name.setIcon(icon_data['icon']) @@ -234,12 +234,12 @@ class AppsTable(QTableWidget): if not icon_was_cached or not os.path.exists(app.model.get_disk_icon_path()): self.window.manager.cache_to_disk(app=app.model, icon_bytes=icon_data['bytes'], only_icon=True) - def update_apps(self, app_views: List[ApplicationView], update_check_enabled: bool = True): - self.setRowCount(len(app_views) if app_views else 0) + def update_apps(self, pkg_views: List[PackageView], update_check_enabled: bool = True): + self.setRowCount(len(pkg_views) if pkg_views else 0) self.setEnabled(True) - if app_views: - for idx, app_v in enumerate(app_views): + if pkg_views: + for idx, app_v in enumerate(pkg_views): self._set_col_name(idx, app_v) self._set_col_version(idx, app_v) self._set_col_description(idx, app_v) @@ -270,7 +270,7 @@ class AppsTable(QTableWidget): return col - def _set_col_installed(self, idx: int, app_v: ApplicationView): + def _set_col_installed(self, idx: int, app_v: PackageView): if app_v.model.installed: if app_v.model.can_be_uninstalled(): @@ -292,7 +292,7 @@ class AppsTable(QTableWidget): self.setCellWidget(idx, 4, col) - def _set_col_type(self, idx: int, app_v: ApplicationView): + def _set_col_type(self, idx: int, app_v: PackageView): col_type = QLabel() pixmap = QPixmap(app_v.model.get_default_icon_path()) col_type.setPixmap(pixmap.scaled(16, 16, Qt.KeepAspectRatio, Qt.SmoothTransformation)) @@ -300,7 +300,7 @@ class AppsTable(QTableWidget): col_type.setToolTip('{}: {}'.format(self.window.locale_keys['type'], app_v.model.get_type())) self.setCellWidget(idx, 3, col_type) - def _set_col_version(self, idx: int, app_v: ApplicationView): + def _set_col_version(self, idx: int, app_v: PackageView): label_version = QLabel(app_v.model.base_data.version if app_v.model.base_data.version else '?') label_version.setAlignment(Qt.AlignCenter) @@ -324,7 +324,7 @@ class AppsTable(QTableWidget): col_version.setToolTip(tooltip) self.setCellWidget(idx, 1, col_version) - def _set_col_name(self, idx: int, app_v: ApplicationView): + def _set_col_name(self, idx: int, app_v: PackageView): col = QTableWidgetItem() col.setText(app_v.model.base_data.name if app_v.model.base_data.name else '...') col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) @@ -347,11 +347,11 @@ class AppsTable(QTableWidget): col.setIcon(icon) self.setItem(idx, 0, col) - def _set_col_description(self, idx: int, app_v: ApplicationView): + def _set_col_description(self, idx: int, app_v: PackageView): col = QTableWidgetItem() col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) - if app_v.model.base_data.description is not None or app_v.model.is_library() or app_v.model.status == ApplicationStatus.READY: + if app_v.model.base_data.description is not None or not app_v.model.is_application() or app_v.model.status == PackageStatus.READY: desc = app_v.model.base_data.description else: desc = '...' @@ -366,7 +366,7 @@ class AppsTable(QTableWidget): self.setItem(idx, 2, col) - def _set_col_settings(self, idx: int, app_v: ApplicationView): + def _set_col_settings(self, idx: int, app_v: PackageView): tb = QToolBar() if app_v.model.can_be_run() and app_v.model.get_command(): diff --git a/bauh/view/qt/history.py b/bauh/view/qt/history.py index 9f896e93..2c454808 100644 --- a/bauh/view/qt/history.py +++ b/bauh/view/qt/history.py @@ -4,13 +4,13 @@ from functools import reduce from PyQt5.QtCore import Qt from PyQt5.QtGui import QColor from PyQt5.QtWidgets import QDialog, QVBoxLayout, QTableWidget, QTableWidgetItem, QHeaderView -from bauh_api.abstract.model import ApplicationHistory +from bauh_api.abstract.model import PackageHistory from bauh_api.util.cache import Cache class HistoryDialog(QDialog): - def __init__(self, app_history: ApplicationHistory, icon_cache: Cache, locale_keys: dict): + def __init__(self, app_history: PackageHistory, icon_cache: Cache, locale_keys: dict): super(HistoryDialog, self).__init__() self.setWindowTitle('{} - {} '.format(locale_keys['popup.history.title'], app_history.app.base_data.name)) diff --git a/bauh/view/qt/systray.py b/bauh/view/qt/systray.py index 41aa95a6..85a36832 100755 --- a/bauh/view/qt/systray.py +++ b/bauh/view/qt/systray.py @@ -5,7 +5,7 @@ from typing import List from PyQt5.QtCore import QThread, pyqtSignal, QCoreApplication, Qt from PyQt5.QtGui import QIcon from PyQt5.QtWidgets import QSystemTrayIcon, QMenu -from bauh_api.abstract.model import ApplicationUpdate +from bauh_api.abstract.model import PackageUpdate from bauh import __app_name__ from bauh.core import resource @@ -84,7 +84,7 @@ class TrayIcon(QSystemTrayIcon): def _verify_updates(self, notify_user: bool): self.notify_updates(self.manager.list_updates(), notify_user=notify_user) - def notify_updates(self, updates: List[ApplicationUpdate], notify_user: bool = True): + def notify_updates(self, updates: List[PackageUpdate], notify_user: bool = True): self.lock_notify.acquire() diff --git a/bauh/view/qt/thread.py b/bauh/view/qt/thread.py index a0e33449..c61ce121 100644 --- a/bauh/view/qt/thread.py +++ b/bauh/view/qt/thread.py @@ -7,12 +7,12 @@ import requests from PyQt5.QtCore import QThread, pyqtSignal from bauh_api.abstract.controller import ApplicationManager from bauh_api.abstract.handler import ProcessWatcher -from bauh_api.abstract.model import ApplicationStatus +from bauh_api.abstract.model import PackageStatus from bauh_api.abstract.view import InputViewComponent, MessageType from bauh_api.exception import NoInternetException from bauh_api.util.cache import Cache -from bauh.view.qt.view_model import ApplicationView +from bauh.view.qt.view_model import PackageView class AsyncAction(QThread, ProcessWatcher): @@ -62,7 +62,7 @@ class AsyncAction(QThread, ProcessWatcher): class UpdateSelectedApps(AsyncAction): - def __init__(self, manager: ApplicationManager, locale_keys: dict, apps_to_update: List[ApplicationView] = None): + def __init__(self, manager: ApplicationManager, locale_keys: dict, apps_to_update: List[PackageView] = None): super(UpdateSelectedApps, self).__init__() self.apps_to_update = apps_to_update self.manager = manager @@ -92,7 +92,7 @@ class UpdateSelectedApps(AsyncAction): class RefreshApps(AsyncAction): - def __init__(self, manager: ApplicationManager, app: ApplicationView = None): + def __init__(self, manager: ApplicationManager, app: PackageView = None): super(RefreshApps, self).__init__() self.manager = manager self.app = app # app that should be on list top @@ -118,7 +118,7 @@ class RefreshApps(AsyncAction): class UninstallApp(AsyncAction): - def __init__(self, manager: ApplicationManager, icon_cache: Cache, app: ApplicationView = None): + def __init__(self, manager: ApplicationManager, icon_cache: Cache, app: PackageView = None): super(UninstallApp, self).__init__() self.app = app self.manager = manager @@ -140,7 +140,7 @@ class UninstallApp(AsyncAction): class DowngradeApp(AsyncAction): - def __init__(self, manager: ApplicationManager, locale_keys: dict, app: ApplicationView = None): + def __init__(self, manager: ApplicationManager, locale_keys: dict, app: PackageView = None): super(DowngradeApp, self).__init__() self.manager = manager self.app = app @@ -163,7 +163,7 @@ class DowngradeApp(AsyncAction): class GetAppInfo(AsyncAction): - def __init__(self, manager: ApplicationManager, app: ApplicationView = None): + def __init__(self, manager: ApplicationManager, app: PackageView = None): super(GetAppInfo, self).__init__() self.app = app self.manager = manager @@ -178,7 +178,7 @@ class GetAppInfo(AsyncAction): class GetAppHistory(AsyncAction): - def __init__(self, manager: ApplicationManager, locale_keys: dict, app: ApplicationView = None): + def __init__(self, manager: ApplicationManager, locale_keys: dict, app: PackageView = None): super(GetAppHistory, self).__init__() self.app = app self.manager = manager @@ -214,7 +214,7 @@ class SearchApps(AsyncAction): class InstallApp(AsyncAction): - def __init__(self, manager: ApplicationManager, disk_cache: bool, icon_cache: Cache, locale_keys: dict, app: ApplicationView = None): + def __init__(self, manager: ApplicationManager, disk_cache: bool, icon_cache: Cache, locale_keys: dict, app: PackageView = None): super(InstallApp, self).__init__() self.app = app self.manager = manager @@ -279,7 +279,7 @@ class VerifyModels(QThread): signal_updates = pyqtSignal() - def __init__(self, apps: List[ApplicationView] = None): + def __init__(self, apps: List[PackageView] = None): super(VerifyModels, self).__init__() self.apps = apps @@ -294,7 +294,7 @@ class VerifyModels(QThread): current_ready = 0 for app in self.apps: - current_ready += 1 if app.model.status == ApplicationStatus.READY else 0 + current_ready += 1 if app.model.status == PackageStatus.READY else 0 if current_ready > last_ready: last_ready = current_ready @@ -314,7 +314,7 @@ class VerifyModels(QThread): class RefreshApp(AsyncAction): - def __init__(self, manager: ApplicationManager, app: ApplicationView = None): + def __init__(self, manager: ApplicationManager, app: PackageView = None): super(RefreshApp, self).__init__() self.app = app self.manager = manager @@ -363,7 +363,7 @@ class ListWarnings(QThread): class RunApp(AsyncAction): - def __init__(self, app: ApplicationView = None): + def __init__(self, app: PackageView = None): super(RunApp, self).__init__() self.app = app diff --git a/bauh/view/qt/view_model.py b/bauh/view/qt/view_model.py index c8aedcd6..940bb965 100644 --- a/bauh/view/qt/view_model.py +++ b/bauh/view/qt/view_model.py @@ -1,20 +1,20 @@ from enum import Enum -from bauh_api.abstract.model import Application +from bauh_api.abstract.model import SoftwarePackage -class ApplicationViewStatus(Enum): +class PackageViewStatus(Enum): LOADING = 0 READY = 1 -class ApplicationView: +class PackageView: - def __init__(self, model: Application, visible: bool = True): + def __init__(self, model: SoftwarePackage, visible: bool = True): self.model = model self.update_checked = model.update self.visible = visible - self.status = ApplicationViewStatus.LOADING + self.status = PackageViewStatus.LOADING def __repr__(self): return '{} ( {} )'.format(self.model.base_data.name, self.model.get_type()) diff --git a/bauh/view/qt/window.py b/bauh/view/qt/window.py index 7f81d83f..d209c9b5 100755 --- a/bauh/view/qt/window.py +++ b/bauh/view/qt/window.py @@ -7,7 +7,7 @@ from PyQt5.QtGui import QIcon, QWindowStateChangeEvent, QPixmap from PyQt5.QtWidgets import QWidget, QVBoxLayout, QApplication, QCheckBox, QHeaderView, QToolButton, QToolBar, \ QLabel, QPlainTextEdit, QLineEdit, QProgressBar, QHBoxLayout, QPushButton, QComboBox from bauh_api.abstract.controller import ApplicationManager -from bauh_api.abstract.model import Application +from bauh_api.abstract.model import SoftwarePackage from bauh_api.abstract.view import MessageType from bauh_api.util.cache import Cache @@ -24,7 +24,7 @@ from bauh.view.qt.root import is_root, ask_root_password from bauh.view.qt.thread import UpdateSelectedApps, RefreshApps, UninstallApp, DowngradeApp, GetAppInfo, \ GetAppHistory, SearchApps, InstallApp, AnimateProgress, VerifyModels, RefreshApp, FindSuggestions, ListWarnings, \ AsyncAction, RunApp -from bauh.view.qt.view_model import ApplicationView +from bauh.view.qt.view_model import PackageView DARK_ORANGE = '#FF4500' @@ -43,7 +43,8 @@ class ManageWindow(QWidget): self.manager = manager self.tray_icon = tray_icon self.working = False # restrict the number of threaded actions - self.apps = [] + self.pkgs = [] + self.pkgs_installed = [] self.label_flatpak = None self.icon_cache = icon_cache self.disk_cache = disk_cache @@ -111,6 +112,14 @@ class ManageWindow(QWidget): self.toolbar.addWidget(new_spacer()) + self.bt_installed = QPushButton() + self.bt_installed.setToolTip(self.locale_keys['manage_window.bt.installed.tooltip']) + self.bt_installed.setIcon(QIcon(resource.get_path('img/disk.png'))) + self.bt_installed.setText(self.locale_keys['manage_window.bt.installed.text'].capitalize()) + self.bt_installed.clicked.connect(self._show_installed) + self.bt_installed.setStyleSheet(self._toolbar_button_style('brown')) + self.ref_bt_installed = self.toolbar.addWidget(self.bt_installed) + self.bt_refresh = QPushButton() self.bt_refresh.setToolTip(locale_keys['manage_window.bt.refresh.tooltip']) self.bt_refresh.setIcon(QIcon(resource.get_path('img/new_refresh.svg'))) @@ -252,6 +261,13 @@ class ManageWindow(QWidget): if not self.thread_warnings.isFinished(): self.thread_warnings.start() + def _show_installed(self): + if self.pkgs_installed: + self.finish_action() + self.ref_checkbox_only_apps.setVisible(True) + self.ref_bt_upgrade.setVisible(True) + self.update_apps(apps=None, as_installed=True) + def _show_about(self): if self.dialog_about is None: self.dialog_about = AboutDialog(self.locale_keys) @@ -302,7 +318,7 @@ class ManageWindow(QWidget): self.checkbox_console.setChecked(False) self.textarea_output.hide() - def refresh_apps(self, keep_console: bool = True, top_app: ApplicationView = None): + def refresh_apps(self, keep_console: bool = True, top_app: PackageView = None): self.type_filter = None self.input_search.clear() @@ -318,14 +334,14 @@ class ManageWindow(QWidget): self.thread_refresh.start() - def _finish_refresh_apps(self, apps: List[Application]): + def _finish_refresh_apps(self, apps: List[SoftwarePackage]): self.finish_action() self.ref_checkbox_only_apps.setVisible(True) self.ref_bt_upgrade.setVisible(True) - self.update_apps(apps) + self.update_apps(apps, as_installed=True) self.first_refresh = False - def uninstall_app(self, app: ApplicationView): + def uninstall_app(self, app: PackageView): pwd = None requires_root = self.manager.requires_root('uninstall', app.model) @@ -342,12 +358,12 @@ class ManageWindow(QWidget): self.thread_uninstall.root_password = pwd self.thread_uninstall.start() - def run_app(self, app: ApplicationView): + def run_app(self, app: PackageView): self._begin_action(self.locale_keys['manage_window.status.running_app'].format(app.model.base_data.name)) self.thread_run_app.app = app self.thread_run_app.start() - def refresh(self, app: ApplicationView): + def refresh(self, app: PackageView): pwd = None requires_root = self.manager.requires_root('refresh', app.model) @@ -364,7 +380,7 @@ class ManageWindow(QWidget): self.thread_refresh_app.root_password = pwd self.thread_refresh_app.start() - def _finish_uninstall(self, app: ApplicationView): + def _finish_uninstall(self, app: PackageView): self.finish_action() if app: @@ -417,10 +433,10 @@ class ManageWindow(QWidget): self.toolbar_substatus.show() def apply_filters(self): - if self.apps: - visible_apps = len(self.apps) - for idx, app_v in enumerate(self.apps): - hidden = self.filter_only_apps and app_v.model.is_library() + if self.pkgs: + visible_apps = len(self.pkgs) + for idx, app_v in enumerate(self.pkgs): + hidden = self.filter_only_apps and not app_v.model.is_application() if not hidden and self.type_filter is not None and self.type_filter != 'any': hidden = app_v.model.get_type() != self.type_filter @@ -443,9 +459,9 @@ class ManageWindow(QWidget): show_bt_upgrade = False app_updates, library_updates, not_installed = 0, 0, 0 - for app_v in self.apps: + for app_v in self.pkgs: if app_v.model.update: - if app_v.model.is_library(): + if not app_v.model.is_application(): library_updates += 1 else: app_updates += 1 @@ -453,7 +469,7 @@ class ManageWindow(QWidget): if not app_v.model.installed: not_installed += 1 - for app_v in self.apps: + for app_v in self.pkgs: if not_installed == 0 and app_v.visible and app_v.update_checked: show_bt_upgrade = True break @@ -492,21 +508,27 @@ class ManageWindow(QWidget): geo.moveCenter(center_point) self.move(geo.topLeft()) - def update_apps(self, apps: List[Application], update_check_enabled: bool = True): - self.apps = [] + def update_apps(self, apps: List[SoftwarePackage], as_installed: bool, update_check_enabled: bool = True): - napps = 0 # number of apps (not libraries) + napps = 0 # number of apps (not libraries, runtimes or something else) available_types = {} - if apps: + if apps is not None: + self.pkgs = [] for app in apps: - app_model = ApplicationView(model=app, visible=(not app.is_library()) or not self.checkbox_only_apps.isChecked()) + app_model = PackageView(model=app, visible=app.is_application() or not self.checkbox_only_apps.isChecked()) available_types[app.get_type()] = app.get_type_icon_path() - napps += 1 if not app.is_library() else 0 - self.apps.append(app_model) + napps += 1 if app.is_application() else 0 + self.pkgs.append(app_model) + + if as_installed: + self.pkgs_installed.append(app_model) + else: # use installed + self.pkgs = self.pkgs_installed + for app in self.pkgs: + napps += 1 if app.model.is_application() else 0 if napps == 0: - if self.first_refresh: self._begin_search('') self.thread_suggestions.start() @@ -519,13 +541,16 @@ class ManageWindow(QWidget): self.checkbox_only_apps.setChecked(True) self._update_type_filters(available_types) - self.table_apps.update_apps(self.apps, update_check_enabled=update_check_enabled) + self.table_apps.update_apps(self.pkgs, update_check_enabled=update_check_enabled) self.apply_filters() self.change_update_state() self.resize_and_center() - self.thread_verify_models.apps = self.apps - self.thread_verify_models.start() + if apps: + self.thread_verify_models.apps = self.pkgs + self.thread_verify_models.start() + + self.ref_bt_installed.setVisible(not as_installed) @staticmethod def _get_resized_icon(path: str, size: int) -> QIcon: @@ -569,12 +594,12 @@ class ManageWindow(QWidget): self.centralize() def update_selected(self): - if self.apps: + if self.pkgs: requires_root = False to_update = [] - for app_v in self.apps: + for app_v in self.pkgs: if app_v.visible and app_v.update_checked: to_update.append(app_v) @@ -631,6 +656,7 @@ class ManageWindow(QWidget): self.label_status.setText(action_label + "...") self.ref_bt_upgrade.setVisible(False) self.ref_bt_refresh.setVisible(False) + self.ref_bt_installed.setVisible(False) self.checkbox_only_apps.setEnabled(False) self.table_apps.setEnabled(False) self.checkbox_updates.setEnabled(False) @@ -663,7 +689,7 @@ class ManageWindow(QWidget): self.extra_filters.setEnabled(True) self.checkbox_updates.setEnabled(True) - def downgrade_app(self, app: ApplicationView): + def downgrade_app(self, app: PackageView): pwd = None requires_root = self.manager.requires_root('downgrade', app.model) @@ -728,12 +754,12 @@ class ManageWindow(QWidget): self.thread_search.word = word self.thread_search.start() - def _finish_search(self, apps_found: List[Application]): + def _finish_search(self, apps_found: List[SoftwarePackage]): self.finish_action() self.ref_bt_upgrade.setVisible(False) - self.update_apps(apps_found, update_check_enabled=False) + self.update_apps(apps_found, as_installed=False, update_check_enabled=False) - def install_app(self, app: ApplicationView): + def install_app(self, app: PackageView): pwd = None requires_root = self.manager.requires_root('install', app.model) @@ -750,7 +776,7 @@ class ManageWindow(QWidget): self.thread_install.root_password = pwd self.thread_install.start() - def _finish_install(self, app: ApplicationView): + def _finish_install(self, app: PackageView): self.input_search.setText('') self.finish_action()