import logging import os import sys from typing import List, Optional from PyQt6.QtWidgets import * from PyQt6.QtGui import * import constants import urlutils from aboutdialog import AboutDialog from cutesettings import CuteSettings from raven.pluginregistry import PluginRegistry from raven.plugins.domain.menucontribution import MenuContribution from raven.plugins.domain.raction import RAction from raven.plugins.domain.rmenu import RMenu from settingsstore import SettingsStore from highlightingdialog import HighlightingDialog from tabs import Tabs from urlutils import url_is_file from functools import reduce MAX_LINE_LENGTH = 4096 logging.basicConfig(level=logging.INFO) log = logging.getLogger("main") def flat_map(array: List[List]) -> List: return reduce(list.__add__, array) class MainWindow(QMainWindow): def __init__(self, *args, **kwargs): super(MainWindow, self).__init__(*args, **kwargs) self.settings = SettingsStore.load() PluginRegistry.execute("set_settings", self.settings) PluginRegistry.execute("set_translator", lambda string: self.tr(string)) self.setWindowTitle(self.tr("RavenLog")) self._restore_window() self.setDockNestingEnabled(True) self.setAcceptDrops(True) self.tabs = Tabs(self.settings) self._menu_recent_files = QMenu(self.tr("Open &Recent"), self) self.setCentralWidget(self.tabs) self.status_bar = QStatusBar(self) self.setStatusBar(self.status_bar) self.setMenuBar(self.create_dynamic_menu_bar()) def create_dynamic_menu_bar(self) -> QMenuBar: menu_bar = QMenuBar() menu_contributions: [MenuContribution] = flat_map(PluginRegistry.execute("get_menu_contributions")) menu_contributions.append(MenuContribution("settings", action=self._action_highlighter())) menu_contributions.append(MenuContribution("settings", action=self._action_highlight_search_terms())) menu_contributions.append(MenuContribution("settings", action=self._action_new_tab())) known_menus = [ ("file", self.tr("&File")), ("settings", self.tr("&Settings")), ("help", self.tr("&Help")) ] for (menu_id, menu_label) in known_menus: menu = QMenu(menu_label, self) mcs: [MenuContribution] = [mc for mc in menu_contributions if mc.menu_id == menu_id] if len(mcs) == 0: continue for menu_contribution in mcs: if menu_contribution.action: action = self._raction_to_qaction(menu_contribution.action, menu) menu.addAction(action) if menu_contribution.menu: submenu = QMenu(self.tr(menu_contribution.menu.label), menu_bar) menu_contribution.menu.add_change_listener( lambda qmenu=submenu, rmenu=menu_contribution.menu: self._rmenu_update(qmenu, rmenu)) self._rmenu_update(submenu, menu_contribution.menu) menu.addMenu(submenu) menu_bar.addMenu(menu) return menu_bar def _rmenu_update(self, qmenu: QMenu, rmenu: RMenu): qmenu.clear() for action in rmenu.actions: action = self._raction_to_qaction(action, qmenu) qmenu.addAction(action) def _raction_to_qaction(self, raction: RAction, qmenu: QMenu) -> QAction: action = QAction(self.tr(raction.label), qmenu) if raction.icon_from_theme: action.setIcon(QIcon.fromTheme(raction.icon_from_theme)) if raction.icon_file: action.setIcon(QIcon(raction.icon_file)) if raction.shortcut: action.setShortcut(raction.shortcut) if raction.action: action.triggered.connect(raction.action) if raction.checkable: action.setCheckable(raction.checkable) action.setChecked(raction.checked) return action def _action_highlighter(self): manage = RAction( "&Highlighter", action=lambda: HighlightingDialog(self.settings).exec(), shortcut='Ctrl+H' ) return manage def _action_highlight_search_terms(self): highlight_search_terms = RAction( "Highlight &Searches", action=lambda checked: self.settings.set_session("general", "highlight_search_term", str(checked)) or self.update() ) highlight_search_terms.set_checkable(True) highlight_search_terms.set_checked(self.settings.session.getboolean("general", "highlight_search_term")) return highlight_search_terms def _action_new_tab(self): new_tab = RAction("Open Tab on Save As File") new_tab.set_checkable(True) new_tab.set_checked(self.settings.session.getboolean("general", "open_tab_on_save_as_file")) new_tab.set_action( lambda checked: self.settings.set_session("general", "open_tab_on_save_as_file", str(checked))) return new_tab def dragEnterEvent(self, e: QDragEnterEvent): if url_is_file(e.mimeData().text()): e.accept() else: e.ignore() def dropEvent(self, e): file = urlutils.url_to_path(e.mimeData().text()) PluginRegistry.executeSingle("create_tab", file) def _restore_window(self): qsettings = CuteSettings() geometry_restored = False geometry = qsettings.value("mainWindow/geometry") if geometry: geometry_restored = self.restoreGeometry(geometry) if not geometry_restored: self.setGeometry(0, 0, 800, 600) def closeEvent(self, event): self.destruct() def destruct(self): self.tabs.destruct() self.close() SettingsStore.save(self.settings) CuteSettings().set_value("mainWindow/geometry", self.saveGeometry())