add context menu actions to set range start and end

This commit is contained in:
2024-03-24 12:06:48 +01:00
parent ff3d3ddc27
commit f3a68d0dee
5 changed files with 155 additions and 34 deletions

View File

@@ -5,8 +5,8 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: RavenLog\n" "Project-Id-Version: RavenLog\n"
"POT-Creation-Date: 2024-03-21 19:39+0100\n" "POT-Creation-Date: 2024-03-24 12:00+0100\n"
"PO-Revision-Date: 2024-03-21 19:40+0100\n" "PO-Revision-Date: 2024-03-24 12:02+0100\n"
"Last-Translator: \n" "Last-Translator: \n"
"Language-Team: \n" "Language-Team: \n"
"Language: de\n" "Language: de\n"
@@ -226,27 +226,39 @@ msgstr "In &Datei Kopieren"
msgid "Select &All" msgid "Select &All"
msgstr "&Alles Selektieren" msgstr "&Alles Selektieren"
#: src/ui/bigtext/bigtext.py:414 #: src/ui/bigtext/bigtext.py:268
msgid "Set Range Start"
msgstr "Setze Start des Anzeigebereichs"
#: src/ui/bigtext/bigtext.py:276
msgid "Set Range End"
msgstr "Setze Ende des Anzeigebereichs"
#: src/ui/bigtext/bigtext.py:283
msgid "Reset Range"
msgstr "Anzeigebereich Zurücksetzen"
#: src/ui/bigtext/bigtext.py:458
msgid "warning" msgid "warning"
msgstr "Achtung" msgstr "Achtung"
#: src/ui/bigtext/bigtext.py:415 #: src/ui/bigtext/bigtext.py:459
msgid "You have selected <b>{0}</b> of data." msgid "You have selected <b>{0}</b> of data."
msgstr "Du hast <b>{0}</b> selektiert." msgstr "Du hast <b>{0}</b> selektiert."
#: src/ui/bigtext/bigtext.py:420 #: src/ui/bigtext/bigtext.py:464
msgid "Copy {0} to Clipboard" msgid "Copy {0} to Clipboard"
msgstr "Kopiere {0} in die Zwischenablage" msgstr "Kopiere {0} in die Zwischenablage"
#: src/ui/bigtext/bigtext.py:424 #: src/ui/bigtext/bigtext.py:468
msgid "Write to File" msgid "Write to File"
msgstr "Schreibe in Datei" msgstr "Schreibe in Datei"
#: src/ui/bigtext/bigtext.py:448 #: src/ui/bigtext/bigtext.py:492
msgid "Save File" msgid "Save File"
msgstr "Speichere Datei" msgstr "Speichere Datei"
#: src/ui/bigtext/bigtext.py:485 #: src/ui/bigtext/bigtext.py:529
msgid "selected {0} - {1:,.0f}:{2:,.0f}" msgid "selected {0} - {1:,.0f}:{2:,.0f}"
msgstr "selektiert {0} - {1:,.0f}:{2:,.0f}" msgstr "selektiert {0} - {1:,.0f}:{2:,.0f}"
@@ -304,7 +316,7 @@ msgstr "Pale Crimson"
#: src/ui/colorbutton.py:23 #: src/ui/colorbutton.py:23
msgid "Broken Buttercup" msgid "Broken Buttercup"
msgstr "Broken Buttercup" msgstr "Kaputtes Butterfass"
#: src/ui/colorbutton.py:24 #: src/ui/colorbutton.py:24
msgid "Passion Fruit Sugar" msgid "Passion Fruit Sugar"
@@ -358,6 +370,10 @@ msgstr "Grau"
msgid "transparent" msgid "transparent"
msgstr "Transparent" msgstr "Transparent"
#: src/ui/rangeslider.py:180
msgid "showing bytes {0} to {1} ({2})"
msgstr "Anzeigebereich: Bytes {0} bis {1} ({2})"
#~ msgid "data selection" #~ msgid "data selection"
#~ msgstr "selektion" #~ msgstr "selektion"

View File

@@ -5,7 +5,7 @@
msgid "" msgid ""
msgstr "" msgstr ""
"Project-Id-Version: PACKAGE VERSION\n" "Project-Id-Version: PACKAGE VERSION\n"
"POT-Creation-Date: 2024-03-21 19:39+0100\n" "POT-Creation-Date: 2024-03-24 12:00+0100\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n" "Language-Team: LANGUAGE <LL@li.org>\n"
@@ -220,27 +220,39 @@ msgstr ""
msgid "Select &All" msgid "Select &All"
msgstr "" msgstr ""
#: src/ui/bigtext/bigtext.py:414 #: src/ui/bigtext/bigtext.py:268
msgid "Set Range Start"
msgstr ""
#: src/ui/bigtext/bigtext.py:276
msgid "Set Range End"
msgstr ""
#: src/ui/bigtext/bigtext.py:283
msgid "Reset Range"
msgstr ""
#: src/ui/bigtext/bigtext.py:458
msgid "warning" msgid "warning"
msgstr "" msgstr ""
#: src/ui/bigtext/bigtext.py:415 #: src/ui/bigtext/bigtext.py:459
msgid "You have selected <b>{0}</b> of data." msgid "You have selected <b>{0}</b> of data."
msgstr "" msgstr ""
#: src/ui/bigtext/bigtext.py:420 #: src/ui/bigtext/bigtext.py:464
msgid "Copy {0} to Clipboard" msgid "Copy {0} to Clipboard"
msgstr "" msgstr ""
#: src/ui/bigtext/bigtext.py:424 #: src/ui/bigtext/bigtext.py:468
msgid "Write to File" msgid "Write to File"
msgstr "" msgstr ""
#: src/ui/bigtext/bigtext.py:448 #: src/ui/bigtext/bigtext.py:492
msgid "Save File" msgid "Save File"
msgstr "" msgstr ""
#: src/ui/bigtext/bigtext.py:485 #: src/ui/bigtext/bigtext.py:529
msgid "selected {0} - {1:,.0f}:{2:,.0f}" msgid "selected {0} - {1:,.0f}:{2:,.0f}"
msgstr "" msgstr ""
@@ -352,3 +364,7 @@ msgstr ""
msgid "transparent" msgid "transparent"
msgstr "" msgstr ""
#: src/ui/rangeslider.py:180
msgid "showing bytes {0} to {1} ({2})"
msgstr ""

View File

@@ -87,7 +87,10 @@ class BigText(QWidget):
self.v_scroll_bar = ScaledScrollBar() self.v_scroll_bar = ScaledScrollBar()
self.big_text = InnerBigText(self, model, self.v_scroll_bar) self.range_limit = RangeSlider()
self.range_limit.value_changed.connect(self._range_limit_event)
self.big_text = InnerBigText(self, model, self.v_scroll_bar, self.range_limit)
self.big_text.setSizePolicy(QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)) self.big_text.setSizePolicy(QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding))
self.h_scroll_bar = QScrollBar(Qt.Orientation.Horizontal) self.h_scroll_bar = QScrollBar(Qt.Orientation.Horizontal)
@@ -99,8 +102,7 @@ class BigText(QWidget):
self.v_scroll_bar.scaledValueChanged.connect(self.big_text.v_scroll_event) self.v_scroll_bar.scaledValueChanged.connect(self.big_text.v_scroll_event)
self.v_scroll_bar.scrolled_to_end.connect(self.big_text.v_scroll_update_follow_tail) self.v_scroll_bar.scrolled_to_end.connect(self.big_text.v_scroll_update_follow_tail)
self.range_limit = RangeSlider()
self.range_limit.value_changed.connect(self._range_limit_event)
if show_range_slider: if show_range_slider:
self.grid.addWidget(self.range_limit, 0, 0) self.grid.addWidget(self.range_limit, 0, 0)
@@ -112,12 +114,9 @@ class BigText(QWidget):
QThreadPool.globalInstance().start(self.watchdog) QThreadPool.globalInstance().start(self.watchdog)
self.trigger_update.connect(self.big_text._file_changed) self.trigger_update.connect(self.big_text._file_changed)
def _range_limit_event(self, lower_value: float, upper_value: float): def _range_limit_event(self, range_start: str, range_end: str):
byte_count = self.model.byte_count() # print("-> %s, %s -- range limit event" %(range_start, range_end))
range_start = int(byte_count * (lower_value / 100.0)) self.big_text.set_range(int(range_start), int(range_end))
range_end = int(byte_count * (upper_value / 100.0))
print(f"-> {lower_value}, {upper_value}, {range_start}, {range_end} -- range limit event")
self.big_text.set_range(range_start, range_end)
def get_file(self): def get_file(self):
return self.model.get_file() return self.model.get_file()
@@ -150,12 +149,14 @@ class InnerBigText(QWidget):
_range_start = 0 _range_start = 0
_range_end = -1 _range_end = -1
def __init__(self, parent: BigText, model: LogFileModel, v_scaled_scrollbar: ScaledScrollBar): def __init__(self, parent: BigText, model: LogFileModel, v_scaled_scrollbar: ScaledScrollBar,
range_limit: RangeSlider):
super(InnerBigText, self).__init__() super(InnerBigText, self).__init__()
self.char_height = None self.char_height = None
self.char_width = None self.char_width = None
self.model = model self.model = model
self._v_scaled_scrollbar = v_scaled_scrollbar self._v_scaled_scrollbar = v_scaled_scrollbar
self._range_limit = range_limit
self.parent = parent self.parent = parent
self.setFocusPolicy(Qt.FocusPolicy.StrongFocus) self.setFocusPolicy(Qt.FocusPolicy.StrongFocus)
self.setFocusPolicy(Qt.FocusPolicy.WheelFocus) self.setFocusPolicy(Qt.FocusPolicy.WheelFocus)
@@ -232,7 +233,7 @@ class InnerBigText(QWidget):
# print("wheel event fired :) %s" % (direction)) # print("wheel event fired :) %s" % (direction))
self.scroll_by_lines(direction * 3) self.scroll_by_lines(direction * 3)
def _open_menu(self, position): def _open_menu(self, position: QPoint):
menu = QMenu(self) menu = QMenu(self)
copy_clipboard = QAction(Icon.fromTheme("edit-copy", "icons/myicons/edit-copy.svg"), _("&Copy to Clipboard"), copy_clipboard = QAction(Icon.fromTheme("edit-copy", "icons/myicons/edit-copy.svg"), _("&Copy to Clipboard"),
@@ -261,8 +262,52 @@ class InnerBigText(QWidget):
manage_highlighting.setShortcut("CTRL+H") manage_highlighting.setShortcut("CTRL+H")
menu.addAction(manage_highlighting) menu.addAction(manage_highlighting)
menu.addSeparator()
set_range_start = QAction(
Icon("icons/myicons/range-start.svg"),
_("Set Range Start"),
self,
triggered=lambda: self._set_range_start_by_y_pos(position.y())
)
menu.addAction(set_range_start)
set_range_end = QAction(
Icon("icons/myicons/range-end.svg"),
_("Set Range End"),
self,
triggered=lambda: self._set_range_end_by_y_pos(position.y())
)
menu.addAction(set_range_end)
reset_range = QAction(
_("Reset Range"),
self,
triggered=lambda: self._reset_range()
)
menu.addAction(reset_range)
menu.exec(self.mapToGlobal(position)) menu.exec(self.mapToGlobal(position))
def _set_range_start_by_y_pos(self, y_pos: int) -> None:
line_number = self.y_pos_to_line(y_pos)
self.lines = self.model.data(self._byte_offset, 0, line_number + 1, self._range_start,
self._range_end)
range_start = self.lines[line_number].byte_offset()
self.parent.range_limit.set_range_start(range_start)
def _set_range_end_by_y_pos(self, y_pos: int) -> None:
line_number = self.y_pos_to_line(y_pos)
self.lines = self.model.data(self._byte_offset, 0, line_number + 1, self._range_start,
self._range_end)
range_end = self.lines[line_number].byte_end() + 1
self.parent.range_limit.set_range_end(range_end)
def _reset_range(self):
self.parent.range_limit.set_range_start(0)
self.parent.range_limit.set_range_end(self.model.byte_count())
def scroll_by_lines(self, scroll_lines: int): def scroll_by_lines(self, scroll_lines: int):
self.scroll_lines = scroll_lines self.scroll_lines = scroll_lines
self.update() self.update()
@@ -511,8 +556,10 @@ class InnerBigText(QWidget):
self._byte_offset = self.lines[0].byte_offset() if len(self.lines) > 0 else 0 self._byte_offset = self.lines[0].byte_offset() if len(self.lines) > 0 else 0
# print("new byte offset: ", self._byte_offset) # print("new byte offset: ", self._byte_offset)
# document length == maximum + pageStep + aFewBytesSoThatTheLastLineIsShown # document length == maximum + pageStep + aFewBytesSoThatTheLastLineIsShown
vmax = self.model.byte_count() - 1 if self._range_end < 0 else min(self._range_end, self.model.byte_count() - 1) byte_count = self.model.byte_count()
vmax = byte_count - 1 if self._range_end < 0 else min(self._range_end, self.model.byte_count() - 1)
self.parent.v_scroll_bar.setMaximum(vmax) self.parent.v_scroll_bar.setMaximum(vmax)
self.parent.range_limit.set_maximum(byte_count)
for line in self.lines: for line in self.lines:
self.update_longest_line(len(line.line())) self.update_longest_line(len(line.line()))

View File

@@ -7,8 +7,10 @@ from PySide6.QtCore import QRect, QPoint, Signal
from PySide6.QtGui import QPainter, Qt from PySide6.QtGui import QPainter, Qt
from PySide6.QtWidgets import QWidget from PySide6.QtWidgets import QWidget
from src.pluginregistry import PluginRegistry
from src.util import conversion
from src.util.color import to_qcolor from src.util.color import to_qcolor
from src.i18n import _
class RangeSliderHandle(): class RangeSliderHandle():
def __init__(self, value: int): def __init__(self, value: int):
@@ -27,7 +29,13 @@ class UpdateStyle(Enum):
class RangeSlider(QWidget): class RangeSlider(QWidget):
value_changed = Signal(float, float) value_changed = Signal(str, str)
"""Signal emitted when the range slider value changes.
**Note**: The value is a string and must be parsed into an int.
QT's signal api only supports 32bit integers. Ints larger
than 2**32-1 will overflow. Probably because there is some C/C++
code involved. We work around this by converting the python int
into a string."""
_width = 20 _width = 20
_handle_width = 12 _handle_width = 12
@@ -42,11 +50,22 @@ class RangeSlider(QWidget):
self.max_value = 100 self.max_value = 100
self.lower_value = RangeSliderHandle(0) self.lower_value = RangeSliderHandle(0)
self.upper_value = RangeSliderHandle(100) self.upper_value = RangeSliderHandle(self.max_value)
self.selected_handle = None self.selected_handle = None
self.selection_drag_range = (self.min_value, self.max_value) self.selection_drag_range = (self.min_value, self.max_value)
def set_maximum(self, max: int):
if self.max_value == max:
return
was_at_max = self.upper_value.value == self.max_value
self.max_value = max
if was_at_max:
self.upper_value.value = max
self._emit_value_changed()
def paintEvent(self, event: PySide6.QtGui.QPaintEvent) -> None: def paintEvent(self, event: PySide6.QtGui.QPaintEvent) -> None:
painter = QPainter(self) painter = QPainter(self)
self._draw_background(painter) self._draw_background(painter)
@@ -104,13 +123,13 @@ class RangeSlider(QWidget):
painter.drawEllipse(QPoint(self._width / 2, y_pixel), self._handle_width / 2 - 1, self._handle_width / 2 - 1) painter.drawEllipse(QPoint(self._width / 2, y_pixel), self._handle_width / 2 - 1, self._handle_width / 2 - 1)
def _value_to_pixel(self, value: int) -> int: def _value_to_pixel(self, value: int) -> int:
value_percent = value / (self.max_value - self.min_value) value_percent = value / self.max_value
pixel = (self.height() - 2 * self._handle_width) * value_percent + self._handle_width pixel = (self.height() - 2 * self._handle_width) * value_percent + self._handle_width
return pixel return pixel
def _pixel_to_value(self, pixel: int) -> int: def _pixel_to_value(self, pixel: int) -> int:
pixel_percent = (pixel - self._handle_width) / (self.height() - 2 * self._handle_width) pixel_percent = (pixel - self._handle_width) / (self.height() - 2 * self._handle_width)
return (self.max_value - self.min_value) * pixel_percent return int(math.floor(self.max_value * pixel_percent))
def _is_on_handle(self, handle: RangeSliderHandle, y_pixel: int, direction=1) -> bool: def _is_on_handle(self, handle: RangeSliderHandle, y_pixel: int, direction=1) -> bool:
handle_y_pixel = self._value_to_pixel(handle.value) handle_y_pixel = self._value_to_pixel(handle.value)
@@ -139,5 +158,28 @@ class RangeSlider(QWidget):
if self.selection_drag_range[0] <= value <= self.selection_drag_range[1]: if self.selection_drag_range[0] <= value <= self.selection_drag_range[1]:
self.selected_handle.value = value self.selected_handle.value = value
# print("%s, %s" %(self.lower_value.value, self.upper_value.value)) # print("%s, %s" %(self.lower_value.value, self.upper_value.value))
self.value_changed.emit(self.lower_value.value, self.upper_value.value) self._emit_value_changed()
self.update() self.update()
self._update_tooltip()
def set_range_start(self, value: int):
self.lower_value.value = value
self._emit_value_changed()
self.update()
def set_range_end(self, value: int):
self.upper_value.value = value
self._emit_value_changed()
self.update()
def _emit_value_changed(self):
# print(f"emit {str(self.lower_value.value)}, {str(self.upper_value.value)}")
self.value_changed.emit(str(self.lower_value.value), str(self.upper_value.value))
def _update_tooltip(self):
text = _("showing bytes {0} to {1} ({2})").format(
self.lower_value.value,
self.upper_value.value,
conversion.humanbytes(self.upper_value.value - self.lower_value.value))
PluginRegistry.execute("update_status_bar", text)
self.setToolTip(text)