diff --git a/CHANGELOG.md b/CHANGELOG.md
index d224c420..987cfb0f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [0.3.0]
### Features
+- Allows to retrieve app information and history by right clicking it.
- Allows app uninstall and downgrade by right clicking it.
### Improvements
diff --git a/fpakman/core/flatpak.py b/fpakman/core/flatpak.py
index 9933eea2..f8ba10be 100755
--- a/fpakman/core/flatpak.py
+++ b/fpakman/core/flatpak.py
@@ -4,6 +4,8 @@ from typing import List
from fpakman.core import system
+BASE_CMD = 'flatpak'
+
def app_str_to_json(line: str, version: str) -> dict:
@@ -39,22 +41,24 @@ def app_str_to_json(line: str, version: str) -> dict:
return app
-def get_app_info_fields(app_id: str, branch: str, fields: List[str], check_runtime: bool = False):
+def get_app_info_fields(app_id: str, branch: str, fields: List[str] = [], check_runtime: bool = False):
info = re.findall(r'\w+:\s.+', get_app_info(app_id, branch))
data = {}
fields_to_retrieve = len(fields) + (1 if check_runtime and 'ref' not in fields else 0)
for field in info:
- if fields_to_retrieve == 0:
+ if fields and fields_to_retrieve == 0:
break
field_val = field.split(':')
field_name = field_val[0].lower()
- if field_name in fields or (check_runtime and field_name == 'ref'):
+ if not fields or field_name in fields or (check_runtime and field_name == 'ref'):
data[field_name] = field_val[1].strip()
- fields_to_retrieve -= 1
+
+ if fields:
+ fields_to_retrieve -= 1
if check_runtime and field_name == 'ref':
data['runtime'] = data['ref'].startswith('runtime/')
@@ -63,16 +67,16 @@ def get_app_info_fields(app_id: str, branch: str, fields: List[str], check_runti
def get_version():
- res = system.run_cmd('flatpak --version')
+ res = system.run_cmd('{} --version'.format(BASE_CMD))
return res.split(' ')[1].strip() if res else None
def get_app_info(app_id: str, branch: str):
- return system.run_cmd('flatpak info {} {}'.format(app_id, branch))
+ return system.run_cmd('{} info {} {}'.format(BASE_CMD, app_id, branch))
def list_installed() -> List[dict]:
- apps_str = system.run_cmd('flatpak list')
+ apps_str = system.run_cmd('{} list'.format(BASE_CMD))
if apps_str:
version = get_version()
@@ -83,7 +87,7 @@ def list_installed() -> List[dict]:
def update(app_ref: str) -> bool:
- return bool(system.run_cmd('flatpak update -y ' + app_ref))
+ return bool(system.run_cmd('{} update -y {}'.format(BASE_CMD, app_ref)))
def update_and_stream(app_ref: str):
@@ -92,7 +96,7 @@ def update_and_stream(app_ref: str):
:param app_ref:
:return:
"""
- return system.stream_cmd(['flatpak', 'update', '-y', app_ref])
+ return system.stream_cmd([BASE_CMD, 'update', '-y', app_ref])
def uninstall_and_stream(app_ref: str):
@@ -101,11 +105,11 @@ def uninstall_and_stream(app_ref: str):
:param app_ref:
:return:
"""
- return system.stream_cmd(['flatpak', 'uninstall', app_ref, '-y'])
+ return system.stream_cmd([BASE_CMD, 'uninstall', app_ref, '-y'])
def list_updates_as_str():
- return system.run_cmd('flatpak update', ignore_return_code=True)
+ return system.run_cmd('{} update'.format(BASE_CMD), ignore_return_code=True)
def downgrade_and_stream(app_ref: str, commit: str, root_password: str):
@@ -114,12 +118,31 @@ def downgrade_and_stream(app_ref: str, commit: str, root_password: str):
if root_password is not None:
downgrade_cmd.extend(['sudo', '-S'])
- pwdin = subprocess.Popen(['echo', root_password], stdout=subprocess.PIPE).stdout
+ pwdin = system.stream_cmd(['echo', root_password])
- downgrade_cmd.extend(['flatpak', 'update', '--commit={}'.format(commit), app_ref, '-y'])
+ downgrade_cmd.extend([BASE_CMD, 'update', '--commit={}'.format(commit), app_ref, '-y'])
return subprocess.Popen(downgrade_cmd, stdin=pwdin, stdout=subprocess.PIPE, stderr=subprocess.DEVNULL).stdout
def get_app_commits(app_ref: str, origin: str) -> List[str]:
- log = system.run_cmd('flatpak remote-info --log {} {}'.format(origin, app_ref))
+ log = system.run_cmd('{} remote-info --log {} {}'.format(BASE_CMD, origin, app_ref))
return re.findall(r'Commit+:\s(.+)', log)
+
+
+def get_app_commits_data(app_ref: str, origin: str) -> List[dict]:
+ log = system.run_cmd('{} remote-info --log {} {}'.format(BASE_CMD, origin, app_ref))
+
+ res = re.findall(r'(Commit|Subject|Date):\s(.+)', log)
+
+ commits = []
+
+ commit = {}
+
+ for idx, data in enumerate(res):
+ commit[data[0].strip().lower()] = data[1].strip()
+
+ if (idx + 1) % 3 == 0:
+ commits.append(commit)
+ commit = {}
+
+ return commits
diff --git a/fpakman/core/system.py b/fpakman/core/system.py
index ddd5edfa..a7b1715b 100644
--- a/fpakman/core/system.py
+++ b/fpakman/core/system.py
@@ -3,9 +3,9 @@ from typing import List
def run_cmd(cmd: str, expected_code: int = 0, ignore_return_code: bool = False) -> str:
- res = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE)
+ res = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, env={'LANG': 'en'})
return res.stdout.decode() if ignore_return_code or res.returncode == expected_code else None
def stream_cmd(cmd: List[str]):
- return subprocess.Popen(cmd, stdout=subprocess.PIPE).stdout
+ return subprocess.Popen(cmd, stdout=subprocess.PIPE, env={'LANG': 'en'}).stdout
diff --git a/fpakman/resources/img/history.svg b/fpakman/resources/img/history.svg
new file mode 100755
index 00000000..e1f00f18
--- /dev/null
+++ b/fpakman/resources/img/history.svg
@@ -0,0 +1,218 @@
+
+
+
+
\ No newline at end of file
diff --git a/fpakman/resources/img/info.svg b/fpakman/resources/img/info.svg
new file mode 100755
index 00000000..7983485e
--- /dev/null
+++ b/fpakman/resources/img/info.svg
@@ -0,0 +1,154 @@
+
+
+
+
\ No newline at end of file
diff --git a/fpakman/resources/locale/en b/fpakman/resources/locale/en
index 3c1c96a5..b2a4787b 100644
--- a/fpakman/resources/locale/en
+++ b/fpakman/resources/locale/en
@@ -1,12 +1,8 @@
manage_window.title=Flatpak Application Manager
-manage_window.columns.name=Name
-manage_window.columns.version=Version
manage_window.columns.latest_version=Latest Version
-manage_window.columns.branch=Branch
-manage_window.columns.arch=Arch
-manage_window.columns.ref=Ref
-manage_window.columns.origin=Origin
manage_window.columns.update=Upgrade ?
+manage_window.apps_table.row.actions.info=Information
+manage_window.apps_table.row.actions.history=History
manage_window.apps_table.row.actions.uninstall=Uninstall
manage_window.apps_table.row.actions.uninstall.popup.title=Uninstall
manage_window.apps_table.row.actions.uninstall.popup.body=Remove {} ?
@@ -18,6 +14,8 @@ manage_window.status.refreshing=Refreshing
manage_window.status.upgrading=Upgrading
manage_window.status.uninstalling=Uninstalling
manage_window.status.downgrading=Downgrading
+manage_window.status.info=Retrieving information
+manage_window.status.history=Retrieving history
manage_window.bt.refresh.tooltip=Reload the data about installed applications
manage_window.bt.upgrade.tooltip=Upgrade all selected applications
popup.flatpak_not_installed.title=Error
@@ -28,9 +26,29 @@ popup.root.bad_password.title=Error
popup.root.bad_password.body=Wrong password
popup.downgrade.impossible.title=Impossible to downgrade
popup.downgrade.impossible.body=The app is in its first version
+popup.history.title=History
+popup.history.selected.tooltip=Current version
popup.button.yes=Yes
popup.button.no=No
popup.button.cancel=Cancel
tray.action.manage=Manage applications
tray.action.exit=Exit
-notification.new_updates=Updates found
\ No newline at end of file
+notification.new_updates=Updates found
+flatpak.info.arch=arch
+flatpak.info.branch=branch
+flatpak.info.collection=collection
+flatpak.info.commit=commit
+flatpak.info.date=date
+flatpak.info.id=id
+flatpak.info.installation=installation
+flatpak.info.installed=installed
+flatpak.info.license=license
+flatpak.info.name=name
+flatpak.info.origin=origin
+flatpak.info.parent=parent
+flatpak.info.ref=ref
+flatpak.info.runtime=runtime
+flatpak.info.sdk=sdk
+flatpak.info.subject=subject
+flatpak.info.type=type
+flatpak.info.version=version
\ No newline at end of file
diff --git a/fpakman/resources/locale/es b/fpakman/resources/locale/es
index ad3da9ff..e4c897fb 100644
--- a/fpakman/resources/locale/es
+++ b/fpakman/resources/locale/es
@@ -1,23 +1,21 @@
manage_window.title=Administrador de Aplicativos Flatpak
-manage_window.columns.name=Nombre
-manage_window.columns.version=Versión
manage_window.columns.latest_version=Ultima Versión
-manage_window.columns.branch=Rama
-manage_window.columns.arch=Arch
-manage_window.columns.ref=Ref
-manage_window.columns.origin=Origen
-manage_window.columns.update=¿Actualizar?
+manage_window.columns.update=Actualizar ?
+manage_window.apps_table.row.actions.info=Información
+manage_window.apps_table.row.actions.history=Historia
manage_window.apps_table.row.actions.uninstall=Desinstalar
manage_window.apps_table.row.actions.uninstall.popup.title=Desinstalación
manage_window.apps_table.row.actions.uninstall.popup.body=¿Eliminar {}?
manage_window.apps_table.row.actions.downgrade=Revertir versión
manage_window.apps_table.row.actions.downgrade.popup.body=¿Realmente quieres revertir la versión actual de {}?
-manage_window.checkbox.only_apps=Apps
+manage_window.checkbox.only_apps=Aplicativos
manage_window.label.updates=Actualizaciones
manage_window.status.refreshing=Recargando
manage_window.status.upgrading=Actualizando
manage_window.status.uninstalling=Desinstalando
manage_window.status.downgrading=Revirtiendo
+manage_window.status.info=Obteniendo información
+manage_window.status.history=Obteniendo la historia
manage_window.bt.refresh.tooltip=Recarga los datos sobre los aplicativos instalados
manage_window.bt.upgrade.tooltip=Actualiza todos los aplicativos seleccionados
popup.flatpak_not_installed.title=Error
@@ -28,9 +26,29 @@ popup.root.bad_password.title=Error
popup.root.bad_password.body=Contraseña incorrecta
popup.downgrade.impossible.title=Imposible revertir la versión
popup.downgrade.impossible.body=El aplicativo está en su primera versión
+popup.history.title=Historia
+popup.history.selected.tooltip=Versión actual
popup.button.yes=Sí
popup.button.no=No
popup.button.cancel=Cancelar
tray.action.manage=Administrar aplicativos
tray.action.exit=Salir
-notification.new_updates=Actualizaciones encontradas
\ No newline at end of file
+notification.new_updates=Actualizaciones encontradas
+flatpak.info.arch=arquitectura
+flatpak.info.branch=rama
+flatpak.info.collection=colección
+flatpak.info.commit=commit
+flatpak.info.date=fecha
+flatpak.info.id=id
+flatpak.info.installation=instalación
+flatpak.info.installed=instalado
+flatpak.info.license=licencia
+flatpak.info.name=nombre
+flatpak.info.origin=origen
+flatpak.info.parent=padre
+flatpak.info.ref=ref
+flatpak.info.runtime=runtime
+flatpak.info.sdk=sdk
+flatpak.info.subject=tema
+flatpak.info.type=tipo
+flatpak.info.version=versión
\ No newline at end of file
diff --git a/fpakman/resources/locale/pt b/fpakman/resources/locale/pt
index d917c4d2..5775be5e 100644
--- a/fpakman/resources/locale/pt
+++ b/fpakman/resources/locale/pt
@@ -1,23 +1,21 @@
manage_window.title=Gerenciador de Aplicativos Flatpak
-manage_window.columns.name=Nome
-manage_window.columns.version=Versão
manage_window.columns.latest_version=Última Versão
-manage_window.columns.branch=Ramo
-manage_window.columns.arch=Arch
-manage_window.columns.ref=Ref
-manage_window.columns.origin=Origem
manage_window.columns.update=Atualizar ?
+manage_window.apps_table.row.actions.info=Informação
+manage_window.apps_table.row.actions.history=Histórico
manage_window.apps_table.row.actions.uninstall=Desinstalar
manage_window.apps_table.row.actions.uninstall.popup.title=Desinstalação
manage_window.apps_table.row.actions.uninstall.popup.body=Remover {}?
manage_window.apps_table.row.actions.downgrade=Reverter versão
manage_window.apps_table.row.actions.downgrade.popup.body=Você realmente quer reverter a versão atual de {} ?
-manage_window.checkbox.only_apps=Apps
+manage_window.checkbox.only_apps=Aplicativos
manage_window.label.updates=Atualizações
manage_window.status.refreshing=Recarregando
manage_window.status.upgrading=Atualizando
manage_window.status.uninstalling=Desinstalando
manage_window.status.downgrading=Revertendo
+manage_window.status.info=Obtendo informação
+manage_window.status.history=Obtendo histórico
manage_window.bt.refresh.tooltip=Recarrega os dados sobre os aplicativos instalados
manage_window.bt.upgrade.tooltip=Atualiza todos os aplicativos selecionados
popup.flatpak_not_installed.title=Erro
@@ -28,9 +26,29 @@ popup.root.bad_password.title=Erro
popup.root.bad_password.body=Senha incorreta
popup.downgrade.impossible.title=Impossível reverter a versão
popup.downgrade.impossible.body=O aplicativo está na sua primeira versão
+popup.history.title=Histórico
+popup.history.selected.tooltip=Versão atual
popup.button.yes=Sim
popup.button.no=Não
popup.button.cancel=Cancelar
tray.action.manage=Gerenciar aplicativos
tray.action.exit=Sair
-notification.new_updates=Atualizações encontradas
\ No newline at end of file
+notification.new_updates=Atualizações encontradas
+flatpak.info.arch=arquitetura
+flatpak.info.branch=ramo
+flatpak.info.collection=coleção
+flatpak.info.commit=commit
+flatpak.info.date=data
+flatpak.info.id=id
+flatpak.info.installation=instalação
+flatpak.info.installed=instalado
+flatpak.info.license=licença
+flatpak.info.name=nome
+flatpak.info.origin=origem
+flatpak.info.parent=pai
+flatpak.info.ref=ref
+flatpak.info.runtime=runtime
+flatpak.info.sdk=sdk
+flatpak.info.subject=assunto
+flatpak.info.type=tipo
+flatpak.info.version=versão
\ No newline at end of file
diff --git a/fpakman/view/qt/apps_table.py b/fpakman/view/qt/apps_table.py
index 6478f64e..00b54437 100644
--- a/fpakman/view/qt/apps_table.py
+++ b/fpakman/view/qt/apps_table.py
@@ -1,12 +1,13 @@
+import json
from typing import List
-from PyQt5.QtCore import Qt, QUrl
+from PyQt5.QtCore import Qt, QUrl, QThread, pyqtSignal
from PyQt5.QtGui import QPixmap, QIcon, QColor, QCursor
from PyQt5.QtNetwork import QNetworkRequest, QNetworkAccessManager
from PyQt5.QtWidgets import QTableWidget, QTableView, QMenu, QAction, QTableWidgetItem, QToolButton, QWidget, \
- QMessageBox, QHeaderView
+ QMessageBox, QHeaderView, QDialog, QLineEdit, QVBoxLayout, QPlainTextEdit
-from fpakman.core import resource
+from fpakman.core import resource, flatpak
from fpakman.core.controller import FlatpakController
from fpakman.view.qt import dialog
@@ -48,8 +49,6 @@ class AppsTable(QTableWidget):
self.setHorizontalHeaderLabels(columns)
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.icon_flathub = QIcon(resource.get_path('img/flathub_45.svg'))
- self.icon_uninstall = QIcon(resource.get_path('img/uninstall.svg'))
- self.icon_downgrade = QIcon(resource.get_path('img/downgrade.svg'))
self.network_man = QNetworkAccessManager()
self.network_man.finished.connect(self._load_icon)
@@ -59,28 +58,41 @@ class AppsTable(QTableWidget):
def contextMenuEvent(self, QContextMenuEvent): # selected row right click event
menu_row = QMenu()
+ action_info = QAction(self.parent.locale_keys["manage_window.apps_table.row.actions.info"])
+ action_info.setIcon(QIcon(resource.get_path('img/info.svg')))
+ action_info.triggered.connect(self._get_app_info)
+ menu_row.addAction(action_info)
+
+ action_history = QAction(self.parent.locale_keys["manage_window.apps_table.row.actions.history"])
+ action_history.setIcon(QIcon(resource.get_path('img/history.svg')))
+ action_history.triggered.connect(self._get_app_history)
+ menu_row.addAction(action_history)
+
action_uninstall = QAction(self.parent.locale_keys["manage_window.apps_table.row.actions.uninstall"])
- action_uninstall.setIcon(self.icon_uninstall)
+ action_uninstall.setIcon(QIcon(resource.get_path('img/uninstall.svg')))
action_uninstall.triggered.connect(self._uninstall_app)
menu_row.addAction(action_uninstall)
- app = self._get_selected_app()
+ app = self.get_selected_app()
if not app['model']['runtime']: # downgrade only allowed for apps
action_downgrade = QAction(self.parent.locale_keys["manage_window.apps_table.row.actions.downgrade"])
action_downgrade.triggered.connect(self._downgrade_app)
- action_downgrade.setIcon(self.icon_downgrade)
+ action_downgrade.setIcon(QIcon(resource.get_path('img/downgrade.svg')))
menu_row.addAction(action_downgrade)
menu_row.adjustSize()
menu_row.popup(QCursor.pos())
menu_row.exec_()
- def _get_selected_app(self):
+ def get_selected_app(self):
return self.parent.apps[self.currentRow()]
+ def get_selected_app_icon(self):
+ return self.item(self.currentRow(), 0).icon()
+
def _uninstall_app(self):
- selected_app = self._get_selected_app()
+ selected_app = self.get_selected_app()
if dialog.ask_confirmation(title=self.parent.locale_keys['manage_window.apps_table.row.actions.uninstall.popup.title'],
body=self.parent.locale_keys['manage_window.apps_table.row.actions.uninstall.popup.body'].format(selected_app['model']['name']),
@@ -88,13 +100,19 @@ class AppsTable(QTableWidget):
self.parent.uninstall_app(selected_app['model']['ref'])
def _downgrade_app(self):
- selected_app = self._get_selected_app()
+ selected_app = self.get_selected_app()
if dialog.ask_confirmation(title=self.parent.locale_keys['manage_window.apps_table.row.actions.downgrade'],
body=self.parent.locale_keys['manage_window.apps_table.row.actions.downgrade.popup.body'].format(selected_app['model']['name']),
locale_keys=self.parent.locale_keys):
self.parent.downgrade_app(selected_app['model']['ref'])
+ def _get_app_info(self):
+ self.parent.get_app_info(self.get_selected_app())
+
+ def _get_app_history(self):
+ self.parent.get_app_history(self.get_selected_app())
+
def _load_icon(self, http_response):
icon_url = http_response.url().toString()
pixmap = QPixmap()
diff --git a/fpakman/view/qt/history.py b/fpakman/view/qt/history.py
new file mode 100644
index 00000000..5282fe97
--- /dev/null
+++ b/fpakman/view/qt/history.py
@@ -0,0 +1,52 @@
+import operator
+from functools import reduce
+
+from PyQt5.QtCore import Qt
+from PyQt5.QtGui import QIcon
+from PyQt5.QtWidgets import QDialog, QVBoxLayout, QTableWidget, QTableWidgetItem, QHeaderView
+
+
+class HistoryDialog(QDialog):
+
+ def __init__(self, app: dict, app_icon: QIcon, locale_keys: dict):
+ super(HistoryDialog, self).__init__()
+
+ self.setWindowTitle('{} - {} '.format(locale_keys['popup.history.title'], app['model']['name']))
+ self.setWindowIcon(app_icon)
+
+ layout = QVBoxLayout()
+ self.setLayout(layout)
+
+ table_history = QTableWidget()
+ table_history.setFocusPolicy(Qt.NoFocus)
+ table_history.setShowGrid(False)
+ table_history.verticalHeader().setVisible(False)
+ table_history.setAlternatingRowColors(True)
+
+ table_history.setColumnCount(len(app['commits'][0]))
+ table_history.setRowCount(len(app['commits']))
+ table_history.setHorizontalHeaderLabels([locale_keys['flatpak.info.' + key].capitalize() for key in sorted(app['commits'][0].keys())])
+
+ for row, commit in enumerate(app['commits']):
+
+ current_app_commit = app['model']['commit'] == commit['commit']
+
+ for col, key in enumerate(sorted(commit.keys())):
+ item = QTableWidgetItem()
+ item.setText(commit[key])
+ item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled)
+
+ if current_app_commit:
+ item.setBackground(Qt.darkYellow)
+ item.setToolTip(locale_keys['popup.history.selected.tooltip'])
+
+ table_history.setItem(row, col, item)
+
+ layout.addWidget(table_history)
+
+ header_horizontal = table_history.horizontalHeader()
+ for i in range(0, table_history.columnCount()):
+ header_horizontal.setSectionResizeMode(i, QHeaderView.Stretch)
+
+ new_width = reduce(operator.add, [table_history.columnWidth(i) for i in range(table_history.columnCount())])
+ self.resize(new_width, table_history.height())
diff --git a/fpakman/view/qt/info.py b/fpakman/view/qt/info.py
new file mode 100644
index 00000000..db32fb30
--- /dev/null
+++ b/fpakman/view/qt/info.py
@@ -0,0 +1,34 @@
+from PyQt5.QtGui import QIcon
+from PyQt5.QtWidgets import QDialog, QVBoxLayout, QFormLayout, QGroupBox, \
+ QLineEdit, QLabel
+
+
+class InfoDialog(QDialog):
+
+ def __init__(self, app: dict, app_icon: QIcon, locale_keys: dict):
+ super(InfoDialog, self).__init__()
+ self.setWindowTitle(app['name'])
+ self.setWindowIcon(app_icon)
+ layout = QVBoxLayout()
+ self.setLayout(layout)
+
+ gbox_info_layout = QFormLayout()
+ gbox_info = QGroupBox()
+ gbox_info.setLayout(gbox_info_layout)
+ layout.addWidget(gbox_info)
+
+ for attr in sorted(app.keys()):
+
+ if attr != 'name':
+ text = QLineEdit()
+ text.setText(app[attr])
+ text.setStyleSheet("width: 400px")
+ text.setReadOnly(True)
+ text.setCursorPosition(0)
+
+ label = QLabel("{}: ".format(locale_keys.get('flatpak.info.' + attr, attr)).capitalize())
+ label.setStyleSheet("font-weight: bold")
+
+ gbox_info_layout.addRow(label, text)
+
+ self.adjustSize()
diff --git a/fpakman/view/qt/window.py b/fpakman/view/qt/window.py
index b6b09a27..137d9606 100755
--- a/fpakman/view/qt/window.py
+++ b/fpakman/view/qt/window.py
@@ -1,19 +1,22 @@
+import json
import operator
from functools import reduce
from threading import Lock
from typing import List
-from PyQt5.QtCore import QThread, pyqtSignal, QEvent
+from PyQt5.QtCore import QThread, pyqtSignal, QEvent, Qt
from PyQt5.QtGui import QIcon, QWindowStateChangeEvent
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QApplication, QCheckBox, QHeaderView, QToolButton, QToolBar, \
- QSizePolicy, QLabel, QMessageBox, QPlainTextEdit
-from fpakman.core.model import FlatpakManager, ImpossibleDowngradeException
+ QSizePolicy, QLabel, QPlainTextEdit, QDialog, QGroupBox, QFormLayout, QLineEdit, QTableWidget, QTableWidgetItem
from fpakman import __version__
-from fpakman.core import resource
+from fpakman.core import resource, flatpak
from fpakman.core.controller import FlatpakController
+from fpakman.core.model import FlatpakManager, ImpossibleDowngradeException
from fpakman.view.qt import dialog
from fpakman.view.qt.apps_table import AppsTable
+from fpakman.view.qt.history import HistoryDialog
+from fpakman.view.qt.info import InfoDialog
from fpakman.view.qt.root import is_root, ask_root_password
@@ -21,17 +24,17 @@ class ManageWindow(QWidget):
__BASE_HEIGHT__ = 400
- def __init__(self, locale_keys: dict, controller: FlatpakController, manager: FlatpakManager, tray_icon = None):
+ def __init__(self, locale_keys: dict, controller: FlatpakController, manager: FlatpakManager, tray_icon=None):
super(ManageWindow, self).__init__()
self.locale_keys = locale_keys
- self.column_names = [locale_keys['manage_window.columns.name'],
- locale_keys['manage_window.columns.version'],
- locale_keys['manage_window.columns.latest_version'],
- locale_keys['manage_window.columns.branch'],
- locale_keys['manage_window.columns.arch'],
- locale_keys['manage_window.columns.ref'],
- locale_keys['manage_window.columns.origin'],
- locale_keys['manage_window.columns.update']]
+ self.column_names = [locale_keys[key].capitalize() for key in ['flatpak.info.name',
+ 'flatpak.info.version',
+ 'manage_window.columns.latest_version',
+ 'flatpak.info.branch',
+ 'flatpak.info.arch',
+ 'flatpak.info.ref',
+ 'flatpak.info.origin',
+ 'manage_window.columns.update']]
self.controller = controller
self.manager = manager
self.tray_icon = tray_icon
@@ -112,6 +115,12 @@ class ManageWindow(QWidget):
self.thread_downgrade.signal_output.connect(self._update_action_output)
self.thread_downgrade.signal_finished.connect(self._finish_downgrade)
+ self.thread_get_info = GetAppInfo()
+ self.thread_get_info.signal_finished.connect(self._finish_get_info)
+
+ self.thread_get_history = GetAppHistory()
+ self.thread_get_history.signal_finished.connect(self._finish_get_history)
+
self.toolbar_bottom = QToolBar()
self.label_updates = QLabel('')
self.toolbar_bottom.addWidget(self.label_updates)
@@ -174,7 +183,7 @@ class ManageWindow(QWidget):
if self._acquire_lock():
self._check_flatpak_installed()
- self._begin_action(self.locale_keys['manage_window.status.refreshing'] + '...')
+ self._begin_action(self.locale_keys['manage_window.status.refreshing'])
if clear_output:
self.textarea_output.clear()
@@ -194,7 +203,7 @@ class ManageWindow(QWidget):
if self._acquire_lock():
self.textarea_output.clear()
self.textarea_output.setVisible(True)
- self._begin_action(self.locale_keys['manage_window.status.uninstalling'] + '...')
+ self._begin_action(self.locale_keys['manage_window.status.uninstalling'])
self.thread_uninstall.app_ref = app_ref
self.thread_uninstall.start()
@@ -303,7 +312,7 @@ class ManageWindow(QWidget):
self.textarea_output.clear()
self.textarea_output.setVisible(True)
- self._begin_action(self.locale_keys['manage_window.status.upgrading'] + '...')
+ self._begin_action(self.locale_keys['manage_window.status.upgrading'])
self.thread_update.refs_to_update = to_update
self.thread_update.start()
@@ -316,7 +325,7 @@ class ManageWindow(QWidget):
self.textarea_output.appendPlainText(output)
def _begin_action(self, action_label: str):
- self.label_status.setText(action_label)
+ self.label_status.setText(action_label + "...")
self.bt_upgrade.setEnabled(False)
self.bt_refresh.setEnabled(False)
self.checkbox_only_apps.setEnabled(False)
@@ -345,12 +354,44 @@ class ManageWindow(QWidget):
self.textarea_output.clear()
self.textarea_output.setVisible(True)
- self._begin_action(self.locale_keys['manage_window.status.downgrading'] + '...')
+ self._begin_action(self.locale_keys['manage_window.status.downgrading'])
self.thread_downgrade.app_ref = app_ref
self.thread_downgrade.root_password = pwd
self.thread_downgrade.start()
+ def get_app_info(self, app: dict):
+
+ if self._acquire_lock():
+ self.textarea_output.clear()
+ self.textarea_output.setVisible(False)
+ self._begin_action(self.locale_keys['manage_window.status.info'])
+
+ self.thread_get_info.app = app
+ self.thread_get_info.start()
+
+ def get_app_history(self, app: dict):
+ if self._acquire_lock():
+ self.textarea_output.clear()
+ self.textarea_output.setVisible(False)
+ self._begin_action(self.locale_keys['manage_window.status.history'])
+
+ self.thread_get_history.app = app
+ self.thread_get_history.start()
+
+ def _finish_get_info(self, app_info: dict):
+ self._release_lock()
+ self.finish_action()
+ dialog_info = InfoDialog(app_info, self.table_apps.get_selected_app_icon(), self.locale_keys)
+ dialog_info.exec_()
+
+ def _finish_get_history(self, app: dict):
+ self._release_lock()
+ self.finish_action()
+
+ dialog_history = HistoryDialog(app, self.table_apps.get_selected_app_icon(), self.locale_keys)
+ dialog_history.exec_()
+
# Threaded actions
class UpdateSelectedApps(QThread):
@@ -433,3 +474,33 @@ class DowngradeApp(QThread):
self.app_ref = None
self.root_password = None
self.signal_finished.emit()
+
+
+class GetAppInfo(QThread):
+ signal_finished = pyqtSignal(dict)
+
+ def __init__(self):
+ super(GetAppInfo, self).__init__()
+ self.app = None
+
+ def run(self):
+ if self.app:
+ app_info = flatpak.get_app_info_fields(self.app['model']['id'], self.app['model']['branch'])
+ app_info['name'] = self.app['model']['name']
+ app_info['type'] = 'runtime' if self.app['model']['runtime'] else 'app'
+ self.signal_finished.emit(app_info)
+ self.app = None
+
+
+class GetAppHistory(QThread):
+ signal_finished = pyqtSignal(dict)
+
+ def __init__(self):
+ super(GetAppHistory, self).__init__()
+ self.app = None
+
+ def run(self):
+ if self.app:
+ commits = flatpak.get_app_commits_data(self.app['model']['ref'], self.app['model']['origin'])
+ self.signal_finished.emit({'model': self.app['model'], 'commits': commits})
+ self.app = None