import logging from typing import Any, TYPE_CHECKING from dzgui.const.constants import APP_NAME, LOG_FILTERS from dzgui.const.enum import ContextMenuGroup from dzgui.model.model_factory import ModelFactory from dzgui.util import strings from dzgui.views.trees.tree_base import TreeView from dzgui.views.mixins.context_mixin import ContextMixin import gi gi.require_version("Gtk", "3.0") from gi.repository import Gtk, GLib, Gdk, GObject, Pango # noqa E402 if TYPE_CHECKING: from pathlib import Path from dzgui.controllers.mc import Controller logger = logging.getLogger(APP_NAME) class LogTreeView(ContextMixin, TreeView): # type: ignore def __init__(self, controller: "Controller") -> None: super().__init__(controller, menu=ContextMenuGroup.LOG) self.controller = controller self.controller.register_widget("logtreeview", self) self.set_headers_visible(True) self.set_fixed_height_mode(True) self.set_vexpand(True) self.get_selection().set_mode(Gtk.SelectionMode.MULTIPLE) self.set_model(None) self.filters = list(LOG_FILTERS) for i, column_title in enumerate(strings.log_cols): renderer = Gtk.CellRendererText() column = Gtk.TreeViewColumn(column_title, renderer, text=i) column.set_sizing(Gtk.TreeViewColumnSizing.FIXED) column.set_resizable(True) column.set_sort_column_id(i) if i == 1: column.set_fixed_width(100) self.append_column(column) self.connect("button-press-event", self._on_log_buttonpress) self.connect("key-press-event", self._on_log_keypress) def populate_log(self, filepath: "Path") -> None: model = ModelFactory().new_model_from_logfile(filepath) _filter = model.filter_new() _filter.set_visible_func(self._filter_rows) sortable = Gtk.TreeModelSort.new_with_model(_filter) self.set_model(sortable) _filter.refilter() path = Gtk.TreePath.new_from_indices([0]) self.set_cursor(path) def toggle_filter(self, _filter: str) -> None: if _filter in self.filters: self.filters.remove(_filter) else: self.filters.append(_filter) # NOTE: unwrap TreeModelSort and TreeModelFilter self.get_model().get_model().refilter() # type: ignore def _filter_rows( self, filter_model: Gtk.TreeModelFilter, _iter: Gtk.TreeIter, data: Any ) -> bool: if len(self.filters) < 1: return False return filter_model[_iter][1] in self.filters def _on_log_buttonpress(self, widget: Gtk.Widget, event: Gdk.EventButton) -> bool: if event.button == Gdk.BUTTON_SECONDARY: self.present_menu(widget, event) return True return False def _on_log_keypress(self, widget: Gtk.Widget, event: Gdk.EventKey) -> None: self.present_menu(widget, event) def concatenate_rows(self) -> str | None: # NOTE: LogTreeView uses Gtk.SelectionMode.MULTIPLE final = [] model, records = self.get_selection().get_selected_rows() if len(records) < 1: return None for record in records: raw_record = model[record] els: tuple[Any] = tuple(raw_record) # type: ignore concat = strings.delimiter.join(map(str, els)) final.append(concat) text = "\n".join(final) return text