diff --git a/TermTk/TTkWidgets/TTkModelView/table.py b/TermTk/TTkWidgets/TTkModelView/table.py index 116c4f17..385111c7 100644 --- a/TermTk/TTkWidgets/TTkModelView/table.py +++ b/TermTk/TTkWidgets/TTkModelView/table.py @@ -53,7 +53,7 @@ class TTkTable(TTkAbstractScrollArea): super().__init__(parent=parent, visible=visible, **kwargs) self._tableView = kwargs.get('TableWidget',TTkTableWidget(**kwargs)) self.setViewport(self._tableView) - self.setFocusPolicy(TTkK.ClickFocus) + # self.setFocusPolicy(TTkK.ClickFocus) self.model = self._tableView.model self.setModel = self._tableView.setModel @@ -75,6 +75,9 @@ class TTkTable(TTkAbstractScrollArea): self.setHSeparatorVisibility = self._tableView.setHSeparatorVisibility self.setVSeparatorVisibility = self._tableView.setVSeparatorVisibility + self.setFocus = self._tableView.setFocus + self.focusChanged = self._tableView.focusChanged + # # Forward the signal # self.itemActivated = self._tableView.itemActivated # self.itemChanged = self._tableView.itemChanged diff --git a/TermTk/TTkWidgets/TTkModelView/tablewidget.py b/TermTk/TTkWidgets/TTkModelView/tablewidget.py index 2326e22b..0d5e35ec 100644 --- a/TermTk/TTkWidgets/TTkModelView/tablewidget.py +++ b/TermTk/TTkWidgets/TTkModelView/tablewidget.py @@ -32,7 +32,7 @@ from TermTk.TTkCore.signal import pyTTkSignal, pyTTkSlot from TermTk.TTkGui.textdocument import TTkTextDocument -from TermTk.TTkWidgets.texedit import TTkTextEdit +from TermTk.TTkWidgets.texedit import TTkTextEdit, TTkTextEditView from TermTk.TTkWidgets.lineedit import TTkLineEdit from TermTk.TTkWidgets.spinbox import TTkSpinBox from TermTk.TTkWidgets.TTkPickers.textpicker import TTkTextPicker, TTkTextDialogPicker @@ -79,6 +79,25 @@ class _HeaderView(): def isVisible(self) -> bool: return self._visible +class _TTkTextEditViewCustom(TTkTextEditView): + __slots__ = ('enterPressed') + def __init__(self, **kwargs): + self.enterPressed = pyTTkSignal(bool) + super().__init__(**kwargs) + + def keyEvent(self, evt): + if ( evt.type == TTkK.SpecialKey and + evt.mod==TTkK.NoModifier and + evt.key == TTkK.Key_Enter ): + self.enterPressed.emit(True) + return True + elif ( evt.type == TTkK.SpecialKey and + evt.mod==TTkK.ControlModifier|TTkK.AltModifier and + evt.key == TTkK.Key_M ): + evt.mod = TTkK.NoModifier + evt.key = TTkK.Key_Enter + return super().keyEvent(evt) + class TTkTableWidget(TTkAbstractScrollView): '''TTkTableWidget''' @@ -88,6 +107,7 @@ class TTkTableWidget(TTkAbstractScrollView): 'lineColor': TTkColor.fg("#444444"), 'headerColor': TTkColor.fg("#FFFFFF")+TTkColor.bg("#444444")+TTkColor.BOLD, 'hoverColor': TTkColor.fg("#FFFF00")+TTkColor.bg("#0088AA")+TTkColor.BOLD, + 'currentColor': TTkColor.fg("#FFFF00")+TTkColor.bg("#0088FF")+TTkColor.BOLD, 'selectedColor': TTkColor.bg("#0066AA"), 'separatorColor': TTkColor.fg("#555555")+TTkColor.bg("#444444")}, 'disabled': { @@ -95,6 +115,7 @@ class TTkTableWidget(TTkAbstractScrollView): 'lineColor': TTkColor.fg("#888888"), 'headerColor': TTkColor.fg("#888888"), 'hoverColor': TTkColor.bg("#888888"), + 'currentColor': TTkColor.bg("#888888"), 'selectedColor': TTkColor.fg("#888888"), 'separatorColor': TTkColor.fg("#888888")}, } @@ -106,7 +127,7 @@ class TTkTableWidget(TTkAbstractScrollView): '_colsPos', '_rowsPos', '_internal', '_selected', '_hSeparatorSelected', '_vSeparatorSelected', - '_hoverPos', '_dragPos', + '_hoverPos', '_dragPos', '_currentPos', '_sortColumn', '_sortOrder', '_fastCheck', '_guessDataEdit', # Signals @@ -134,6 +155,7 @@ class TTkTableWidget(TTkAbstractScrollView): self._selected = None self._hoverPos = None self._dragPos = None + self._currentPos = None self._internal = {} self._hSeparatorSelected = None self._vSeparatorSelected = None @@ -143,7 +165,7 @@ class TTkTableWidget(TTkAbstractScrollView): super().__init__(**kwargs) self._refreshLayout() self.setMinimumHeight(1) - self.setFocusPolicy(TTkK.ClickFocus) + self.setFocusPolicy(TTkK.ClickFocus + TTkK.TabFocus) # self._rootItem = TTkTableWidgetItem(expanded=True) # self.clear() self.viewChanged.connect(self._viewChangedHandler) @@ -368,9 +390,11 @@ class TTkTableWidget(TTkAbstractScrollView): return row,col def _editStr(self, x,y,w,h, row, col, data): + _tev = _TTkTextEditViewCustom() _te = TTkTextEdit( parent=self, pos=(x, y), size=(w,h), readOnly=False, wrapMode=TTkK.NoWrap) + _tev = _te.textEditView() _te.setText(data) _te.setFocus() @@ -382,14 +406,45 @@ class TTkTableWidget(TTkAbstractScrollView): self._tableModel.setData(row,col,txt) self.update() _te.close() - + self.setFocus() + + # Override the key event + _ke = _tev.keyEvent + _doc = _tev.document() + _cur = _tev.textCursor() + def _keyEvent(evt): + if ( evt.type == TTkK.SpecialKey): + _line = _cur.anchor().line + _pos = _cur.anchor().pos + _lineCount = _doc.lineCount() + _lineLen + if evt.mod==TTkK.NoModifier: + if evt.key == TTkK.Key_Enter: + # self.enterPressed.emit(True) + self._moveCurrentCell( 0,+1) + _processClose(True) + return True + elif evt.key == TTkK.Key_Up: + if _cur.anchor().line == 0: + self._moveCurrentCell( 0,-1) + _processClose(True) + return True + elif evt.key == TTkK.Key_Left: + if _cur.anchor().pos == 0: + self._moveCurrentCell(-1, 0) + _processClose(True) + return True + elif ( evt.type == TTkK.SpecialKey and + evt.mod==TTkK.ControlModifier|TTkK.AltModifier and + evt.key == TTkK.Key_M ): + evt.mod = TTkK.NoModifier + evt.key = TTkK.Key_Enter + return _ke(evt) + _tev.keyEvent = _keyEvent + + # _tev.enterPressed.connect(_processClose) self.focusChanged.connect(_processClose) - _dataEditType = { - str : '', - TTkString : '' - } - def _editNum(self, x,y,w,h, row, col, data): _sb = TTkSpinBox( parent=self, pos=(x, y), size=(w,1), @@ -405,14 +460,10 @@ class TTkTableWidget(TTkAbstractScrollView): self._tableModel.setData(row,col,val) self.update() _sb.close() + self.setFocus() self.focusChanged.connect(_processClose) - _dataEditType = { - str : '', - TTkString : '' - } - def _editTTkString(self, x,y,w,h, row, col, data): _tp = TTkTextPicker( parent=self, pos=(x, y), size=(w,h), @@ -428,13 +479,58 @@ class TTkTableWidget(TTkAbstractScrollView): self._tableModel.setData(row,col,txt) self.update() _tp.close() + self.setFocus() self.focusChanged.connect(_processClose) - _dataEditType = { - str : '', - TTkString : '' - } + def _editCell(self, row, col): + showHS = self._showHSeparators + showVS = self._showVSeparators + rp = self._rowsPos + cp = self._colsPos + xa,xb = 1+cp[col-1] if col>0 else 0, cp[col] + (0 if showVS else 1) + ya,yb = 1+rp[row-1] if row>0 else 0, rp[row] + (0 if showHS else 1) + + data = self._tableModel.data(row, col) + if type(data) is str: + self._editStr(xa,ya,xb-xa,yb-ya,row,col,data) + elif type(data) in [int,float]: + self._editNum(xa,ya,xb-xa,yb-ya,row,col,data) + else: + data = self._tableModel.ttkStringData(row, col) + self._editTTkString(xa,ya,xb-xa,yb-ya,row,col,data) + + def _moveCurrentCell(self, dx, dy): + rows = self._tableModel.rowCount() + cols = self._tableModel.columnCount() + if self._currentPos: + row,col = self._currentPos + row = max(0,min(row+dy, rows-1)) + col = max(0,min(col+dx, cols-1)) + else: + row,col = 0,0 + self._currentPos = (row,col) + self.update() + + def keyEvent(self, evt): + if self._currentPos: + row,col = self._currentPos + else: + row,col = 0,0 + if evt.type == TTkK.SpecialKey: + if evt.mod==TTkK.NoModifier: + if evt.key == TTkK.Key_Up: self._moveCurrentCell( 0,-1) + elif evt.key == TTkK.Key_Down: self._moveCurrentCell( 0, 1) + elif evt.key == TTkK.Key_Left: self._moveCurrentCell(-1, 0) + elif evt.key == TTkK.Key_Right: self._moveCurrentCell( 1, 0) + elif evt.key == TTkK.Key_Enter: self._editCell(row,col) + self.update() + return True + else: + self._tableModel.setData(row,col,evt.key) + self._editCell(row,col) + return True + def mouseDoubleClickEvent(self, evt): x,y = evt.x, evt.y @@ -473,6 +569,8 @@ class TTkTableWidget(TTkAbstractScrollView): return True row,col = self._findCell(x,y, headers=False) + self._editCell(row,col) + return True xa,xb = 1+cp[col-1] if col>0 else 0, cp[col] + (0 if showVS else 1) ya,yb = 1+rp[row-1] if row>0 else 0, rp[row] + (0 if showHS else 1) @@ -587,6 +685,7 @@ class TTkTableWidget(TTkAbstractScrollView): line[col] = not state else: # Cell Select + self._currentPos = (row,col) if _ctrl: self._selected[row][col] = not self._selected[row][col] else: self._selected[row][col] = True self._hoverPos = None @@ -719,6 +818,7 @@ class TTkTableWidget(TTkAbstractScrollView): lineColor:TTkColor= style['lineColor'] headerColor:TTkColor= style['headerColor'] hoverColor:TTkColor= style['hoverColor'] + currentColor:TTkColor= style['currentColor'] selectedColor:TTkColor= style['selectedColor'] separatorColor:TTkColor= style['separatorColor'] @@ -798,6 +898,7 @@ class TTkTableWidget(TTkAbstractScrollView): if xa>w : break if xb