scroll with scrollbars
This commit is contained in:
75
bigtext.py
75
bigtext.py
@@ -2,8 +2,11 @@ import math
|
|||||||
import re
|
import re
|
||||||
from typing import Optional, List
|
from typing import Optional, List
|
||||||
import PyQt6.QtGui
|
import PyQt6.QtGui
|
||||||
|
from PyQt6 import QtGui
|
||||||
|
|
||||||
from PyQt6.QtCore import *
|
from PyQt6.QtCore import *
|
||||||
from PyQt6.QtGui import *
|
from PyQt6.QtGui import *
|
||||||
|
from PyQt6.QtGui import QMouseEvent
|
||||||
from PyQt6.QtWidgets import *
|
from PyQt6.QtWidgets import *
|
||||||
|
|
||||||
from highlight import Highlight
|
from highlight import Highlight
|
||||||
@@ -17,16 +20,49 @@ import re
|
|||||||
from settings import Settings
|
from settings import Settings
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
class BigText(QWidget):
|
class BigText(QWidget):
|
||||||
|
def __init__(self, model: LogFileModel):
|
||||||
|
super(BigText, self).__init__()
|
||||||
|
|
||||||
|
self.grid = QGridLayout()
|
||||||
|
self.grid.setContentsMargins(0,0,0,0)
|
||||||
|
self.grid.setHorizontalSpacing(0)
|
||||||
|
self.grid.setVerticalSpacing(0)
|
||||||
|
self.setLayout(self.grid)
|
||||||
|
|
||||||
|
big_text = InnerBigText(model, self)
|
||||||
|
big_text.setSizePolicy(QSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding))
|
||||||
|
|
||||||
|
self.h_scroll_bar = QScrollBar(Qt.Orientation.Horizontal)
|
||||||
|
self.h_scroll_bar.setMinimum(0)
|
||||||
|
self.h_scroll_bar.setMaximum(1)
|
||||||
|
self.h_scroll_bar.valueChanged.connect(big_text.h_scroll_event)
|
||||||
|
|
||||||
|
self.v_scroll_bar = QScrollBar()
|
||||||
|
self.v_scroll_bar.setPageStep(1)
|
||||||
|
self.v_scroll_bar.valueChanged.connect(big_text.v_scroll_event)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
self.grid.addWidget(big_text,0,0)
|
||||||
|
|
||||||
|
self.grid.addWidget(self.h_scroll_bar, 1, 0)
|
||||||
|
self.grid.addWidget(self.v_scroll_bar, 0, 1)
|
||||||
|
|
||||||
|
|
||||||
|
class InnerBigText(QWidget):
|
||||||
_byte_offset = 0
|
_byte_offset = 0
|
||||||
_left_offset = 0
|
_left_offset = 0
|
||||||
scroll_lines = 0
|
scroll_lines = 0
|
||||||
|
longest_line = 0
|
||||||
|
|
||||||
highlights: [Highlight] = []
|
highlights: [Highlight] = []
|
||||||
|
|
||||||
def __init__(self, model: LogFileModel):
|
def __init__(self, model: LogFileModel, parent: BigText):
|
||||||
super(BigText, self).__init__()
|
super(InnerBigText, self).__init__()
|
||||||
self.model = model
|
self.model = model
|
||||||
|
self.parent = parent
|
||||||
self.font = QFont("monospace", 12)
|
self.font = QFont("monospace", 12)
|
||||||
self.update_font_metrics(QPainter(self))
|
self.update_font_metrics(QPainter(self))
|
||||||
self.lines = []
|
self.lines = []
|
||||||
@@ -48,10 +84,9 @@ class BigText(QWidget):
|
|||||||
#print("wheel event fired :) %s" % (direction))
|
#print("wheel event fired :) %s" % (direction))
|
||||||
self.scroll_lines = direction * 3
|
self.scroll_lines = direction * 3
|
||||||
self.update()
|
self.update()
|
||||||
#self.draw(direction * 3)
|
self.parent.v_scroll_bar.setValue(self._byte_offset)
|
||||||
#self._vscrollbar.setValue(self._byte_offset)
|
|
||||||
|
|
||||||
def mousePressEvent(self, e: QMouseEvent) -> None:
|
def mousePressEvent(self, e: QtGui.QMouseEvent) -> None:
|
||||||
if e.buttons() == Qt.MouseButton.LeftButton:
|
if e.buttons() == Qt.MouseButton.LeftButton:
|
||||||
offset = self.to_byte_offset(e)
|
offset = self.to_byte_offset(e)
|
||||||
self.selection_highlight.set_start(offset)
|
self.selection_highlight.set_start(offset)
|
||||||
@@ -66,6 +101,23 @@ class BigText(QWidget):
|
|||||||
self.update()
|
self.update()
|
||||||
# print("-> %s,%s" %(self._selection_start_byte, self._selection_end_byte))
|
# print("-> %s,%s" %(self._selection_start_byte, self._selection_end_byte))
|
||||||
|
|
||||||
|
def h_scroll_event(self, left_offset: int):
|
||||||
|
self._left_offset = left_offset
|
||||||
|
#print("left_offset: %d" % left_offset)
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
def v_scroll_event(self, byte_offset: int):
|
||||||
|
self._byte_offset = byte_offset
|
||||||
|
self.update()
|
||||||
|
|
||||||
|
def update_longest_line(self, length: int):
|
||||||
|
width_in_chars = self.width() / self.char_width
|
||||||
|
#print("width_in_chars: %d" % width_in_chars)
|
||||||
|
if self.longest_line < length:
|
||||||
|
self.longest_line = length
|
||||||
|
maximum = max(0, length - width_in_chars+1)
|
||||||
|
self.parent.h_scroll_bar.setMaximum(maximum)
|
||||||
|
|
||||||
def to_byte_offset(self, e: QMouseEvent) -> int:
|
def to_byte_offset(self, e: QMouseEvent) -> int:
|
||||||
line_number = int(e.pos().y() / self.char_height)
|
line_number = int(e.pos().y() / self.char_height)
|
||||||
|
|
||||||
@@ -92,6 +144,11 @@ class BigText(QWidget):
|
|||||||
self.lines = self.model.data(self._byte_offset, self.scroll_lines, lines_to_show)
|
self.lines = self.model.data(self._byte_offset, self.scroll_lines, lines_to_show)
|
||||||
self.scroll_lines=0
|
self.scroll_lines=0
|
||||||
self._byte_offset = self.lines[0].byte_offset()
|
self._byte_offset = self.lines[0].byte_offset()
|
||||||
|
self.parent.v_scroll_bar.setMaximum(
|
||||||
|
self.model.byte_count() - 1 - 10) # document length == maximum + pageStep + aFewBytesSoThatTheLastLineIsShown
|
||||||
|
|
||||||
|
for l in self.lines:
|
||||||
|
self.update_longest_line(len(l.line()))
|
||||||
|
|
||||||
# draw hightlights first - some characters may overlap to the next line
|
# draw hightlights first - some characters may overlap to the next line
|
||||||
# by drawing the background hightlights first we prevent that the hightlight
|
# by drawing the background hightlights first we prevent that the hightlight
|
||||||
@@ -105,14 +162,16 @@ class BigText(QWidget):
|
|||||||
self.draw_highlight(highlight, painter, y_line_offset)
|
self.draw_highlight(highlight, painter, y_line_offset)
|
||||||
y_line_offset = y_line_offset + self.char_height
|
y_line_offset = y_line_offset + self.char_height
|
||||||
|
|
||||||
|
left_offset = -1*self._left_offset * self.char_width
|
||||||
y_line_offset = self.char_height;
|
y_line_offset = self.char_height;
|
||||||
for l in self.lines:
|
for l in self.lines:
|
||||||
painter.drawText(0, y_line_offset, l.line())
|
painter.drawText(left_offset, y_line_offset, l.line())
|
||||||
y_line_offset = y_line_offset + self.char_height
|
y_line_offset = y_line_offset + self.char_height
|
||||||
|
|
||||||
painter.end()
|
painter.end()
|
||||||
|
|
||||||
def draw_highlight(self, highlight: HighlightedRange, painter: QPainter, y_line_offset: int):
|
def draw_highlight(self, highlight: HighlightedRange, painter: QPainter, y_line_offset: int):
|
||||||
|
left_offset = -1*self._left_offset * self.char_width
|
||||||
x1 = highlight.get_start() * self.char_width
|
x1 = highlight.get_start() * self.char_width
|
||||||
width = highlight.get_width() * self.char_width
|
width = highlight.get_width() * self.char_width
|
||||||
|
|
||||||
@@ -121,10 +180,10 @@ class BigText(QWidget):
|
|||||||
|
|
||||||
if highlight.is_highlight_full_line():
|
if highlight.is_highlight_full_line():
|
||||||
full_width = Settings.max_line_length() * self.char_width
|
full_width = Settings.max_line_length() * self.char_width
|
||||||
rect = QRect(0, y1, full_width, height)
|
rect = QRect(left_offset, y1, full_width, height)
|
||||||
self.highlight_background(painter, rect, highlight.get_brush_full_line())
|
self.highlight_background(painter, rect, highlight.get_brush_full_line())
|
||||||
|
|
||||||
rect = QRect(x1, y1, width, height)
|
rect = QRect(left_offset+x1, y1, width, height)
|
||||||
self.highlight_background(painter, rect, highlight.get_brush())
|
self.highlight_background(painter, rect, highlight.get_brush())
|
||||||
|
|
||||||
def highlight_background(self, painter: QPainter, rect: QRect, brush: QBrush):
|
def highlight_background(self, painter: QPainter, rect: QRect, brush: QBrush):
|
||||||
|
|||||||
@@ -121,3 +121,5 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
|||||||
2018-09-06T00:00:31.268Z,2,vapfacbk01,ApplicationStateService.getState,AXC_5.14_526,,successful
|
2018-09-06T00:00:31.268Z,2,vapfacbk01,ApplicationStateService.getState,AXC_5.14_526,,successful
|
||||||
2018-09-06T00:00:31.309Z,2,vapfacbk01,ApplicationLockService.getLocks,AXC_5.14_526,,successful
|
2018-09-06T00:00:31.309Z,2,vapfacbk01,ApplicationLockService.getLocks,AXC_5.14_526,,successful
|
||||||
2018-09-06T00:00:31.311Z,2,vapfacbk01,ApplicationStateService.getState,AXC_5.14_526,,successful
|
2018-09-06T00:00:31.311Z,2,vapfacbk01,ApplicationStateService.getState,AXC_5.14_526,,successful
|
||||||
|
---------1---------2---------3---------4---------5---------6---------7---------8---------9--------10---------1---------2---------3---------4---------5---------6---------7---------8---------9--------10---------1---------2---------3---------4---------5---------6---------7---------8---------9--------10
|
||||||
|
---------1---------2---------3---------4---------5---------6---------7---------8---------9--------10---------1---------2---------3---------4---------5---------6---------7---------8---------9--------10---------1---------2---------3---------4---------5---------6---------7---------8---------9--------10---------1---------2---------3---------4---------5---------6---------7---------8---------9--------10
|
||||||
@@ -31,7 +31,7 @@ class LogFileModel:
|
|||||||
f.seek(offset)
|
f.seek(offset)
|
||||||
while l := f.readline():
|
while l := f.readline():
|
||||||
new_offset = f.tell()
|
new_offset = f.tell()
|
||||||
line = Line(offset, new_offset, l.decode("utf8").replace("\r", "").replace("\n", ""))
|
line = Line(offset, new_offset, l.decode("utf8", errors="ignore").replace("\r", "").replace("\n", ""))
|
||||||
# print("%s %s" %(line.byte_offset(), line.line()))
|
# print("%s %s" %(line.byte_offset(), line.line()))
|
||||||
if offset < byte_offset:
|
if offset < byte_offset:
|
||||||
lines_before_offset.append(line)
|
lines_before_offset.append(line)
|
||||||
@@ -48,7 +48,7 @@ class LogFileModel:
|
|||||||
elif eof_reached:
|
elif eof_reached:
|
||||||
# we always return the number of requested lines even if we reach the end of the file
|
# we always return the number of requested lines even if we reach the end of the file
|
||||||
lines_to_return_from_before_offset = int(lines_to_find - len(lines_after_offset));
|
lines_to_return_from_before_offset = int(lines_to_find - len(lines_after_offset));
|
||||||
print(lines_to_return_from_before_offset)
|
#print(lines_to_return_from_before_offset)
|
||||||
if lines_to_return_from_before_offset > 0:
|
if lines_to_return_from_before_offset > 0:
|
||||||
result = result + lines_before_offset[-lines_to_return_from_before_offset:]
|
result = result + lines_before_offset[-lines_to_return_from_before_offset:]
|
||||||
result = result + lines_after_offset
|
result = result + lines_after_offset
|
||||||
|
|||||||
6
main.py
6
main.py
@@ -33,7 +33,11 @@ class MainWindow(QMainWindow):
|
|||||||
#model = LogFileModel("/home/andi/ws/performanceDb/data/production/logs_2018-09-06_2018-09-06.csv")
|
#model = LogFileModel("/home/andi/ws/performanceDb/data/production/logs_2018-09-06_2018-09-06.csv")
|
||||||
model = LogFileModel("/home/andi/ws/ravenlog/example.log")
|
model = LogFileModel("/home/andi/ws/ravenlog/example.log")
|
||||||
big_text = BigText(model)
|
big_text = BigText(model)
|
||||||
tabs.addTab(big_text, QIcon("icons/tables.png"), "tables")
|
tabs.addTab(big_text, "small")
|
||||||
|
|
||||||
|
model = LogFileModel("/home/andi/ws/performanceDb/data/production/logs_2018-09-06_2018-09-06.csv")
|
||||||
|
big_text = BigText(model)
|
||||||
|
tabs.addTab(big_text, "big")
|
||||||
|
|
||||||
return tabs
|
return tabs
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user