Note_Qt/qt_markdown/text_formatter/text_formatter.py

69 lines
3.3 KiB
Python

from PyQt6.QtWidgets import QTextEdit
from PyQt6.QtCore import QTimer, QDir, QUrl, QVariant, Qt
from PyQt6.QtGui import QTextCharFormat, QFont, QTextCursor, QTextImageFormat, QImage, QTextDocument, QTextBlockFormat
from .header_formatter import HeaderFormatter
from .text_style_formatter import TextStyleFormatter
class TextFormatter:
def __init__(self, text_edit: QTextEdit):
self.text_edit = text_edit
self.timer = QTimer()
self.timer.setSingleShot(True)
self.timer.timeout.connect(self.process_text_changes)
self.text_edit.textChanged.connect(self.delay_text)
self.header_formatter = HeaderFormatter()
self.text_style_formatter = TextStyleFormatter()
def delay_text(self):
self.timer.start(500)
def process_text_changes(self):
cursor = self.text_edit.textCursor()
cursor.beginEditBlock()
cursor.select(QTextCursor.SelectionType.Document)
cursor.setCharFormat(QTextCharFormat())
self.header_formatter.process_headers(self.text_edit)
self.text_style_formatter.apply_text_formatting(cursor, self.text_edit.toPlainText())
self.process_markdown_images(cursor, self.text_edit.toPlainText())
cursor.endEditBlock()
def toggle_special_symbols(self, symbol_start, symbol_end=None):
cursor = self.text_edit.textCursor()
if cursor.hasSelection():
selected_text = cursor.selectedText()
full_text = self.text_edit.toPlainText()
start = cursor.selectionStart()
end = cursor.selectionEnd()
corrected_text, new_start, new_end = self._toggle_special_symbols_in_selection(full_text, start, end, symbol_start, symbol_end)
self.text_edit.setPlainText(corrected_text)
cursor.setPosition(new_start)
cursor.setPosition(new_end, QTextCursor.MoveMode.KeepAnchor)
self.text_edit.setTextCursor(cursor)
else:
cursor.select(QTextCursor.SelectionType.WordUnderCursor)
word = cursor.selectedText()
full_text = self.text_edit.toPlainText()
start = cursor.selectionStart()
end = cursor.selectionEnd()
corrected_text, new_start, new_end = self._toggle_special_symbols_in_selection(full_text, start, end, symbol_start, symbol_end)
self.text_edit.setPlainText(corrected_text)
cursor.setPosition(new_start)
cursor.setPosition(new_end, QTextCursor.MoveMode.KeepAnchor)
self.text_edit.setTextCursor(cursor)
def _toggle_special_symbols_in_selection(self, text, start, end, symbol_start, symbol_end=None):
if symbol_end is None:
symbol_end = symbol_start
if text[start - len(symbol_start):start] == symbol_start and text[end:end + len(symbol_end)] == symbol_end:
corrected_text = text[:start - len(symbol_start)] + text[start:end] + text[end + len(symbol_end):]
new_start = start - len(symbol_start)
new_end = end - len(symbol_start)
return corrected_text, new_start, new_end
else:
corrected_text = text[:start] + symbol_start + text[start:end] + symbol_end + text[end:]
new_start = start + len(symbol_start)
new_end = end + len(symbol_end)
return corrected_text, new_start, new_end