improve highlighting
This commit is contained in:
44
bigtext.py
44
bigtext.py
@@ -1,9 +1,13 @@
|
||||
import math
|
||||
|
||||
from typing import Optional
|
||||
import PyQt6.QtGui
|
||||
from PyQt6.QtCore import *
|
||||
from PyQt6.QtGui import *
|
||||
from PyQt6.QtWidgets import *
|
||||
|
||||
from highlight import Highlight
|
||||
from highlight_selection import HightlightSelection
|
||||
from highlighted_range import HighlightedRange
|
||||
from line import Line
|
||||
from logFileModel import LogFileModel
|
||||
|
||||
@@ -11,9 +15,8 @@ from logFileModel import LogFileModel
|
||||
class BigText(QWidget):
|
||||
_byte_offset = 0
|
||||
_left_offset = 0
|
||||
_selection_start_byte = 0
|
||||
_selection_end_byte = 0
|
||||
|
||||
highlights : [Highlight] = []
|
||||
|
||||
def __init__(self, model: LogFileModel):
|
||||
super(BigText, self).__init__()
|
||||
@@ -21,21 +24,24 @@ class BigText(QWidget):
|
||||
self.font = QFont("monospace", 20)
|
||||
self.update_font_metrics(QPainter(self))
|
||||
self.lines = []
|
||||
self.selection_highlight= HightlightSelection(0,0)
|
||||
self.highlights = [self.selection_highlight]
|
||||
|
||||
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
|
||||
offset = self.to_byte_offset(e)
|
||||
self.selection_highlight.set_start(offset)
|
||||
self.selection_highlight.set_end_byte(offset)
|
||||
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
|
||||
if self.selection_highlight.end_byte != current_byte:
|
||||
self.selection_highlight.set_end_byte(current_byte)
|
||||
self.update()
|
||||
#print("-> %s,%s" %(self._selection_start_byte, self._selection_end_byte))
|
||||
|
||||
@@ -69,8 +75,12 @@ class BigText(QWidget):
|
||||
# draws over a character
|
||||
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)
|
||||
#if l.intersects(self._selection_start_byte, self._selection_end_byte):
|
||||
# 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 = self.char_height;
|
||||
@@ -100,11 +110,21 @@ class BigText(QWidget):
|
||||
#print(rect)
|
||||
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_pen = painter.pen()
|
||||
painter.setBrush(color)
|
||||
painter.setPen(Qt.PenStyle.NoPen)
|
||||
painter.setBrush(brush)
|
||||
painter.setPen(pen)
|
||||
painter.drawRoundedRect(rect, 3.0, 3.0)
|
||||
painter.setBrush(old_brush)
|
||||
painter.setPen(old_pen)
|
||||
|
||||
12
highlight.py
Normal file
12
highlight.py
Normal 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
42
highlight_selection.py
Normal 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
23
highlighted_range.py
Normal 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
|
||||
@@ -2,6 +2,8 @@ from typing import List
|
||||
import os
|
||||
from line import Line
|
||||
|
||||
from settings import Settings
|
||||
|
||||
|
||||
class LogFileModel:
|
||||
def __init__(self, file):
|
||||
@@ -12,8 +14,8 @@ class LogFileModel:
|
||||
|
||||
# TODO handle lines longer than 4096 bytes
|
||||
with open(self._file, 'r') as f:
|
||||
offset = max(0, byte_offset - 4096)
|
||||
offset = offset - offset % 4096 # align to blocks of 4kb
|
||||
offset = max(0, byte_offset - Settings.max_line_length())
|
||||
offset = offset - offset % Settings.max_line_length() # align to blocks of 4kb
|
||||
f.seek(offset)
|
||||
while l := f.readline():
|
||||
new_offset = f.tell()
|
||||
|
||||
2
main.py
2
main.py
@@ -6,6 +6,8 @@ import sys
|
||||
from bigtext import BigText
|
||||
from logFileModel import LogFileModel
|
||||
|
||||
MAX_LINE_LENGTH = 4096
|
||||
|
||||
|
||||
class MainWindow(QMainWindow):
|
||||
def __init__(self, *args, **kwargs):
|
||||
|
||||
6
settings.py
Normal file
6
settings.py
Normal file
@@ -0,0 +1,6 @@
|
||||
|
||||
|
||||
class Settings():
|
||||
@staticmethod
|
||||
def max_line_length():
|
||||
return 4096
|
||||
Reference in New Issue
Block a user