improve highlighting
This commit is contained in:
44
bigtext.py
44
bigtext.py
@@ -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
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
|
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()
|
||||||
|
|||||||
2
main.py
2
main.py
@@ -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
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