Files
krowlog/bigtext.py
2021-10-24 15:11:03 +02:00

109 lines
3.9 KiB
Python

from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from line import Line
from logFileModel import LogFileModel
class BigText(QWidget):
_byte_offset = 0
_left_offset = 0
_selection_start_byte = 0
_selection_end_byte = 0
def __init__(self, model: LogFileModel):
super(BigText, self).__init__()
self.model = model
self.font = QFont("monospace", 12)
self.update_font_metrics(QPainter(self))
self.lines = []
def paintEvent(self, event: QPaintEvent) -> None:
self.draw()
def mousePressEvent(self, e: QMouseEvent) -> None:
if e.buttons() == Qt.MouseButton.LeftButton:
self._selection_start_byte = self.to_byte_offset(e)
self._selection_end_byte = self._selection_start_byte
self.update()
def mouseMoveEvent(self, e: QMouseEvent):
current_byte = self.to_byte_offset(e)
if self._selection_end_byte != current_byte:
self._selection_end_byte = current_byte
self.update()
print("-> %s,%s" %(self._selection_start_byte, self._selection_end_byte))
def to_byte_offset(self, e: QMouseEvent) -> int:
line_number = int(e.pos().y() / self.char_height)
if line_number < len(self.lines):
line = self.lines[line_number]
char_in_line = int(e.pos().x() / self.char_width) + self._left_offset
char_in_line = min(char_in_line, line.length())
#print("%s in line %s" % (char_in_line, line_number))
current_byte = line.byte_offset() + char_in_line
#print("%s + %s = %s" % (line.byte_offset(), char_in_line, current_byte))
else:
current_byte = self.model.byte_count()
return current_byte
def draw(self):
painter = QPainter()
painter.begin(self)
painter.setFont(self.font)
painter.setPen(QColor(0, 0, 0))
self.update_font_metrics( painter)
lines_to_show = self.height() / (self.fontMetrics().height())
self.lines = self.model.data(self._byte_offset, lines_to_show)
y_line_offset = self.char_height;
for l in self.lines:
if l.intersects(self._selection_start_byte, self._selection_end_byte):
self.draw_selection(painter, l, y_line_offset)
painter.drawText(0, y_line_offset, l.line())
y_line_offset = y_line_offset + self.char_height
painter.end()
def draw_selection(self, painter: QPainter, line: Line, y_line_offset: int):
hightlight_color = QColor(255, 255, 0)
if line.includes_byte(self._selection_start_byte):
#print("%s bytes in line: " % (self._selection_start_byte - line.byte_offset()))
x1 = (self._selection_start_byte - line.byte_offset() - self._left_offset) * self.char_width
else:
x1 = 0
if line.includes_byte(self._selection_end_byte):
width = (self._selection_end_byte - line.byte_offset() - self._left_offset) * self.char_width - x1
else:
width = len(line.line().rstrip()) * self.char_width -x1
y1 = y_line_offset- self.char_height
height = self.char_height
rect = QRect(x1,y1,width,height)
#print(rect)
self.hightlight(painter,rect , hightlight_color)
def hightlight(self, painter: QPainter,rect: QRect, color: QColor):
old_brush = painter.brush()
old_pen = painter.pen()
painter.setBrush(color)
painter.setPen(color)
painter.drawRoundedRect(rect, 3.0, 3.0)
#painter.drawRect(rect)
painter.setBrush(old_brush)
painter.setPen(old_pen)
def update_font_metrics(self, painter: QPainter):
fm: QFontMetrics = painter.fontMetrics()
self.char_height = fm.height()
self.char_width = fm.averageCharWidth()# all chars have same with for monospace font
print("font width=%s height=%s" % (self.char_width, self.char_height))