| # Copyright 2021 The Pigweed Authors |
| # |
| # Licensed under the Apache License, Version 2.0 (the "License"); you may not |
| # use this file except in compliance with the License. You may obtain a copy of |
| # the License at |
| # |
| # https://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
| # License for the specific language governing permissions and limitations under |
| # the License. |
| """LogPane FilterToolbar class.""" |
| |
| from __future__ import annotations |
| import functools |
| from typing import TYPE_CHECKING |
| |
| from prompt_toolkit.filters import Condition |
| from prompt_toolkit.layout import ( |
| ConditionalContainer, |
| FormattedTextControl, |
| VSplit, |
| Window, |
| WindowAlign, |
| HorizontalAlign, |
| ) |
| from prompt_toolkit.mouse_events import MouseEvent, MouseEventType |
| |
| import pw_console.widgets.checkbox |
| import pw_console.widgets.mouse_handlers |
| import pw_console.style |
| |
| if TYPE_CHECKING: |
| from pw_console.log_pane import LogPane |
| |
| |
| class FilterToolbar(ConditionalContainer): |
| """Container showing each filter applied in order.""" |
| |
| TOOLBAR_HEIGHT = 1 |
| |
| def mouse_handler_delete_filter(self, filter_text, |
| mouse_event: MouseEvent): |
| """Delete the given log filter.""" |
| if mouse_event.event_type == MouseEventType.MOUSE_UP: |
| self.log_pane.log_view.delete_filter(filter_text) |
| return None |
| return NotImplemented |
| |
| def get_left_fragments(self): |
| """Return formatted text tokens for display.""" |
| separator = ('', ' ') |
| space = ('', ' ') |
| fragments = [('class:filter-bar-title', ' Filters '), separator] |
| |
| button_style = pw_console.style.get_button_style(self.log_pane) |
| |
| for filter_text, log_filter in self.log_pane.log_view.filters.items(): |
| fragments.append(('class:filter-bar-delimiter', '<')) |
| |
| if log_filter.invert: |
| fragments.append(('class:filter-bar-setting', 'NOT ')) |
| |
| if log_filter.field: |
| fragments.append( |
| ('class:filter-bar-setting', log_filter.field)) |
| fragments.append(space) |
| |
| fragments.append(('', filter_text)) |
| fragments.append(space) |
| |
| fragments.append( |
| (button_style + ' class:filter-bar-delete', ' (X) ', |
| functools.partial(self.mouse_handler_delete_filter, |
| filter_text))) # type: ignore |
| fragments.append(('class:filter-bar-delimiter', '>')) |
| |
| fragments.append(separator) |
| return fragments |
| |
| def get_center_fragments(self): |
| """Return formatted text tokens for display.""" |
| clear_filters = functools.partial( |
| pw_console.widgets.mouse_handlers.on_click, |
| self.log_pane.log_view.clear_filters) |
| |
| button_style = pw_console.style.get_button_style(self.log_pane) |
| |
| return pw_console.widgets.checkbox.to_keybind_indicator( |
| 'Ctrl-Alt-r', |
| 'Clear Filters', |
| clear_filters, |
| base_style=button_style) |
| |
| def __init__(self, log_pane: 'LogPane'): |
| self.log_pane = log_pane |
| left_bar_control = FormattedTextControl(self.get_left_fragments) |
| left_bar_window = Window(content=left_bar_control, |
| align=WindowAlign.LEFT, |
| dont_extend_width=True) |
| center_bar_control = FormattedTextControl(self.get_center_fragments) |
| center_bar_window = Window(content=center_bar_control, |
| align=WindowAlign.LEFT, |
| dont_extend_width=False) |
| super().__init__( |
| VSplit( |
| [ |
| left_bar_window, |
| center_bar_window, |
| ], |
| style=functools.partial(pw_console.style.get_toolbar_style, |
| self.log_pane, |
| dim=True), |
| height=1, |
| align=HorizontalAlign.LEFT, |
| ), |
| # Only show if filtering is enabled. |
| filter=Condition(lambda: self.log_pane.log_view.filtering_on), |
| ) |