blob: 9c76f5131f7f7c3e7ac3b9513b7cf2f6a3eafaae [file] [log] [blame]
# Copyright 2022 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.
"""Dialog box for log selection functions."""
from __future__ import annotations
import functools
from typing import TYPE_CHECKING
from prompt_toolkit.filters import Condition
from prompt_toolkit.layout import (
ConditionalContainer,
FormattedTextControl,
Window,
WindowAlign,
)
import pw_console.style
import pw_console.widgets.checkbox
import pw_console.widgets.border
import pw_console.widgets.mouse_handlers
if TYPE_CHECKING:
from pw_console.log_pane import LogPane
class LogPaneSelectionDialog(ConditionalContainer):
"""Dialog box for showing log selection functions.
Displays number of lines selected, buttons for copying to the clipboar or
saving to a file, and buttons to select all or cancel (clear) the
selection."""
# Height of the dialog box contens in lines of text.
DIALOG_HEIGHT = 3
def __init__(self, log_pane: 'LogPane'):
self.log_pane = log_pane
self.log_view = log_pane.log_view
self._markdown_flag: bool = False
self._table_flag: bool = True
selection_bar_control = FormattedTextControl(self.get_fragments)
selection_bar_window = Window(content=selection_bar_control,
height=1,
align=WindowAlign.LEFT,
dont_extend_width=False,
style='class:selection-dialog')
super().__init__(
pw_console.widgets.border.create_border(
selection_bar_window,
(LogPaneSelectionDialog.DIALOG_HEIGHT - 1),
border_style='class:selection-dialog-border',
base_style='class:selection-dialog-default-fg',
top=False,
right=False,
),
filter=Condition(lambda: self.log_view.visual_select_mode))
def focus_log_pane(self):
self.log_pane.application.focus_on_container(self.log_pane)
def _toggle_markdown_flag(self) -> None:
self._markdown_flag = not self._markdown_flag
def _toggle_table_flag(self) -> None:
self._table_flag = not self._table_flag
def _select_all(self) -> None:
self.log_view.visual_select_all()
def _select_none(self) -> None:
self.log_view.clear_visual_selection()
def _copy_selection(self) -> None:
if self.log_view.export_logs(
to_clipboard=True,
use_table_formatting=self._table_flag,
selected_lines_only=True,
add_markdown_fence=self._markdown_flag,
):
self._select_none()
def _saveas_file(self) -> None:
self.log_pane.start_saveas(table_format=self._table_flag,
selected_lines_only=True)
def get_fragments(self):
"""Return formatted text tuples for both rows of the selection
dialog."""
focus = functools.partial(pw_console.widgets.mouse_handlers.on_click,
self.focus_log_pane)
one_space = ('', ' ', focus)
two_spaces = ('', ' ', focus)
select_all = functools.partial(
pw_console.widgets.mouse_handlers.on_click, self._select_all)
select_none = functools.partial(
pw_console.widgets.mouse_handlers.on_click, self._select_none)
copy_selection = functools.partial(
pw_console.widgets.mouse_handlers.on_click, self._copy_selection)
saveas_file = functools.partial(
pw_console.widgets.mouse_handlers.on_click, self._saveas_file)
toggle_markdown = functools.partial(
pw_console.widgets.mouse_handlers.on_click,
self._toggle_markdown_flag)
toggle_table = functools.partial(
pw_console.widgets.mouse_handlers.on_click,
self._toggle_table_flag)
button_style = 'class:toolbar-button-inactive'
# First row of text
fragments = [('class:selection-dialog-title', ' {} Selected '.format(
self.log_view.visual_selected_log_count()), focus), one_space,
('class:selection-dialog-default-fg', 'Format: ', focus)]
# Table and Markdown options
fragments.extend(
pw_console.widgets.checkbox.to_checkbox_with_keybind_indicator(
self._table_flag,
key='',
description='Table',
mouse_handler=toggle_table,
base_style='class:selection-dialog-default-bg'))
fragments.extend(
pw_console.widgets.checkbox.to_checkbox_with_keybind_indicator(
self._markdown_flag,
key='',
description='Markdown',
mouse_handler=toggle_markdown,
base_style='class:selection-dialog-default-bg'))
# Line break
fragments.append(('', '\n'))
# Second row of text
fragments.append(one_space)
fragments.extend(
pw_console.widgets.checkbox.to_keybind_indicator(
key='Ctrl-c',
description='Cancel',
mouse_handler=select_none,
base_style=button_style,
))
fragments.append(two_spaces)
fragments.extend(
pw_console.widgets.checkbox.to_keybind_indicator(
key='Ctrl-a',
description='Select All',
mouse_handler=select_all,
base_style=button_style,
))
fragments.append(two_spaces)
fragments.append(one_space)
fragments.extend(
pw_console.widgets.checkbox.to_keybind_indicator(
key='',
description='Save as File',
mouse_handler=saveas_file,
base_style=button_style,
))
fragments.append(two_spaces)
fragments.extend(
pw_console.widgets.checkbox.to_keybind_indicator(
key='',
description='Copy',
mouse_handler=copy_selection,
base_style=button_style,
))
fragments.append(one_space)
return fragments