From 614968ca4bec1f5409beebdb412cfa6cb6956954 Mon Sep 17 00:00:00 2001 From: Andreas Huber Date: Sat, 4 Dec 2021 16:53:02 +0100 Subject: [PATCH] move the log file viewer to its own plugin We plan to have multiple different types of tabs. --- fulltabwidget.py | 15 +++++++-- main.py | 3 +- raven/pluginregistry.py | 6 ++-- raven/plugins/logfileplugin.py | 38 +++++++++++++++++++++ raven/plugins/openfileplugin.py | 14 ++++---- raven/plugins/ravenlog/Tab.py | 23 +++++++++++++ raven/plugins/ravenlog/__init__.py | 0 raven/plugins/ravenlogplugin.py | 6 ++-- tabs.py | 53 ++++++++++-------------------- 9 files changed, 106 insertions(+), 52 deletions(-) create mode 100644 raven/plugins/logfileplugin.py create mode 100644 raven/plugins/ravenlog/Tab.py create mode 100644 raven/plugins/ravenlog/__init__.py diff --git a/fulltabwidget.py b/fulltabwidget.py index 573032e..139165b 100644 --- a/fulltabwidget.py +++ b/fulltabwidget.py @@ -5,12 +5,14 @@ from bigtext import BigText from filterviewsyncer import FilterViewSyncer from filterwidget import FilterWidget from logFileModel import LogFileModel +from raven.plugins.ravenlog.Tab import Tab +from conversion import humanbytes -class FullTabWidget(QWidget): +class FullTabWidget(Tab): - def __init__(self, model: LogFileModel): - super(FullTabWidget, self).__init__() + def __init__(self, model: LogFileModel, unique_id: str, title: str): + super(FullTabWidget, self).__init__(unique_id, title) self._model = model self.file_view = BigText(model) self.filter_hit_view = FilterWidget(self._model) @@ -33,6 +35,13 @@ class FullTabWidget(QWidget): def get_file(self) -> str: return self.file_view.get_file() + # overriding abstract method def destruct(self): self.file_view.destruct() self.filter_hit_view.destruct() + + # overriding abstract method + def get_status_text(self) -> str: + file = self._model.get_file() + file_size = humanbytes(self._model.byte_count()) + return "%s - %s" % (file_size, file) diff --git a/main.py b/main.py index faea003..e039d94 100644 --- a/main.py +++ b/main.py @@ -53,8 +53,9 @@ if __name__ == "__main__": # init plugins PluginRegistry.load_plugin("RavenLogPlugin") PluginRegistry.load_plugin("OpenFilePlugin") + PluginRegistry.load_plugin("LogFilePlugin") - window = PluginRegistry.executeSingle("create_main_window") + window = PluginRegistry.execute_single("create_main_window") RavenUI.window = window window.show() # window.open_file("/home/andi/ws/performanceDb/data/production/logs_2018-09-06_2018-09-06.csv") diff --git a/raven/pluginregistry.py b/raven/pluginregistry.py index 83e982d..9b4f958 100644 --- a/raven/pluginregistry.py +++ b/raven/pluginregistry.py @@ -1,5 +1,5 @@ from types import ModuleType -from typing import Dict +from typing import Dict, Optional from inspect import isclass from pkgutil import iter_modules from pathlib import Path @@ -46,11 +46,11 @@ class PluginRegistry(): return PluginRegistry.modules.copy() @staticmethod - def executeSingle(function_name: str, *args): + def execute_single(function_name: str, *args) -> Optional[any]: return PluginRegistry._execute(function_name, True, *args) @staticmethod - def execute(function_name: str, *args) -> []: + def execute(function_name: str, *args) -> [any]: return PluginRegistry._execute(function_name, False, *args) @staticmethod diff --git a/raven/plugins/logfileplugin.py b/raven/plugins/logfileplugin.py new file mode 100644 index 0000000..9f7a87d --- /dev/null +++ b/raven/plugins/logfileplugin.py @@ -0,0 +1,38 @@ +import os.path +from typing import Callable, Optional + +from PyQt6.QtWidgets import QMessageBox + +from fulltabwidget import FullTabWidget +from logFileModel import LogFileModel +from raven.pluginbase import PluginBase +from raven.plugins.ravenlog.Tab import Tab +from settings import Settings + + +class LogFilePlugin(PluginBase): + def __init__(self): + super(LogFilePlugin, self).__init__() + self.settings = None + self.tr = None + + def set_settings(self, settings: Settings): + self.settings = settings + + def set_translator(self, tr: Callable[[str], str]): + self.tr = tr + + def create_tab(self, file: str) -> Optional[Tab]: + if not os.path.isfile(file): + message = QMessageBox(QMessageBox.Icon.Warning, "File not found", + "'%s' is not a file or cannot be opened" % file) + message.exec() + return None + + realpath = os.path.realpath(file) + filename = os.path.basename(realpath) + + model = LogFileModel(file, self.settings) + tab = FullTabWidget(model, unique_id=realpath, title=filename) + + return tab diff --git a/raven/plugins/openfileplugin.py b/raven/plugins/openfileplugin.py index 902a295..71738c0 100644 --- a/raven/plugins/openfileplugin.py +++ b/raven/plugins/openfileplugin.py @@ -1,6 +1,6 @@ import os from typing import Callable - +from pathlib import Path from PyQt6.QtGui import QAction, QIcon from PyQt6.QtWidgets import QMenu, QFileDialog @@ -41,8 +41,8 @@ class OpenFilePlugin(PluginBase): ] def _open_file_dialog(self) -> None: - current_file = PluginRegistry.executeSingle("current_file") - directory = os.path.dirname(current_file) if current_file else '' + current_file = PluginRegistry.execute_single("current_file") + directory = os.path.dirname(current_file) if current_file else os.path.join(Path.home()) dialog = QFileDialog() (selected_file, _filter) = dialog.getOpenFileName( @@ -53,12 +53,14 @@ class OpenFilePlugin(PluginBase): self._open_file(selected_file) def _open_file(self, selected_file: str): - PluginRegistry.executeSingle("create_tab", selected_file) - self._remember_recent_file(selected_file) + tab = PluginRegistry.execute_single("create_tab", selected_file) + if tab: + PluginRegistry.execute_single("add_tab", tab) + PluginRegistry.execute("after_open_file", selected_file) def _get_recent_files(self) -> [str]: recent_files = self.settings.session.get('general', 'recent_files', fallback='') - print(recent_files) + # print(recent_files) files = recent_files.split(os.pathsep) if "" in files: files.remove("") diff --git a/raven/plugins/ravenlog/Tab.py b/raven/plugins/ravenlog/Tab.py new file mode 100644 index 0000000..c0bb39d --- /dev/null +++ b/raven/plugins/ravenlog/Tab.py @@ -0,0 +1,23 @@ +from abc import abstractmethod + +from PyQt6.QtWidgets import QWidget + + +class Tab(QWidget): + + def __init__(self, unique_id: str, title: str): + super(Tab, self).__init__() + self.unique_id = unique_id + self.title = title + + @abstractmethod + def get_status_text(self) -> str: + pass + + @abstractmethod + def get_file(self) -> str: + pass + + @abstractmethod + def destruct(self): + pass diff --git a/raven/plugins/ravenlog/__init__.py b/raven/plugins/ravenlog/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/raven/plugins/ravenlogplugin.py b/raven/plugins/ravenlogplugin.py index d4ebee7..1b51081 100644 --- a/raven/plugins/ravenlogplugin.py +++ b/raven/plugins/ravenlogplugin.py @@ -8,6 +8,7 @@ from raven.pluginbase import PluginBase from raven.pluginregistry import PluginRegistry from raven.plugins.domain.menucontribution import MenuContribution from raven.plugins.domain.raction import RAction +from raven.plugins.ravenlog.Tab import Tab class RavenLogPlugin(PluginBase): @@ -29,9 +30,8 @@ class RavenLogPlugin(PluginBase): def current_file(self) -> Optional[str]: return self.main_window.tabs.current_file() - def create_tab(self, file: str): - self.main_window.tabs.create_tab(file) - PluginRegistry.execute("after_open_file", file) + def add_tab(self, tab: Tab): + self.main_window.tabs.add_tab(tab) def _action_about(self) -> RAction: about_action = RAction( diff --git a/tabs.py b/tabs.py index b00d99d..87da764 100644 --- a/tabs.py +++ b/tabs.py @@ -6,16 +6,14 @@ from PyQt6.QtCore import * from PyQt6.QtGui import * from bigtext import BigText -from conversion import humanbytes from fulltabwidget import FullTabWidget from logFileModel import LogFileModel +from raven.plugins.ravenlog.Tab import Tab from ravenui import RavenUI from settings import Settings class Tabs(QWidget): - tabs_by_filename = {} - def __init__(self, settings: Settings): super(Tabs, self).__init__() @@ -32,46 +30,29 @@ class Tabs(QWidget): self.layout.addWidget(self.tabs) - def create_tab(self, file: str): - if not os.path.isfile(file): - message = QMessageBox(QMessageBox.Icon.Warning, "File not found", - "'%s' is not a file or cannot be opened" % (file)) - message.exec() - return + def add_tab(self, tab: Tab): + # if tab already exists then open it + for tab_index in range(0, self.tabs.count()): + widget: Tab = self.tabs.widget(tab_index) + if widget.unique_id == tab.unique_id: + self.tabs.setCurrentIndex(tab_index) + return - model = LogFileModel(file, self.settings) - full_tab = FullTabWidget(model) - - if model.get_file() in self.tabs_by_filename: - for tab_index in range(0, self.tabs.count()): - widget: FullTabWidget = self.tabs.widget(tab_index) - if widget.get_file() == model.get_file(): - self.tabs.setCurrentIndex(tab_index) - break - else: - tab_index = self.tabs.addTab(full_tab, model.get_tab_name()) - self.tabs_by_filename[model.get_file()] = full_tab - self.tabs.setCurrentIndex(tab_index) + tab_index = self.tabs.addTab(tab, tab.title) + self.tabs.setCurrentIndex(tab_index) def _current_tab_changed(self, tab_index: int): - full_tab: FullTabWidget = self.tabs.widget(tab_index) - if full_tab: - # window title - file = full_tab.file_view.get_file() - file_name = os.path.basename(file) - RavenUI.update_window_title(file_name) - - # status bar text - status_text = "%s - %s" % (humanbytes(full_tab.file_view.model.byte_count()), file) - RavenUI.update_status_bar(status_text) + tab: Tab = self.tabs.widget(tab_index) + if tab: + RavenUI.update_window_title(tab.title) + RavenUI.update_status_bar(tab.get_status_text()) else: RavenUI.update_window_title("") RavenUI.update_status_bar("") def _close_tab(self, tab_index: int): - full_tab: FullTabWidget = self.tabs.widget(tab_index) + full_tab: Tab = self.tabs.widget(tab_index) full_tab.destruct() - del self.tabs_by_filename[full_tab.file_view.get_file()] self.tabs.removeTab(tab_index) def destruct(self): @@ -85,5 +66,5 @@ class Tabs(QWidget): if self.tabs.currentIndex() < 0: return None - full_tab: FullTabWidget = self.tabs.widget(self.tabs.currentIndex()) - return full_tab.get_file() + tab: Tab = self.tabs.widget(self.tabs.currentIndex()) + return tab.get_file()