aboutsummaryrefslogtreecommitdiff
path: root/src/gui/tags/panel/table/model.py
blob: 7c66b5d52d4361d762882e2d647d0f24737c1d1a (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 model.tag import Tag
import time
import math
import util.array
import util.range
import gui.color

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 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(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