From d809d0bcca544e42e3bb1b89f55481bb646c1a90 Mon Sep 17 00:00:00 2001 From: Pier CeccoPierangioliEugenio Date: Wed, 5 Mar 2025 16:02:58 +0000 Subject: [PATCH] feat: added find in the text edit (#320) --- TermTk/TTkCore/string.py | 2 +- TermTk/TTkGui/textdocument.py | 16 ++++++++++++++++ TermTk/TTkWidgets/texedit.py | 36 ++++++++++++++++++++++++----------- 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/TermTk/TTkCore/string.py b/TermTk/TTkCore/string.py index 3e58e928..7afc90c0 100644 --- a/TermTk/TTkCore/string.py +++ b/TermTk/TTkCore/string.py @@ -581,7 +581,7 @@ class TTkString(): ''' return re.search(regexp, self._text, re.IGNORECASE if ignoreCase else 0) - def find(self, *args, **kwargs) -> None: + def find(self, *args, **kwargs) -> Any: return self._text.find(*args, **kwargs) def findall(self, regexp, ignoreCase=False): diff --git a/TermTk/TTkGui/textdocument.py b/TermTk/TTkGui/textdocument.py index 39a91849..bb037418 100644 --- a/TermTk/TTkGui/textdocument.py +++ b/TermTk/TTkGui/textdocument.py @@ -22,6 +22,7 @@ __all__ = ['TTkTextDocument'] +from typing import TYPE_CHECKING from threading import Lock from TermTk.TTkCore.log import TTkLog @@ -29,6 +30,11 @@ from TermTk.TTkCore.signal import pyTTkSignal, pyTTkSlot from TermTk.TTkCore.string import TTkString from TermTk.TTkCore.color import TTkColor +if TYPE_CHECKING: + from TermTk.TTkGui.textcursor import TTkTextCursor +else: + class TTkTextCursor(): ... + class TTkTextDocument(): # ''' # Undo,Redo Logic @@ -305,6 +311,16 @@ class TTkTextDocument(): self.undoAvailable.emit(self.isUndoAvailable()) self.redoAvailable.emit(self.isRedoAvailable()) + def find(self, exp) -> TTkTextCursor: + for i,line in enumerate(self._dataLines): + if -1 != (pos := line.find(str(exp))): + from .textcursor import TTkTextCursor + ret = TTkTextCursor(document=self) + ret.setPosition(line=i, pos=pos) + ret.setPosition(line=i, pos=pos+len(exp), moveMode=TTkTextCursor.MoveMode.KeepAnchor) + return ret + return None + def _restoreSnapshotDiff(self, next=True): if ( not self._snap or ( next and not self._snap._nextDiff) or diff --git a/TermTk/TTkWidgets/texedit.py b/TermTk/TTkWidgets/texedit.py index e5d008a4..7ba6a2aa 100644 --- a/TermTk/TTkWidgets/texedit.py +++ b/TermTk/TTkWidgets/texedit.py @@ -134,15 +134,15 @@ class TTkTextEditView(TTkAbstractScrollView): :param format: A format that is used to specify the type of selection, defaults to :py:class:`TTkK.NONE`. :type format: :py:class:`TTkK.SelectionFormat` :param color: The color used to specify the foreground/background color/mod for the selection. - :type color: :py:class:`TTkColor` + :type color: :py:class:`TTkColor` :param cursor: A cursor that contains a selection in a :py:class:`QTextDocument`. :type cursor: :py:class:`TTkTextCursor` ''' __slots__ = ('_format', '_color', '_cursor') - def __init__(self, - format:TTkK.SelectionFormat=TTkK.NONE, - color:TTkColor=TTkColor.RST, + def __init__(self, + format:TTkK.SelectionFormat=TTkK.NONE, + color:TTkColor=TTkColor.RST, cursor:TTkTextCursor=None) -> None: self._color = color self._format = format @@ -155,13 +155,13 @@ class TTkTextEditView(TTkAbstractScrollView): :rtype: :py:class:`TTkColor` ''' return self._color - + def setColor(self, color:TTkColor) -> None: ''' Set the color. :param color: A color that is used for the selection. - :type color: :py:class:`TTkColor` + :type color: :py:class:`TTkColor` ''' self._color = color @@ -172,16 +172,16 @@ class TTkTextEditView(TTkAbstractScrollView): :rtype: :py:class:`TTkK.SelectionFormat` ''' return self._format - + def setFormat(self, format:TTkK.SelectionFormat) -> None: ''' Set the format. :param format: A format that is used to specify the type of selection. - :type format: :py:class:`TTkK.SelectionFormat` + :type format: :py:class:`TTkK.SelectionFormat` ''' self._format = format - + def cursor(self) -> TTkTextCursor: ''' This propery holds the fcursor that contains a selection in a :py:class:`QTextDocument`. @@ -419,8 +419,8 @@ class TTkTextEditView(TTkAbstractScrollView): def setExtraSelections(self, extraSelections:list[ExtraSelection]) -> None: ''' - This function allows temporarily marking certain regions in the document with a given color, - specified as selections. This can be useful for example in a programming editor to mark a + This function allows temporarily marking certain regions in the document with a given color, + specified as selections. This can be useful for example in a programming editor to mark a whole line of text with a given background color to indicate the existence of a breakpoint. :param extraSelections: the list of extra selections. @@ -476,6 +476,14 @@ class TTkTextEditView(TTkAbstractScrollView): if c := self._textDocument.restoreSnapshotNext(): self._textCursor.restore(c) + @pyTTkSlot(TTkString) + def find(self, exp): + if not (cursor := self._textDocument.find(exp)): + return False + self._textCursor = cursor + self._textDocument.cursorPositionChanged.emit(self._textCursor) + return True + @pyTTkSlot() def clear(self) -> None: pass @@ -573,6 +581,11 @@ class TTkTextEditView(TTkAbstractScrollView): self._scrolToInclude(x,y) return x, y + @pyTTkSlot() + def ensureCursorVisible(self): + cp = self._textCursor.position() + self._scrolToInclude(cp.pos,cp.line) + def _scrolToInclude(self, x, y) -> None: # Scroll the area (if required) to include the position x,y _,_,w,h = self.geometry() @@ -846,6 +859,7 @@ class TTkTextEdit(TTkAbstractScrollArea): 'extraSelections', 'setExtraSelections', 'cut', 'copy', 'paste', 'undo', 'redo', 'isUndoAvailable', 'isRedoAvailable', + 'find', 'ensureCursorVisible', # Export Methods, 'toAnsi', 'toRawText', 'toPlainText', # 'toHtml', 'toMarkdown', ])