diff --git a/libs/pyTermTk/TermTk/TTkCore/string.py b/libs/pyTermTk/TermTk/TTkCore/string.py index fbff4bfa..04a90758 100644 --- a/libs/pyTermTk/TermTk/TTkCore/string.py +++ b/libs/pyTermTk/TermTk/TTkCore/string.py @@ -638,7 +638,7 @@ class TTkString(): sum(unicodedata.category(ch) in ('Me','Mn') for ch in txt) ) @staticmethod - def _getLenTextWoZero(txt:str): + def _getLenTextWoZero(txt:str) -> int: return ( len(txt) - sum(unicodedata.category(ch) in ('Me','Mn') for ch in txt) ) diff --git a/libs/pyTermTk/TermTk/TTkGui/textcursor.py b/libs/pyTermTk/TermTk/TTkGui/textcursor.py index 249656bc..8461031e 100644 --- a/libs/pyTermTk/TermTk/TTkGui/textcursor.py +++ b/libs/pyTermTk/TermTk/TTkGui/textcursor.py @@ -20,16 +20,13 @@ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. +from __future__ import annotations + __all__ = ['TTkTextCursor'] from enum import IntEnum -from typing import List - -try: - from typing import Self -except: - class Self(): pass +from typing import List, Optional, Tuple from TermTk.TTkCore.log import TTkLog from TermTk.TTkCore.color import TTkColor @@ -48,7 +45,7 @@ class _CP(): pos:int def __init__(self, l:int=0, p:int=0) -> None: self.set(l,p) - def copy(self) -> Self: + def copy(self) -> _CP: return _CP(self.line, self.pos) def set(self, l, p) -> None: self.pos = p @@ -64,7 +61,7 @@ class _Prop(): self.anchor:_CP = anchor self.position:_CP = position - def copy(self) -> Self: + def copy(self) -> _Prop: return _Prop(self.anchor.copy(), self.position.copy()) def selectionStart(self) -> _CP: @@ -183,30 +180,31 @@ class TTkTextCursor(): PreviousRow = MoveOperation.PreviousRow __slots__ = ('_document', '_properties', '_cID', '_color', '_autoChanged') - def __init__(self, document:TTkTextDocument=None) -> None: + _color:Optional[TTkColor] + _document:TTkTextDocument + _properties:list[_Prop] + def __init__(self, document:TTkTextDocument) -> None: self._color = None self._cID = 0 self._autoChanged = False self._properties = [_Prop(_CP(),_CP())] - if document: - self._document = document - self._document.contentsChanged.connect(self._documentContentChanged) + self._document = document + self._document.contentsChanged.connect(self._documentContentChanged) def _documentContentChanged(self): if self._autoChanged: return True self.clearCursors() self.clearSelection() - def copy(self) -> Self: - ret = TTkTextCursor() - ret._document = self._document + def copy(self) -> TTkTextCursor: + ret = TTkTextCursor(self._document) ret._properties = [p.copy() for p in self._properties] ret._cID = self._cID ret._color = self._color ret._autoChanged = self._autoChanged return ret - def restore(self, cursor:Self) -> None: + def restore(self, cursor:TTkTextCursor) -> None: self._document = cursor._document self._properties = [p.copy() for p in cursor._properties] self._cID = cursor._cID @@ -226,7 +224,7 @@ class TTkTextCursor(): def position(self) -> _CP: return self._properties[self._cID].position - def cursors(self) -> list[_CP]: + def cursors(self) -> list[_Prop]: return self._properties def addCursor(self, line:int, pos:int) -> None: @@ -302,7 +300,7 @@ class TTkTextCursor(): if notify or currPos != currCurs.position.toNum(): self._document.cursorPositionChanged.emit(self) - def movePosition(self, operation:MoveOperation, moveMode:MoveMode=MoveMode.MoveAnchor, n=1, textWrap:TTkTextWrap=None) -> None: + def movePosition(self, operation:MoveOperation, moveMode:MoveMode=MoveMode.MoveAnchor, n=1, textWrap:Optional[TTkTextWrap]=None) -> None: currPos = self.position().toNum() def moveRight(cID,p,_): if p.pos < len(self._document._dataLines[p.line]): @@ -318,6 +316,8 @@ class TTkTextCursor(): self.setPosition(p.line-1, len(self._document._dataLines[p.line-1]) , moveMode, cID=cID) def moveUpDown(offset): def _moveUpDown(cID,p,n): + if not textWrap: + raise ValueError("textWrap is required for the Up,Down movement") cx, cy = textWrap.dataToScreenPosition(p.line, p.pos) x, y = textWrap.normalizeScreenPosition(cx,cy+offset*n) line, pos = textWrap.screenToDataPosition(x,y) @@ -359,11 +359,13 @@ class TTkTextCursor(): # if there is no selection, just select the next n chars till the end of the line # the newline is not replaced self._document._acquire() + if isinstance(text,str): + text=TTkString(text) for p in self._properties: if not p.hasSelection(): line = p.position.line pos = p.position.pos - lenWoZero = TTkString._getLenTextWoZero(text) + lenWoZero =text.termWidth() size = len(self._document._dataLines[line]) for _ in range(lenWoZero): pos = self._document._dataLines[line].nextPos(pos) @@ -525,7 +527,7 @@ class TTkTextCursor(): return True return False - def _removeSelectedText(self) -> None: + def _removeSelectedText(self) -> Tuple[int,int,int]: currPos = self.position().toNum() lineFirst = self._properties[0].selectionStart().line diff --git a/libs/pyTermTk/TermTk/TTkGui/textdocument.py b/libs/pyTermTk/TermTk/TTkGui/textdocument.py index 9f0e7ab2..aa1fef2c 100644 --- a/libs/pyTermTk/TermTk/TTkGui/textdocument.py +++ b/libs/pyTermTk/TermTk/TTkGui/textdocument.py @@ -316,7 +316,7 @@ class TTkTextDocument(): self.undoAvailable.emit(self.isUndoAvailable()) self.redoAvailable.emit(self.isRedoAvailable()) - def find(self, exp:TTkStringType) -> TTkTextCursor: + def find(self, exp:TTkStringType) -> Optional[TTkTextCursor]: for i,line in enumerate(self._dataLines): if -1 != (pos := line.find(str(exp))): from .textcursor import TTkTextCursor diff --git a/libs/pyTermTk/TermTk/TTkWidgets/texedit.py b/libs/pyTermTk/TermTk/TTkWidgets/texedit.py index 25f6fd2a..f813420a 100644 --- a/libs/pyTermTk/TermTk/TTkWidgets/texedit.py +++ b/libs/pyTermTk/TermTk/TTkWidgets/texedit.py @@ -223,12 +223,12 @@ class TTkTextEditView(TTkAbstractScrollView): __slots__ = ('_format', '_color', '_cursor') def __init__(self, + cursor:TTkTextCursor, format:TTkK.SelectionFormat=TTkK.NONE, - color:TTkColor=TTkColor.RST, - cursor:Optional[TTkTextCursor]=None) -> None: + color:TTkColor=TTkColor.RST) -> None: self._color = color self._format = format - self._cursor = cursor if cursor else TTkTextCursor() + self._cursor = cursor def color(self) -> TTkColor: '''