add progress bar

This commit is contained in:
2022-02-22 20:17:35 +01:00
parent 1f9ca04e23
commit a5ce2f83cd

View File

@@ -2,12 +2,13 @@ import os
import re import re
import tempfile import tempfile
import threading import threading
import time
from typing import Optional, Callable from typing import Optional, Callable
from PySide6.QtCore import QRunnable, QThreadPool, Signal from PySide6.QtCore import QRunnable, QThreadPool, Signal
from PySide6.QtGui import QIcon from PySide6.QtGui import QIcon
from PySide6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QCheckBox, QPushButton, QComboBox, \ from PySide6.QtWidgets import QWidget, QVBoxLayout, QHBoxLayout, QCheckBox, QPushButton, QComboBox, \
QSizePolicy QSizePolicy, QProgressBar
from src.ui.bigtext.bigtext import BigText from src.ui.bigtext.bigtext import BigText
from src.ui.bigtext.logFileModel import LogFileModel from src.ui.bigtext.logFileModel import LogFileModel
@@ -26,6 +27,7 @@ class FilterTask(QRunnable):
regex: re.Pattern, regex: re.Pattern,
lock: threading.RLock, lock: threading.RLock,
filter_match_found_listeners: Callable[[int], None], filter_match_found_listeners: Callable[[int], None],
progress_handler: Callable[[float], None],
on_before: Callable[[], None], on_before: Callable[[], None],
on_finish: Callable[[], None] on_finish: Callable[[], None]
): ):
@@ -33,6 +35,7 @@ class FilterTask(QRunnable):
self.source_model = source_model self.source_model = source_model
self.filter_model = filter_model self.filter_model = filter_model
self.regex = regex self.regex = regex
self.progress_handler = progress_handler
self.on_before = on_before self.on_before = on_before
self.on_finish = on_finish self.on_finish = on_finish
self.lock = lock self.lock = lock
@@ -52,6 +55,7 @@ class FilterTask(QRunnable):
for listener in self.filter_match_found_listeners: for listener in self.filter_match_found_listeners:
listener(-1, -1) # notify listeners that a new search started listener(-1, -1) # notify listeners that a new search started
last_progress_report = time.time()
try: try:
with open(self.source_model.get_file(), "rb") as source: with open(self.source_model.get_file(), "rb") as source:
with open(self.filter_model.get_file(), "w+b") as target: with open(self.filter_model.get_file(), "w+b") as target:
@@ -62,7 +66,6 @@ class FilterTask(QRunnable):
line = l.decode("utf8", errors="ignore") line = l.decode("utf8", errors="ignore")
if self.regex.findall(line): if self.regex.findall(line):
# time.sleep(0.5)
lines_written = lines_written + 1 lines_written = lines_written + 1
source_line_offset = source.tell() - len(l) source_line_offset = source.tell() - len(l)
target_line_offset = target.tell() target_line_offset = target.tell()
@@ -72,10 +75,17 @@ class FilterTask(QRunnable):
# sometime buffering can hide results for a while # sometime buffering can hide results for a while
# We force a flush periodically. # We force a flush periodically.
if line_count % 10000 == 0 and lines_written > 0: if line_count % 10000 == 0:
if lines_written > 0:
target.flush() target.flush()
lines_written = 0 lines_written = 0
now = time.time()
if now - last_progress_report > 0.2:
progress = source.tell() / os.stat(self.source_model.get_file()).st_size
self.progress_handler(progress)
last_progress_report = now
if self.aborted: if self.aborted:
# print("aborted ", time.time()) # print("aborted ", time.time())
break break
@@ -88,6 +98,7 @@ class FilterWidget(QWidget):
filter_model: LogFileModel filter_model: LogFileModel
filter_task: Optional[FilterTask] = None filter_task: Optional[FilterTask] = None
search_is_running = Signal(bool) search_is_running = Signal(bool)
signal_update_progress = Signal(float)
def __init__(self, source_model: LogFileModel): def __init__(self, source_model: LogFileModel):
super(FilterWidget, self).__init__() super(FilterWidget, self).__init__()
@@ -106,10 +117,15 @@ class FilterWidget(QWidget):
self.query_field.lineEdit().returnPressed.connect(self.filter_changed) self.query_field.lineEdit().returnPressed.connect(self.filter_changed)
self.query_field.setInsertPolicy(QComboBox.NoInsert) self.query_field.setInsertPolicy(QComboBox.NoInsert)
self.progress_bar = QProgressBar()
self.progress_bar.setVisible(False)
self.progress_bar.setMaximumWidth(50)
self.signal_update_progress.connect(self.update_progress)
self.btn_cancel_search = QPushButton(_("Cancel")) self.btn_cancel_search = QPushButton(_("Cancel"))
self.btn_cancel_search.setVisible(False) self.btn_cancel_search.setVisible(False)
self.btn_cancel_search.pressed.connect(self._cancel_search) self.btn_cancel_search.pressed.connect(self._cancel_search)
self.search_is_running.connect(lambda is_running: self.btn_cancel_search.setVisible(is_running)) self.search_is_running.connect(self.search_running_status_changed)
self.btn_bookmark = QPushButton(QIcon("icons/ionicons/star.svg"), "") self.btn_bookmark = QPushButton(QIcon("icons/ionicons/star.svg"), "")
self.btn_bookmark.setToolTip(_("save query")) self.btn_bookmark.setToolTip(_("save query"))
@@ -127,6 +143,7 @@ class FilterWidget(QWidget):
filter_bar.layout = QHBoxLayout(filter_bar) filter_bar.layout = QHBoxLayout(filter_bar)
filter_bar.layout.setContentsMargins(0, 0, 0, 0) filter_bar.layout.setContentsMargins(0, 0, 0, 0)
filter_bar.layout.addWidget(self.query_field) filter_bar.layout.addWidget(self.query_field)
filter_bar.layout.addWidget(self.progress_bar)
filter_bar.layout.addWidget(self.btn_cancel_search) filter_bar.layout.addWidget(self.btn_cancel_search)
filter_bar.layout.addWidget(self.btn_bookmark) filter_bar.layout.addWidget(self.btn_bookmark)
filter_bar.layout.addWidget(self.ignore_case) filter_bar.layout.addWidget(self.ignore_case)
@@ -140,7 +157,7 @@ class FilterWidget(QWidget):
self.layout.addWidget(filter_bar) self.layout.addWidget(filter_bar)
self.layout.addWidget(self.hits_view) self.layout.addWidget(self.hits_view)
self.filter_match_found_listeners: [Callable[[int], None]] = [] self.filter_match_found_listeners: [Callable[[int, int], None]] = []
def on_reveal(self): def on_reveal(self):
self._reload_save_queries() self._reload_save_queries()
@@ -183,6 +200,16 @@ class FilterWidget(QWidget):
self.filter_model.clear_query_highlight() self.filter_model.clear_query_highlight()
PluginRegistry.execute("update_ui") PluginRegistry.execute("update_ui")
def search_running_status_changed(self, is_running: bool):
self.btn_cancel_search.setVisible(is_running)
self.progress_bar.setVisible(is_running)
def update_progress(self, progress: float):
self.progress_bar.setValue(progress * 100)
def progress_handler(self, progress: float):
self.signal_update_progress.emit(progress)
def filter_changed(self): def filter_changed(self):
query = self.query_field.currentText() query = self.query_field.currentText()
ignore_case = self.ignore_case.isChecked() ignore_case = self.ignore_case.isChecked()
@@ -206,6 +233,8 @@ class FilterWidget(QWidget):
self.filter_model.truncate() self.filter_model.truncate()
return return
self.progress_bar.setValue(0)
self.source_model.set_query_highlight(query, ignore_case, is_regex) self.source_model.set_query_highlight(query, ignore_case, is_regex)
self.filter_model.set_query_highlight(query, ignore_case, is_regex) self.filter_model.set_query_highlight(query, ignore_case, is_regex)
@@ -215,6 +244,7 @@ class FilterWidget(QWidget):
regex, regex,
self._lock, self._lock,
self.filter_match_found_listeners, self.filter_match_found_listeners,
self.progress_handler,
lambda: self.search_is_running.emit(True), lambda: self.search_is_running.emit(True),
lambda: self.search_is_running.emit(False) lambda: self.search_is_running.emit(False)
) )