installed button

This commit is contained in:
Vinicius Moreira
2019-08-29 12:56:40 -03:00
parent a0a93ce62f
commit 503241e522
11 changed files with 131 additions and 99 deletions

View File

@@ -1,10 +1,10 @@
from argparse import Namespace from argparse import Namespace
from threading import Thread 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.controller import ApplicationManager, SearchResult
from bauh_api.abstract.handler import ProcessWatcher 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 DiskCacheLoader
from bauh_api.util.disk import DiskCacheLoaderFactory 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._enabled_map = {} if app_args.check_packaging_once else None
self.thread_prepare = 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 = [], [], [] exact_name_matches, contains_name_matches, others = [], [], []
@@ -96,7 +96,7 @@ class GenericApplicationManager(ApplicationManager):
self.thread_prepare.join() self.thread_prepare.join()
self.thread_prepare = None 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() self._wait_to_be_ready()
installed = [] installed = []
@@ -119,7 +119,7 @@ class GenericApplicationManager(ApplicationManager):
return installed 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) man = self._get_manager_for(app)
if man and app.can_be_downgraded(): if man and app.can_be_downgraded():
@@ -127,37 +127,37 @@ class GenericApplicationManager(ApplicationManager):
else: else:
raise Exception("downgrade is not possible for {}".format(app.__class__.__name__)) 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) man = self._get_manager_for(app)
if man: if man:
return man.clean_cache_for(app) 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) man = self._get_manager_for(app)
if man: if man:
return man.update(app, root_password, handler) 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) man = self._get_manager_for(app)
if man: if man:
return man.uninstall(app, root_password, handler) 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) man = self._get_manager_for(app)
if man: if man:
return man.install(app, root_password, handler) 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) man = self._get_manager_for(app)
if man: if man:
return man.get_info(app) 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) man = self._get_manager_for(app)
if man: if man:
@@ -169,24 +169,24 @@ class GenericApplicationManager(ApplicationManager):
def is_enabled(self): def is_enabled(self):
return True return True
def _get_manager_for(self, app: Application) -> ApplicationManager: def _get_manager_for(self, app: SoftwarePackage) -> ApplicationManager:
man = self.map[app.__class__] man = self.map[app.__class__]
return man if man and self._is_enabled(man) else None 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(): if self.disk_loader_factory.disk_cache and app.supports_disk_cache():
man = self._get_manager_for(app) man = self._get_manager_for(app)
if man: if man:
return man.cache_to_disk(app, icon_bytes=icon_bytes, only_icon=only_icon) 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) man = self._get_manager_for(app)
if man: if man:
return man.requires_root(action, app) 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() self._wait_to_be_ready()
man = self._get_manager_for(app) man = self._get_manager_for(app)
@@ -204,7 +204,7 @@ class GenericApplicationManager(ApplicationManager):
self.thread_prepare = Thread(target=self._prepare) self.thread_prepare = Thread(target=self._prepare)
self.thread_prepare.start() self.thread_prepare.start()
def list_updates(self) -> List[ApplicationUpdate]: def list_updates(self) -> List[PackageUpdate]:
self._wait_to_be_ready() self._wait_to_be_ready()
updates = [] updates = []
@@ -242,7 +242,7 @@ class GenericApplicationManager(ApplicationManager):
if man_sugs: if man_sugs:
suggestions.extend(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: if self.managers:
suggestions, threads = [], [] suggestions, threads = [], []
for man in self.managers: for man in self.managers:

BIN
bauh/resources/img/disk.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 820 B

View File

@@ -30,6 +30,8 @@ manage_window.bt.refresh.text=Refresh
manage_window.bt.refresh.tooltip=Reload the data about installed applications manage_window.bt.refresh.tooltip=Reload the data about installed applications
manage_window.bt.upgrade.text=Upgrade manage_window.bt.upgrade.text=Upgrade
manage_window.bt.upgrade.tooltip=Upgrade all checked applications 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 manage_window.checkbox.show_details=Show details
popup.root.title=Requires root privileges popup.root.title=Requires root privileges
popup.root.password=Password popup.root.password=Password

View File

@@ -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.refresh.tooltip=Recarga los datos sobre los aplicativos instalados
manage_window.bt.upgrade.text=Actualizar manage_window.bt.upgrade.text=Actualizar
manage_window.bt.upgrade.tooltip=Actualiza todos los aplicativos marcados 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 manage_window.checkbox.show_details=Mostrar detalles
popup.root.title=Requiere privilegios de root popup.root.title=Requiere privilegios de root
popup.root.password=Contraseña popup.root.password=Contraseña

View File

@@ -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.refresh.tooltip=Recarrega os dados sobre os aplicativos instalados
manage_window.bt.upgrade.text=Atualizar manage_window.bt.upgrade.text=Atualizar
manage_window.bt.upgrade.tooltip=Atualiza todos os aplicativos marcados 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 manage_window.checkbox.show_details=Mostrar detalhes
popup.root.title=Requer privilégios de root popup.root.title=Requer privilégios de root
popup.root.password=Senha popup.root.password=Senha

View File

@@ -7,13 +7,13 @@ from PyQt5.QtGui import QPixmap, QIcon, QCursor
from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest from PyQt5.QtNetwork import QNetworkAccessManager, QNetworkRequest
from PyQt5.QtWidgets import QTableWidget, QTableView, QMenu, QAction, QTableWidgetItem, QToolButton, QWidget, \ from PyQt5.QtWidgets import QTableWidget, QTableView, QMenu, QAction, QTableWidgetItem, QToolButton, QWidget, \
QHeaderView, QLabel, QHBoxLayout, QPushButton, QToolBar 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_api.util.cache import Cache
from bauh.core import resource from bauh.core import resource
from bauh.util import util from bauh.util import util
from bauh.view.qt import dialog 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' INSTALL_BT_STYLE = 'background: {back}; color: white; font-size: 10px; font-weight: bold'
@@ -41,7 +41,7 @@ class IconButton(QWidget):
class UpdateToggleButton(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__() super(UpdateToggleButton, self).__init__()
self.app_view = app_view self.app_view = app_view
@@ -100,12 +100,12 @@ class AppsTable(QTableWidget):
self.lock_async_data = Lock() self.lock_async_data = Lock()
self.setRowHeight(80,80) 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 \ return app_v.model.can_be_refreshed() or \
app_v.model.has_history() or \ app_v.model.has_history() or \
app_v.model.can_be_downgraded() app_v.model.can_be_downgraded()
def show_app_settings(self, app: ApplicationView): def show_app_settings(self, app: PackageView):
menu_row = QMenu() menu_row = QMenu()
if app.model.installed: if app.model.installed:
@@ -148,11 +148,11 @@ class AppsTable(QTableWidget):
menu_row.exec_() menu_row.exec_()
def fill_async_data(self): 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: if self.download_icons:
self.network_man.get(QNetworkRequest(QUrl(app_v.model.base_data.icon_url))) 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_version(idx, app_v)
self._set_col_description(idx, app_v) self._set_col_description(idx, app_v)
self._set_col_settings(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() self.window.resize_and_center()
def get_selected_app(self) -> ApplicationView: def get_selected_app(self) -> PackageView:
return self.window.apps[self.currentRow()] return self.window.pkgs[self.currentRow()]
def get_selected_app_icon(self) -> QIcon: def get_selected_app_icon(self) -> QIcon:
return self.item(self.currentRow(), 0).icon() 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'], 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)))), 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): locale_keys=self.window.locale_keys):
@@ -196,7 +196,7 @@ class AppsTable(QTableWidget):
def _get_app_history(self): def _get_app_history(self):
self.window.get_app_history(self.get_selected_app()) 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( if dialog.ask_confirmation(
title=self.window.locale_keys['manage_window.apps_table.row.actions.install.popup.title'], 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} icon_data = {'icon': icon, 'bytes': icon_bytes}
self.icon_cache.add(icon_url, icon_data) 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: if app.model.base_data.icon_url == icon_url:
col_name = self.item(idx, 0) col_name = self.item(idx, 0)
col_name.setIcon(icon_data['icon']) 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()): 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) 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): def update_apps(self, pkg_views: List[PackageView], update_check_enabled: bool = True):
self.setRowCount(len(app_views) if app_views else 0) self.setRowCount(len(pkg_views) if pkg_views else 0)
self.setEnabled(True) self.setEnabled(True)
if app_views: if pkg_views:
for idx, app_v in enumerate(app_views): for idx, app_v in enumerate(pkg_views):
self._set_col_name(idx, app_v) self._set_col_name(idx, app_v)
self._set_col_version(idx, app_v) self._set_col_version(idx, app_v)
self._set_col_description(idx, app_v) self._set_col_description(idx, app_v)
@@ -270,7 +270,7 @@ class AppsTable(QTableWidget):
return col 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.installed:
if app_v.model.can_be_uninstalled(): if app_v.model.can_be_uninstalled():
@@ -292,7 +292,7 @@ class AppsTable(QTableWidget):
self.setCellWidget(idx, 4, col) 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() col_type = QLabel()
pixmap = QPixmap(app_v.model.get_default_icon_path()) pixmap = QPixmap(app_v.model.get_default_icon_path())
col_type.setPixmap(pixmap.scaled(16, 16, Qt.KeepAspectRatio, Qt.SmoothTransformation)) 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())) col_type.setToolTip('{}: {}'.format(self.window.locale_keys['type'], app_v.model.get_type()))
self.setCellWidget(idx, 3, col_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 = QLabel(app_v.model.base_data.version if app_v.model.base_data.version else '?')
label_version.setAlignment(Qt.AlignCenter) label_version.setAlignment(Qt.AlignCenter)
@@ -324,7 +324,7 @@ class AppsTable(QTableWidget):
col_version.setToolTip(tooltip) col_version.setToolTip(tooltip)
self.setCellWidget(idx, 1, col_version) 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 = QTableWidgetItem()
col.setText(app_v.model.base_data.name if app_v.model.base_data.name else '...') col.setText(app_v.model.base_data.name if app_v.model.base_data.name else '...')
col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
@@ -347,11 +347,11 @@ class AppsTable(QTableWidget):
col.setIcon(icon) col.setIcon(icon)
self.setItem(idx, 0, col) 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 = QTableWidgetItem()
col.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) 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 desc = app_v.model.base_data.description
else: else:
desc = '...' desc = '...'
@@ -366,7 +366,7 @@ class AppsTable(QTableWidget):
self.setItem(idx, 2, col) 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() tb = QToolBar()
if app_v.model.can_be_run() and app_v.model.get_command(): if app_v.model.can_be_run() and app_v.model.get_command():

View File

@@ -4,13 +4,13 @@ from functools import reduce
from PyQt5.QtCore import Qt from PyQt5.QtCore import Qt
from PyQt5.QtGui import QColor from PyQt5.QtGui import QColor
from PyQt5.QtWidgets import QDialog, QVBoxLayout, QTableWidget, QTableWidgetItem, QHeaderView 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 from bauh_api.util.cache import Cache
class HistoryDialog(QDialog): 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__() super(HistoryDialog, self).__init__()
self.setWindowTitle('{} - {} '.format(locale_keys['popup.history.title'], app_history.app.base_data.name)) self.setWindowTitle('{} - {} '.format(locale_keys['popup.history.title'], app_history.app.base_data.name))

View File

@@ -5,7 +5,7 @@ from typing import List
from PyQt5.QtCore import QThread, pyqtSignal, QCoreApplication, Qt from PyQt5.QtCore import QThread, pyqtSignal, QCoreApplication, Qt
from PyQt5.QtGui import QIcon from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QSystemTrayIcon, QMenu 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 import __app_name__
from bauh.core import resource from bauh.core import resource
@@ -84,7 +84,7 @@ class TrayIcon(QSystemTrayIcon):
def _verify_updates(self, notify_user: bool): def _verify_updates(self, notify_user: bool):
self.notify_updates(self.manager.list_updates(), notify_user=notify_user) 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() self.lock_notify.acquire()

View File

@@ -7,12 +7,12 @@ import requests
from PyQt5.QtCore import QThread, pyqtSignal from PyQt5.QtCore import QThread, pyqtSignal
from bauh_api.abstract.controller import ApplicationManager from bauh_api.abstract.controller import ApplicationManager
from bauh_api.abstract.handler import ProcessWatcher 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.abstract.view import InputViewComponent, MessageType
from bauh_api.exception import NoInternetException from bauh_api.exception import NoInternetException
from bauh_api.util.cache import Cache 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): class AsyncAction(QThread, ProcessWatcher):
@@ -62,7 +62,7 @@ class AsyncAction(QThread, ProcessWatcher):
class UpdateSelectedApps(AsyncAction): 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__() super(UpdateSelectedApps, self).__init__()
self.apps_to_update = apps_to_update self.apps_to_update = apps_to_update
self.manager = manager self.manager = manager
@@ -92,7 +92,7 @@ class UpdateSelectedApps(AsyncAction):
class RefreshApps(AsyncAction): class RefreshApps(AsyncAction):
def __init__(self, manager: ApplicationManager, app: ApplicationView = None): def __init__(self, manager: ApplicationManager, app: PackageView = None):
super(RefreshApps, self).__init__() super(RefreshApps, self).__init__()
self.manager = manager self.manager = manager
self.app = app # app that should be on list top self.app = app # app that should be on list top
@@ -118,7 +118,7 @@ class RefreshApps(AsyncAction):
class UninstallApp(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__() super(UninstallApp, self).__init__()
self.app = app self.app = app
self.manager = manager self.manager = manager
@@ -140,7 +140,7 @@ class UninstallApp(AsyncAction):
class DowngradeApp(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__() super(DowngradeApp, self).__init__()
self.manager = manager self.manager = manager
self.app = app self.app = app
@@ -163,7 +163,7 @@ class DowngradeApp(AsyncAction):
class GetAppInfo(AsyncAction): class GetAppInfo(AsyncAction):
def __init__(self, manager: ApplicationManager, app: ApplicationView = None): def __init__(self, manager: ApplicationManager, app: PackageView = None):
super(GetAppInfo, self).__init__() super(GetAppInfo, self).__init__()
self.app = app self.app = app
self.manager = manager self.manager = manager
@@ -178,7 +178,7 @@ class GetAppInfo(AsyncAction):
class GetAppHistory(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__() super(GetAppHistory, self).__init__()
self.app = app self.app = app
self.manager = manager self.manager = manager
@@ -214,7 +214,7 @@ class SearchApps(AsyncAction):
class InstallApp(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__() super(InstallApp, self).__init__()
self.app = app self.app = app
self.manager = manager self.manager = manager
@@ -279,7 +279,7 @@ class VerifyModels(QThread):
signal_updates = pyqtSignal() signal_updates = pyqtSignal()
def __init__(self, apps: List[ApplicationView] = None): def __init__(self, apps: List[PackageView] = None):
super(VerifyModels, self).__init__() super(VerifyModels, self).__init__()
self.apps = apps self.apps = apps
@@ -294,7 +294,7 @@ class VerifyModels(QThread):
current_ready = 0 current_ready = 0
for app in self.apps: 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: if current_ready > last_ready:
last_ready = current_ready last_ready = current_ready
@@ -314,7 +314,7 @@ class VerifyModels(QThread):
class RefreshApp(AsyncAction): class RefreshApp(AsyncAction):
def __init__(self, manager: ApplicationManager, app: ApplicationView = None): def __init__(self, manager: ApplicationManager, app: PackageView = None):
super(RefreshApp, self).__init__() super(RefreshApp, self).__init__()
self.app = app self.app = app
self.manager = manager self.manager = manager
@@ -363,7 +363,7 @@ class ListWarnings(QThread):
class RunApp(AsyncAction): class RunApp(AsyncAction):
def __init__(self, app: ApplicationView = None): def __init__(self, app: PackageView = None):
super(RunApp, self).__init__() super(RunApp, self).__init__()
self.app = app self.app = app

View File

@@ -1,20 +1,20 @@
from enum import Enum 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 LOADING = 0
READY = 1 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.model = model
self.update_checked = model.update self.update_checked = model.update
self.visible = visible self.visible = visible
self.status = ApplicationViewStatus.LOADING self.status = PackageViewStatus.LOADING
def __repr__(self): def __repr__(self):
return '{} ( {} )'.format(self.model.base_data.name, self.model.get_type()) return '{} ( {} )'.format(self.model.base_data.name, self.model.get_type())

View File

@@ -7,7 +7,7 @@ from PyQt5.QtGui import QIcon, QWindowStateChangeEvent, QPixmap
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QApplication, QCheckBox, QHeaderView, QToolButton, QToolBar, \ from PyQt5.QtWidgets import QWidget, QVBoxLayout, QApplication, QCheckBox, QHeaderView, QToolButton, QToolBar, \
QLabel, QPlainTextEdit, QLineEdit, QProgressBar, QHBoxLayout, QPushButton, QComboBox QLabel, QPlainTextEdit, QLineEdit, QProgressBar, QHBoxLayout, QPushButton, QComboBox
from bauh_api.abstract.controller import ApplicationManager 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.abstract.view import MessageType
from bauh_api.util.cache import Cache 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, \ from bauh.view.qt.thread import UpdateSelectedApps, RefreshApps, UninstallApp, DowngradeApp, GetAppInfo, \
GetAppHistory, SearchApps, InstallApp, AnimateProgress, VerifyModels, RefreshApp, FindSuggestions, ListWarnings, \ GetAppHistory, SearchApps, InstallApp, AnimateProgress, VerifyModels, RefreshApp, FindSuggestions, ListWarnings, \
AsyncAction, RunApp AsyncAction, RunApp
from bauh.view.qt.view_model import ApplicationView from bauh.view.qt.view_model import PackageView
DARK_ORANGE = '#FF4500' DARK_ORANGE = '#FF4500'
@@ -43,7 +43,8 @@ class ManageWindow(QWidget):
self.manager = manager self.manager = manager
self.tray_icon = tray_icon self.tray_icon = tray_icon
self.working = False # restrict the number of threaded actions self.working = False # restrict the number of threaded actions
self.apps = [] self.pkgs = []
self.pkgs_installed = []
self.label_flatpak = None self.label_flatpak = None
self.icon_cache = icon_cache self.icon_cache = icon_cache
self.disk_cache = disk_cache self.disk_cache = disk_cache
@@ -111,6 +112,14 @@ class ManageWindow(QWidget):
self.toolbar.addWidget(new_spacer()) 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 = QPushButton()
self.bt_refresh.setToolTip(locale_keys['manage_window.bt.refresh.tooltip']) self.bt_refresh.setToolTip(locale_keys['manage_window.bt.refresh.tooltip'])
self.bt_refresh.setIcon(QIcon(resource.get_path('img/new_refresh.svg'))) 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(): if not self.thread_warnings.isFinished():
self.thread_warnings.start() 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): def _show_about(self):
if self.dialog_about is None: if self.dialog_about is None:
self.dialog_about = AboutDialog(self.locale_keys) self.dialog_about = AboutDialog(self.locale_keys)
@@ -302,7 +318,7 @@ class ManageWindow(QWidget):
self.checkbox_console.setChecked(False) self.checkbox_console.setChecked(False)
self.textarea_output.hide() 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.type_filter = None
self.input_search.clear() self.input_search.clear()
@@ -318,14 +334,14 @@ class ManageWindow(QWidget):
self.thread_refresh.start() self.thread_refresh.start()
def _finish_refresh_apps(self, apps: List[Application]): def _finish_refresh_apps(self, apps: List[SoftwarePackage]):
self.finish_action() self.finish_action()
self.ref_checkbox_only_apps.setVisible(True) self.ref_checkbox_only_apps.setVisible(True)
self.ref_bt_upgrade.setVisible(True) self.ref_bt_upgrade.setVisible(True)
self.update_apps(apps) self.update_apps(apps, as_installed=True)
self.first_refresh = False self.first_refresh = False
def uninstall_app(self, app: ApplicationView): def uninstall_app(self, app: PackageView):
pwd = None pwd = None
requires_root = self.manager.requires_root('uninstall', app.model) 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.root_password = pwd
self.thread_uninstall.start() 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._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.app = app
self.thread_run_app.start() self.thread_run_app.start()
def refresh(self, app: ApplicationView): def refresh(self, app: PackageView):
pwd = None pwd = None
requires_root = self.manager.requires_root('refresh', app.model) 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.root_password = pwd
self.thread_refresh_app.start() self.thread_refresh_app.start()
def _finish_uninstall(self, app: ApplicationView): def _finish_uninstall(self, app: PackageView):
self.finish_action() self.finish_action()
if app: if app:
@@ -417,10 +433,10 @@ class ManageWindow(QWidget):
self.toolbar_substatus.show() self.toolbar_substatus.show()
def apply_filters(self): def apply_filters(self):
if self.apps: if self.pkgs:
visible_apps = len(self.apps) visible_apps = len(self.pkgs)
for idx, app_v in enumerate(self.apps): for idx, app_v in enumerate(self.pkgs):
hidden = self.filter_only_apps and app_v.model.is_library() 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': if not hidden and self.type_filter is not None and self.type_filter != 'any':
hidden = app_v.model.get_type() != self.type_filter hidden = app_v.model.get_type() != self.type_filter
@@ -443,9 +459,9 @@ class ManageWindow(QWidget):
show_bt_upgrade = False show_bt_upgrade = False
app_updates, library_updates, not_installed = 0, 0, 0 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.update:
if app_v.model.is_library(): if not app_v.model.is_application():
library_updates += 1 library_updates += 1
else: else:
app_updates += 1 app_updates += 1
@@ -453,7 +469,7 @@ class ManageWindow(QWidget):
if not app_v.model.installed: if not app_v.model.installed:
not_installed += 1 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: if not_installed == 0 and app_v.visible and app_v.update_checked:
show_bt_upgrade = True show_bt_upgrade = True
break break
@@ -492,21 +508,27 @@ class ManageWindow(QWidget):
geo.moveCenter(center_point) geo.moveCenter(center_point)
self.move(geo.topLeft()) self.move(geo.topLeft())
def update_apps(self, apps: List[Application], update_check_enabled: bool = True): def update_apps(self, apps: List[SoftwarePackage], as_installed: bool, update_check_enabled: bool = True):
self.apps = []
napps = 0 # number of apps (not libraries) napps = 0 # number of apps (not libraries, runtimes or something else)
available_types = {} available_types = {}
if apps: if apps is not None:
self.pkgs = []
for app in apps: 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() available_types[app.get_type()] = app.get_type_icon_path()
napps += 1 if not app.is_library() else 0 napps += 1 if app.is_application() else 0
self.apps.append(app_model) 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 napps == 0:
if self.first_refresh: if self.first_refresh:
self._begin_search('') self._begin_search('')
self.thread_suggestions.start() self.thread_suggestions.start()
@@ -519,13 +541,16 @@ class ManageWindow(QWidget):
self.checkbox_only_apps.setChecked(True) self.checkbox_only_apps.setChecked(True)
self._update_type_filters(available_types) 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.apply_filters()
self.change_update_state() self.change_update_state()
self.resize_and_center() self.resize_and_center()
self.thread_verify_models.apps = self.apps if apps:
self.thread_verify_models.start() self.thread_verify_models.apps = self.pkgs
self.thread_verify_models.start()
self.ref_bt_installed.setVisible(not as_installed)
@staticmethod @staticmethod
def _get_resized_icon(path: str, size: int) -> QIcon: def _get_resized_icon(path: str, size: int) -> QIcon:
@@ -569,12 +594,12 @@ class ManageWindow(QWidget):
self.centralize() self.centralize()
def update_selected(self): def update_selected(self):
if self.apps: if self.pkgs:
requires_root = False requires_root = False
to_update = [] to_update = []
for app_v in self.apps: for app_v in self.pkgs:
if app_v.visible and app_v.update_checked: if app_v.visible and app_v.update_checked:
to_update.append(app_v) to_update.append(app_v)
@@ -631,6 +656,7 @@ class ManageWindow(QWidget):
self.label_status.setText(action_label + "...") self.label_status.setText(action_label + "...")
self.ref_bt_upgrade.setVisible(False) self.ref_bt_upgrade.setVisible(False)
self.ref_bt_refresh.setVisible(False) self.ref_bt_refresh.setVisible(False)
self.ref_bt_installed.setVisible(False)
self.checkbox_only_apps.setEnabled(False) self.checkbox_only_apps.setEnabled(False)
self.table_apps.setEnabled(False) self.table_apps.setEnabled(False)
self.checkbox_updates.setEnabled(False) self.checkbox_updates.setEnabled(False)
@@ -663,7 +689,7 @@ class ManageWindow(QWidget):
self.extra_filters.setEnabled(True) self.extra_filters.setEnabled(True)
self.checkbox_updates.setEnabled(True) self.checkbox_updates.setEnabled(True)
def downgrade_app(self, app: ApplicationView): def downgrade_app(self, app: PackageView):
pwd = None pwd = None
requires_root = self.manager.requires_root('downgrade', app.model) requires_root = self.manager.requires_root('downgrade', app.model)
@@ -728,12 +754,12 @@ class ManageWindow(QWidget):
self.thread_search.word = word self.thread_search.word = word
self.thread_search.start() self.thread_search.start()
def _finish_search(self, apps_found: List[Application]): def _finish_search(self, apps_found: List[SoftwarePackage]):
self.finish_action() self.finish_action()
self.ref_bt_upgrade.setVisible(False) 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 pwd = None
requires_root = self.manager.requires_root('install', app.model) 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.root_password = pwd
self.thread_install.start() self.thread_install.start()
def _finish_install(self, app: ApplicationView): def _finish_install(self, app: PackageView):
self.input_search.setText('') self.input_search.setText('')
self.finish_action() self.finish_action()