Keep GUI responsive while processing diff results.

* src/vorta/views/archive_tab.py (ArchiveTab.list_diff_result): Start `ParseThread` that does the processing and creates the dialog.

* src/vorta/views/archive_tab.py (ArchiveTab.show_diff_result): Implement method showing `DiffResultDialog`.

* src/vorta/views/diff_result.py (ParseThread): Move processing of diff results to this thread.
This commit is contained in:
real-yfprojects 2022-04-18 18:53:46 +02:00
parent bdbc172157
commit 71aed9ba0e
No known key found for this signature in database
GPG Key ID: 00F630DFDEE25747
2 changed files with 57 additions and 22 deletions

View File

@ -31,6 +31,8 @@ from vorta.views.extract_dialog import ExtractDialog
from vorta.views.source_tab import SizeItem
from vorta.views.utils import get_colored_icon
from .diff_result import DiffTree, ParseThread
uifile = get_asset('UI/archivetab.ui')
ArchiveTabUI, ArchiveTabBase = uic.loadUiType(uifile)
@ -865,15 +867,28 @@ class ArchiveTab(ArchiveTabBase, ArchiveTabUI, BackupProfileMixin):
name=result['params']['archive_name_newer'])
archive_older = ArchiveModel.get(
name=result['params']['archive_name_older'])
window = DiffResultDialog(result['data'],
archive_newer, archive_older,
result['params']['json_lines'])
self._toggle_all_buttons(True)
window.setParent(self)
window.setWindowFlags(Qt.WindowType.Window)
window.setWindowModality(Qt.WindowModality.NonModal)
self._resultwindow = window # for testing
window.show()
self._set_status(self.tr("Processing diff results."))
model = DiffTree()
self._t = ParseThread(result['data'], result['params']['json_lines'],
model)
self._t.finished.connect(lambda: self.show_diff_result(
archive_newer, archive_older, model))
self._t.start()
def show_diff_result(self, archive_newer, archive_older, model):
self._t = None
# show dialog
self._toggle_all_buttons(True)
self._set_status('')
window = DiffResultDialog(archive_newer, archive_older, model)
window.setParent(self)
window.setWindowFlags(Qt.WindowType.Window)
window.setWindowModality(Qt.WindowModality.NonModal)
self._resultwindow = window # for testing
window.show()
def rename_action(self):
profile = self.profile()

View File

@ -7,7 +7,7 @@ from pathlib import PurePath
from typing import List, Optional, Tuple
from PyQt5 import uic
from PyQt5.QtCore import QMimeData, QModelIndex, QPoint, Qt, QUrl
from PyQt5.QtCore import QMimeData, QModelIndex, QPoint, Qt, QThread, QUrl
from PyQt5.QtGui import QColor, QKeySequence
from PyQt5.QtWidgets import (QApplication, QHeaderView, QMenu, QShortcut,
QTreeView)
@ -24,33 +24,53 @@ DiffResultUI, DiffResultBase = uic.loadUiType(uifile)
logger = logging.getLogger(__name__)
class DiffResultDialog(DiffResultBase, DiffResultUI):
"""Display the results of `borg diff`."""
class ParseThread(QThread):
"""A thread parsing diff results."""
def __init__(self, fs_data, archive_newer, archive_older, json_lines):
def __init__(self,
fs_data: str,
json_lines: bool,
model: 'DiffTree',
parent=None):
"""Init."""
super().__init__()
self.setupUi(self)
self.model = DiffTree(self)
super().__init__(parent)
self.model = model
self.fs_data = fs_data
self.json_lines = json_lines
def run(self) -> None:
"""Do the work"""
# Older version do not support json output
if json_lines:
if self.json_lines:
# If fs_data is already a dict, then there was just a single json-line
# and the default handler already parsed into json dict, otherwise
# fs_data is a str, and needs to be split and parsed into json dicts
if isinstance(fs_data, dict):
lines = [fs_data]
if isinstance(self.fs_data, dict):
lines = [self.fs_data]
else:
lines = [
json.loads(line) for line in fs_data.split('\n') if line
json.loads(line) for line in self.fs_data.split('\n')
if line
]
parse_diff_json(lines, self.model)
else:
lines = [line for line in fs_data.split('\n') if line]
lines = [line for line in self.fs_data.split('\n') if line]
parse_diff_lines(lines, self.model)
class DiffResultDialog(DiffResultBase, DiffResultUI):
"""Display the results of `borg diff`."""
def __init__(self, archive_newer: str, archive_older: str,
model: 'DiffTree'):
"""Init."""
super().__init__()
self.setupUi(self)
self.model = model
self.model.setParent(self)
self.treeView: QTreeView
self.treeView.setUniformRowHeights(
True) # Allows for scrolling optimizations.