1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
|
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtCore import Qt
from typing import List
import time
import math
from todo.model.tag import Tag
import todo.util.array
import todo.util.range
columns = 1
headers = ["Name", "Color"]
default_sort = (0, Qt.AscendingOrder)
class TableModel(QtCore.QAbstractTableModel):
def __init__(self, tags):
super(TableModel, self).__init__()
self._tags = tags
def headerData(self, section, orientation, role):
if role == Qt.DisplayRole and orientation == Qt.Horizontal:
return headers[section]
elif role == Qt.DisplayRole and orientation == Qt.Vertical:
return section + 1
else:
return QtCore.QVariant()
def data(self, index, role):
tag = self._tags[index.row()]
if role == Qt.DisplayRole:
if index.column() == 0:
return tag.name
elif index.column() == 1:
return tag.color
elif role == Qt.BackgroundRole:
return QtGui.QBrush(QtGui.QColor(tag.color))
else:
return QtCore.QVariant()
def rowCount(self, index):
return len(self._tags)
def columnCount(self, index):
return columns
def get_at(self, row):
if row >= 0 and row < len(self._tags):
return self._tags[row]
def insert_tag(self, header: QtWidgets.QHeaderView, tag: Tag) -> int:
at = self.insert_position(header, tag)
self.beginInsertRows(QtCore.QModelIndex(), at, at)
self._tags.insert(at, tag)
self.endInsertRows()
return at
def insert_position(self, header: QtWidgets.QHeaderView, tag: Tag) -> int:
row = header.sortIndicatorSection()
order = header.sortIndicatorOrder()
is_rev = is_reversed(row, order)
return todo.util.array.insert_position(
sort_key(tag, row, is_rev),
[sort_key(t, row, is_rev) for t in self._tags],
is_rev)
def update_tag(self, header: QtWidgets.QHeaderView, row, tag: Tag) -> int:
self.delete_tag_range(row, 1)
return self.insert_tag(header, tag)
def delete_tags(self, indexes):
for range in reversed(todo.util.range.from_indexes(indexes)):
self.delete_tag_range(range.start, range.length)
return True
def delete_tag_range(self, row, rows):
self.beginRemoveRows(QtCore.QModelIndex(), row, row + rows - 1)
self._tags = self._tags[:row] + self._tags[row + rows:]
self.endRemoveRows()
return True
def row_ids(self, rows):
return [tag.id for i, tag in enumerate(self._tags) if i in rows]
def sort(self, row: int, order: Qt.SortOrder):
self.layoutAboutToBeChanged.emit()
is_rev = is_reversed(row, order)
self._tags = sorted(
self._tags,
key = lambda tag: sort_key(tag, row, is_rev),
reverse = is_rev)
self.layoutChanged.emit()
def sort_key(tag: Tag, row: int, is_reversed: bool):
if row == 0:
return tag.name.lower()
elif row == 1:
return tag.color
def is_reversed(row: int, order: Qt.SortOrder) -> bool:
return order == Qt.DescendingOrder
|