improve highlighting

This commit is contained in:
2021-10-24 18:49:47 +02:00
parent 80741a7249
commit eab422a6ce
7 changed files with 121 additions and 14 deletions

View File

@@ -1,9 +1,13 @@
import math import math
from typing import Optional
import PyQt6.QtGui
from PyQt6.QtCore import * from PyQt6.QtCore import *
from PyQt6.QtGui import * from PyQt6.QtGui import *
from PyQt6.QtWidgets import * from PyQt6.QtWidgets import *
from highlight import Highlight
from highlight_selection import HightlightSelection
from highlighted_range import HighlightedRange
from line import Line from line import Line
from logFileModel import LogFileModel from logFileModel import LogFileModel
@@ -11,9 +15,8 @@ from logFileModel import LogFileModel
class BigText(QWidget): class BigText(QWidget):
_byte_offset = 0 _byte_offset = 0
_left_offset = 0 _left_offset = 0
_selection_start_byte = 0
_selection_end_byte = 0
highlights : [Highlight] = []
def __init__(self, model: LogFileModel): def __init__(self, model: LogFileModel):
super(BigText, self).__init__() super(BigText, self).__init__()
@@ -21,21 +24,24 @@ class BigText(QWidget):
self.font = QFont("monospace", 20) self.font = QFont("monospace", 20)
self.update_font_metrics(QPainter(self)) self.update_font_metrics(QPainter(self))
self.lines = [] self.lines = []
self.selection_highlight= HightlightSelection(0,0)
self.highlights = [self.selection_highlight]
def paintEvent(self, event: QPaintEvent) -> None: def paintEvent(self, event: QPaintEvent) -> None:
self.draw() self.draw()
def mousePressEvent(self, e: QMouseEvent) -> None: def mousePressEvent(self, e: QMouseEvent) -> None:
if e.buttons() == Qt.MouseButton.LeftButton: if e.buttons() == Qt.MouseButton.LeftButton:
self._selection_start_byte = self.to_byte_offset(e) offset = self.to_byte_offset(e)
self._selection_end_byte = self._selection_start_byte self.selection_highlight.set_start(offset)
self.selection_highlight.set_end_byte(offset)
self.update() self.update()
def mouseMoveEvent(self, e: QMouseEvent): def mouseMoveEvent(self, e: QMouseEvent):
current_byte = self.to_byte_offset(e) current_byte = self.to_byte_offset(e)
if self._selection_end_byte != current_byte: if self.selection_highlight.end_byte != current_byte:
self._selection_end_byte = current_byte self.selection_highlight.set_end_byte(current_byte)
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))
@@ -69,8 +75,12 @@ class BigText(QWidget):
# draws over a character # draws over a character
y_line_offset = self.char_height; y_line_offset = self.char_height;
for l in self.lines: for l in self.lines:
if l.intersects(self._selection_start_byte, self._selection_end_byte): #if l.intersects(self._selection_start_byte, self._selection_end_byte):
self.draw_selection(painter, l, y_line_offset) # self.draw_selection(painter, l, y_line_offset)
for h in self.highlights:
optional_highlight_range = h.compute_highlight(l)
if optional_highlight_range:
self.draw_highlight(optional_highlight_range, painter, y_line_offset)
y_line_offset = y_line_offset + self.char_height y_line_offset = y_line_offset + self.char_height
y_line_offset = self.char_height; y_line_offset = self.char_height;
@@ -100,11 +110,21 @@ class BigText(QWidget):
#print(rect) #print(rect)
self.hightlight(painter,rect , hightlight_color) self.hightlight(painter,rect , hightlight_color)
def hightlight(self, painter: QPainter,rect: QRect, color: QColor): def draw_highlight(self, highlight: HighlightedRange, painter: QPainter, y_line_offset:int):
x1 = highlight.get_start()*self.char_width
width = highlight.get_width()*self.char_width
y1 = y_line_offset- self.char_height + self.char_height / 7
height = self.char_height
rect = QRect(x1,y1,width,height)
#print(rect)
self.hightlight(painter,rect , highlight.get_brush(), highlight.get_pen())
def hightlight(self, painter: QPainter,rect: QRect, brush: QBrush, pen:QPen):
old_brush = painter.brush() old_brush = painter.brush()
old_pen = painter.pen() old_pen = painter.pen()
painter.setBrush(color) painter.setBrush(brush)
painter.setPen(Qt.PenStyle.NoPen) painter.setPen(pen)
painter.drawRoundedRect(rect, 3.0, 3.0) painter.drawRoundedRect(rect, 3.0, 3.0)
painter.setBrush(old_brush) painter.setBrush(old_brush)
painter.setPen(old_pen) painter.setPen(old_pen)

12
highlight.py Normal file
View File

@@ -0,0 +1,12 @@
from typing import Optional
from line import Line
from highlighted_range import HighlightedRange
class Highlight:
def __init__(self):
pass
def compute_highlight(self, line: Line) -> Optional[HighlightedRange]:
return None

42
highlight_selection.py Normal file
View File

@@ -0,0 +1,42 @@
from typing import Optional
from highlight import Highlight
from highlighted_range import HighlightedRange
from line import Line
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
from settings import Settings
class HightlightSelection(Highlight):
def __init__(self, start_byte: int, end_byte: int):
self.start_byte = start_byte
self.end_byte = end_byte
def set_start(self, start_byte):
self.start_byte = start_byte
def set_end_byte(self, end_byte):
self.end_byte = end_byte
def compute_highlight(self, line: Line) -> Optional[HighlightedRange]:
begin = min(self.start_byte, self.end_byte)
end = max(self.start_byte, self.end_byte)
if line.intersects(begin, end):
if line.includes_byte(begin):
start = begin - line.byte_offset()
else:
start = 0
if line.includes_byte(end):
length = end - line.byte_offset() - start
else:
length = Settings.max_line_length() -start
return HighlightedRange(start, length, QBrush(QColor(255, 255, 0)), Qt.PenStyle.NoPen)
else:
return None

23
highlighted_range.py Normal file
View File

@@ -0,0 +1,23 @@
from PyQt6.QtCore import *
from PyQt6.QtGui import *
from PyQt6.QtWidgets import *
class HighlightedRange:
def __init__(self, start: int, width: int, brush: QBrush = QBrush(), pen: QPen = Qt.PenStyle.NoPen):
self.start = start
self.width = width
self.brush = brush
self.pen = pen
def get_start(self):
return self.start
def get_width(self):
return self.width
def get_brush(self):
return self.brush
def get_pen(self):
return self.pen

View File

@@ -2,6 +2,8 @@ from typing import List
import os import os
from line import Line from line import Line
from settings import Settings
class LogFileModel: class LogFileModel:
def __init__(self, file): def __init__(self, file):
@@ -12,8 +14,8 @@ class LogFileModel:
# TODO handle lines longer than 4096 bytes # TODO handle lines longer than 4096 bytes
with open(self._file, 'r') as f: with open(self._file, 'r') as f:
offset = max(0, byte_offset - 4096) offset = max(0, byte_offset - Settings.max_line_length())
offset = offset - offset % 4096 # align to blocks of 4kb offset = offset - offset % Settings.max_line_length() # align to blocks of 4kb
f.seek(offset) f.seek(offset)
while l := f.readline(): while l := f.readline():
new_offset = f.tell() new_offset = f.tell()

View File

@@ -6,6 +6,8 @@ import sys
from bigtext import BigText from bigtext import BigText
from logFileModel import LogFileModel from logFileModel import LogFileModel
MAX_LINE_LENGTH = 4096
class MainWindow(QMainWindow): class MainWindow(QMainWindow):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):

6
settings.py Normal file
View File

@@ -0,0 +1,6 @@
class Settings():
@staticmethod
def max_line_length():
return 4096