aboutsummaryrefslogtreecommitdiff
path: root/todo/gui/tags/panel/table/model.py
blob: 0112b031392b28a31d22cda2b9d0fac349acb469 (plain)
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 = ["Nom", "Couleur"]

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