Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TTk Table #272

Merged
merged 59 commits into from
Oct 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
bb6b23e
Added basic definition of TTkAbstractTableModel
ceccopierangiolieugenio Jul 23, 2024
e603376
Added prototype table test
ceccopierangiolieugenio Jul 23, 2024
48135b1
Basic Table Rendering/Actions
ceccopierangiolieugenio Aug 4, 2024
f9ce210
Updated Docs
ceccopierangiolieugenio Aug 4, 2024
af498fc
Started bg color implementation in the table widget
ceccopierangiolieugenio Aug 14, 2024
0860f36
TTkColor, added fgbf helper, alternatecolor modifier
ceccopierangiolieugenio Aug 19, 2024
91b0a57
Added basic selectin api in the table widget
ceccopierangiolieugenio Aug 19, 2024
640988c
Added hover cell
ceccopierangiolieugenio Aug 19, 2024
fed4313
Table: Fixed bg color in the cells
ceccopierangiolieugenio Aug 19, 2024
a4163c0
Table, Tuned selection
ceccopierangiolieugenio Aug 19, 2024
38c9d57
TableWidget, improved parametrization
ceccopierangiolieugenio Aug 24, 2024
b065be6
added drawcell closure
ceccopierangiolieugenio Aug 25, 2024
34fe0c0
TableWidget: Improved the paint caching
ceccopierangiolieugenio Aug 30, 2024
536e76a
TtkTable: reworked paint routine, added header/separator togglers
ceccopierangiolieugenio Sep 3, 2024
45cc1c2
TTkTble, added rows,cols,all selection
ceccopierangiolieugenio Sep 4, 2024
9d4a936
TableWidget: Fix border/boudaries
ceccopierangiolieugenio Sep 4, 2024
8d2f911
TTkTable: Added autoresize on doubleclick and api
ceccopierangiolieugenio Sep 5, 2024
89c3f91
TTkTable: Added resize generic
ceccopierangiolieugenio Sep 5, 2024
1d54180
TTkTable: Added Edit cells
ceccopierangiolieugenio Sep 8, 2024
45517d8
TTkTable Initial key binding
ceccopierangiolieugenio Sep 14, 2024
3a5dd79
Added Basic text keyboard controls
ceccopierangiolieugenio Sep 16, 2024
727a509
TtkTable: Tuned the keyboard input for the num editor
ceccopierangiolieugenio Sep 16, 2024
1d9c505
TTkTable added csv import
ceccopierangiolieugenio Sep 26, 2024
4a380cf
Added Table sort
ceccopierangiolieugenio Sep 27, 2024
0f8f7fb
TableWidget, fix sorting if v separators not shown
ceccopierangiolieugenio Sep 27, 2024
cd4b352
Fix smoke test error
ceccopierangiolieugenio Sep 27, 2024
6f5a29e
Improved TabWidget Documentation, addedtab movement
ceccopierangiolieugenio Sep 28, 2024
6569e05
TTkTable: Scroll to currentPos
ceccopierangiolieugenio Sep 28, 2024
96a7cd0
TTkTable, Added Page Up/Down
ceccopierangiolieugenio Sep 28, 2024
a727049
Fix doc typo
ceccopierangiolieugenio Sep 28, 2024
599d1e8
TTkTable: Removed unused class
ceccopierangiolieugenio Sep 28, 2024
ecc3897
Added TableModels Doc
ceccopierangiolieugenio Sep 29, 2024
663e234
TTkTable: Improved documentation
ceccopierangiolieugenio Sep 30, 2024
a64caec
Improved Docs
ceccopierangiolieugenio Oct 1, 2024
dd3e612
Merge branch 'main' into TTkTable
ceccopierangiolieugenio Oct 1, 2024
2ad6caf
constant.py
ceccopierangiolieugenio Oct 1, 2024
ad54e6a
TTkTable: Added undo/redo
ceccopierangiolieugenio Oct 2, 2024
44a7886
Merge remote-tracking branch 'origin/main' into TTkTable
ceccopierangiolieugenio Oct 7, 2024
27c03df
Added Table Copy
ceccopierangiolieugenio Oct 7, 2024
672e9eb
TTkTable: clean cells if del or backspace is pressed
ceccopierangiolieugenio Oct 7, 2024
c74cb1c
TTkTable: Added Cut and fixed cursor movement
ceccopierangiolieugenio Oct 7, 2024
fb80991
TTkTable: Save cursor position in the snapshot
ceccopierangiolieugenio Oct 8, 2024
75658e5
TTkTable: Added Paste Event
ceccopierangiolieugenio Oct 8, 2024
eb92cf7
Fix Test Error
ceccopierangiolieugenio Oct 8, 2024
bb15f83
imrpoved doc
ceccopierangiolieugenio Oct 8, 2024
46846d0
Added TableModelIndex, clipboard use the index to store the cells
ceccopierangiolieugenio Oct 8, 2024
50992d3
TTkTable: added per cell item selection flags
ceccopierangiolieugenio Oct 14, 2024
34dd9e1
TTkTable: added per cell item editable flags
ceccopierangiolieugenio Oct 14, 2024
b97b5c0
TTkTable: Refined the behavior when enter is pressed if cell is not e…
ceccopierangiolieugenio Oct 14, 2024
b37af10
Added table signals
ceccopierangiolieugenio Oct 14, 2024
3aa5a4c
allow textDocument to import non string values
ceccopierangiolieugenio Oct 14, 2024
d5a58a7
Added recording test 003
ceccopierangiolieugenio Oct 15, 2024
af57bc2
TTkTable: Added the examples explaining the basic usage and the custo…
ceccopierangiolieugenio Oct 19, 2024
c6ca329
Added few TTkTable examples
ceccopierangiolieugenio Oct 20, 2024
e67007e
Improved the theming api
ceccopierangiolieugenio Oct 20, 2024
b068303
Added Table examples
ceccopierangiolieugenio Oct 20, 2024
65e0a6e
TTkTable: added undo/redo available
ceccopierangiolieugenio Oct 20, 2024
137efa4
improved Table doc
ceccopierangiolieugenio Oct 20, 2024
3b9c55d
#275 - TTkTree: Exposed sort methods
ceccopierangiolieugenio Oct 20, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/workflows/testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ jobs:
mkdir -p tmp
wget -O tmp/test.input.001.bin https://github.com/ceccopierangiolieugenio/binaryRepo/raw/master/pyTermTk/tests/test.input.001.bin
wget -O tmp/test.input.002.bin https://github.com/ceccopierangiolieugenio/binaryRepo/raw/master/pyTermTk/tests/test.input.002.bin
wget -O tmp/test.input.003.bin https://github.com/ceccopierangiolieugenio/binaryRepo/raw/master/pyTermTk/tests/test.input.003.bin
pytest ${DDDD}/tests/pytest/test_003_string.py
pytest ${DDDD}/tests/pytest/test_002_textedit.py
pytest ${DDDD}/tests/pytest/test_001_demo.py
12 changes: 8 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -134,10 +134,14 @@ test: .venv
mkdir -p tmp
wget -O tmp/test.input.001.bin https://github.com/ceccopierangiolieugenio/binaryRepo/raw/master/pyTermTk/tests/test.input.001.bin
wget -O tmp/test.input.002.bin https://github.com/ceccopierangiolieugenio/binaryRepo/raw/master/pyTermTk/tests/test.input.002.bin
wget -O tmp/test.input.003.bin https://github.com/ceccopierangiolieugenio/binaryRepo/raw/master/pyTermTk/tests/test.input.003.bin
tools/check.import.sh
. .venv/bin/activate ; \
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics --exclude .venv,build,tmp ; \
pytest tests/pytest/test_003_string.py ; \
pytest tests/pytest/test_002_textedit.py ; \
pytest -v tests/pytest/test_001_demo.py ;
flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics --exclude .venv,build,tmp,experiments ;
. .venv/bin/activate ; \
pytest tests/pytest/test_003_string.py ;
. .venv/bin/activate ; \
pytest tests/pytest/test_002_textedit.py ;
. .venv/bin/activate ; \
pytest -v tests/pytest/test_001_demo.py ;

1 change: 1 addition & 0 deletions TermTk/TTkAbstract/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
from .abstractscrollview import *
from .abstractscrollarea import *
from .abstractitemmodel import *
from .abstracttablemodel import *
278 changes: 278 additions & 0 deletions TermTk/TTkAbstract/abstracttablemodel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
# MIT License
#
# Copyright (c) 2024 Eugenio Parodi <ceccopierangiolieugenio AT googlemail DOT com>
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.

__all__ = ['TTkAbstractTableModel','TTkModelIndex']

from TermTk.TTkCore.constant import TTkK
from TermTk.TTkCore.string import TTkString
from TermTk.TTkCore.signal import pyTTkSignal, pyTTkSlot

class TTkModelIndex():
'''
This class is used as an index into item models derived from :class:`~TermTk.TTkAbstract.abstracttablemodel.TTkAbstractTableModel`.
The index is used by item views, delegates, and selection models to locate an item in the model.

New :class:`~TermTk.TTkAbstract.abstracttablemodel.TTkModelIndex` objects are created by the model using the :class:`~TermTk.TTkAbstract.abstracttablemodel.TTkAbstractTableModel` -> :meth:`~TermTk.TTkAbstract.abstracttablemodel.TTkAbstractTableModel.index` function.
An invalid model index can be constructed with the :class:`~TermTk.TTkAbstract.abstracttablemodel.TTkModelIndex` constructor.

Model indexes refer to items in models, and contain all the information required to specify their locations in those models.
Each index is located in a given row and column; use :meth:`row`, :meth:`column`, and :meth:`data` to obtain this information.

To obtain a model index that refers to an existing item in a model, call :class:`~TermTk.TTkAbstract.abstracttablemodel.TTkAbstractTableModel` -> :meth:`~TermTk.TTkAbstract.abstracttablemodel.TTkAbstractTableModel.index` with the required row and column values.
'''
def __init__(self) -> None:
pass

def row(self) -> int:
'''
Returns the row this model index refers to.

:return: int
'''
pass

def col(self) -> int:
'''
Returns the column this model index refers to.

:return: int
'''
pass

def data(self) -> object:
'''
Returns the data for the item referred to by the index.

:return: object
'''
pass

def setData(self, data:object) -> None:
'''
Set the data in the item referred by the current index.

:param data: the data to be set in the (row,col) position of the table
:type data: object
'''
pass

class _TTkModelIndexList(TTkModelIndex):
__slots__ = ('_col','_row','_model')
def __init__(self, row:int, col:list, model) -> None:
self._col = col
self._row = row
self._model = model
super().__init__()

def row(self) -> int:
return self._row

def col(self) -> int:
return self._col

def data(self) -> object:
return self._model.data(self._row,self._col)

def setData(self, data: object) -> None:
self._model.setData(self._row,self._col,data)

class TTkAbstractTableModel():
'''
:class:`TTkAbstractTableModel` provides a standard interface for
models that represent their data as a two-dimensional array of items.
It is not used directly, but must be subclassed.

Since the model provides a more specialized interface than :class:`~TermTk.TTkAbstract.abstractitemmodel.TTkAbstractItemModel`,
it is not suitable for use with tree views.

The :meth:`rowCount` and :meth:`columnCount` functions return the dimensions of the table.

**Subclassing**

When subclassing :class:`TTkAbstractTableModel`, you must implement :meth:`rowCount`, :meth:`columnCount`, and :meth:`data`.
Well behaved models will also implement :meth:`headerData`.

Editable models need to implement :meth:`setData`.

**Built-In Implementation**

:class:`~TermTk.TTkWidgets.TTkModelView.tablemodellist.TTkTableModelList` basic subclass implementing a 2d list as data structure

:class:`~TermTk.TTkWidgets.TTkModelView.tablemodelcsv.TTkTableModelCSV` subclass of :class:`~TermTk.TTkWidgets.TTkModelView.tablemodellist.TTkTableModelList` including the api to import csv data

+-----------------------------------------------------------------------------------------------+
| `Signals <https://ceccopierangiolieugenio.github.io/pyTermTk/tutorial/003-signalslots.html>`_ |
+-----------------------------------------------------------------------------------------------+

.. py:method:: dataChanged(pos,size)
:signal:

This signal is emitted whenever the data in an existing item changes.

If more items are affected, the pos/size definne the minimum area including all of those changes.

When reimplementing the :meth:`setData` function, this signal must be emitted explicitly.

:param pos: the topLeft margin of the modified area
:type pos: tuple(int,int)

:param size: the size of the modified area
:type size: tuple(int,int)
'''
__slots__ = (
# Signals
'dataChanged'
)
def __init__(self):
self.dataChanged = pyTTkSignal(tuple[int,int],tuple[int,int])

def rowCount(self) -> int:
'''
Returns the number of rows of the current model.

:return: int
'''
raise NotImplementedError()

def columnCount(self) -> int:
'''
Returns the number of columns of the current moodel.

:return: int
'''
raise NotImplementedError()

def index(self, row:int, col:int) -> TTkModelIndex:
'''
Returns the index of the item in the model specified by the given row, column.

:param row: the row position of the index
:type row: int
:param col: the column position of the index
:type col: int

:return: :class:`~TermTk.TTkAbstract.abstracttablemodel.TTkModelIndex`
'''
return _TTkModelIndexList(row,col,self)

def data(self, row:int, col:int) -> object:
'''
Returns the data stored for the item referred to by the row/column.

Note: If you do not have a value to return, return *None* instead of returning 0.

:param row: the row position of the data
:type row: int
:param col: the column position of the data
:type col: int

:return: object
'''
raise NotImplementedError()

def setData(self, row:int, col:int, data:object) -> bool:
'''
Returns true if successful; otherwise returns false.

The :meth:`~TermTk.TTkAbstract.abstracttablemodel.TTkAbstractTableModel.dataChanged` signal should be emitted if the data was successfully set.

The base class implementation returns false. This function and :meth:`data` must be reimplemented for editable models.

:param row: the row position of the data
:type row: int
:param col: the column position of the data
:type col: int
:param data: the data to be set in the (row,col) position of the table
:type data: object

:return: bool
'''
return False

def ttkStringData(self, row:int, col:int) -> TTkString:
'''
Returns the :class:`~TermTk.TTkCore.string.TTkString` reprsents the ddata stored in the row/column.

:param row: the row position of the data
:type row: int
:param col: the column position of the data
:type col: int

:return: :class:`~TermTk.TTkCore.string.TTkString`
'''
data = self.data(row,col)
if isinstance(data,TTkString):
return data
elif type(data) == str:
return TTkString(data)
else:
return TTkString(str(data))

def headerData(self, pos:int, orientation:TTkK.Direction) -> TTkString:
'''
Returns the data for the given role and section in the header with the specified orientation.

For horizontal headers, the section number corresponds to the column number.
Similarly, for vertical headers, the section number corresponds to the row number.

:param pos: the position (col or row) of the header
:type pos: int
:param orientation: the orienttin of the header to be retrieved
:type orientation: :class:`~TermTk.TTkCore.constant.TTkConstant.Direction`

:return: :class:`~TermTk.TTkCore.string.TTkString`
'''
if orientation==TTkK.HORIZONTAL:
return TTkString(str(pos))
elif orientation==TTkK.VERTICAL:
return TTkString(str(pos))
return TTkString()

def flags(self, row:int, col:int) -> TTkK.ItemFlag:
'''
Returns the item flags for the given row,column.

The base class implementation returns a combination of flags that
enables the item (:class:`~TermTk.TTkCore.constant.TTkConstant.ItemFlag.ItemIsEnabled`)
and allows it to be selected (:class:`~TermTk.TTkCore.constant.TTkConstant.ItemFlag.ItemIsSelectable`).

:param row: the row position od the data
:type row: int
:param col: the column position of the data
:type col: int

:return: :class:`~TermTk.TTkCore.constant.TTkConstant.ItemFlag`
'''
return (
TTkK.ItemFlag.ItemIsEnabled |
TTkK.ItemFlag.ItemIsSelectable )

def sort(self, column:int, order:TTkK.SortOrder) -> None:
'''
Sorts the model by column in the given order.

:param column: The column index to be sorted, if -1 is provided the original unsorted order is used.
:type column: int
:param order: the sorting order
:type order: :class:`~TermTk.TTkCore.constant.TTkConstant.SortOrder`
'''
pass
Loading
Loading