1 | /* |
2 | SPDX-FileCopyrightText: 2019 Arjen Hiemstra <ahiemstra@heimr.nl> |
3 | |
4 | SPDX-License-Identifier: LGPL-2.0-or-later |
5 | */ |
6 | |
7 | #include "kcolumnheadersmodel.h" |
8 | |
9 | class KColumnHeadersModelPrivate |
10 | { |
11 | public: |
12 | QAbstractItemModel *sourceModel = nullptr; |
13 | int sortColumn = -1; |
14 | Qt::SortOrder sortOrder = Qt::AscendingOrder; |
15 | }; |
16 | |
17 | KColumnHeadersModel::KColumnHeadersModel(QObject *parent) |
18 | : QAbstractListModel(parent) |
19 | , d(new KColumnHeadersModelPrivate) |
20 | { |
21 | } |
22 | |
23 | KColumnHeadersModel::~KColumnHeadersModel() |
24 | { |
25 | } |
26 | |
27 | int KColumnHeadersModel::rowCount(const QModelIndex &parent) const |
28 | { |
29 | if (!d->sourceModel || parent.isValid()) { |
30 | return 0; |
31 | } |
32 | |
33 | return d->sourceModel->columnCount(); |
34 | } |
35 | |
36 | QVariant KColumnHeadersModel::data(const QModelIndex &index, int role) const |
37 | { |
38 | if (!d->sourceModel || !index.isValid()) { |
39 | return QVariant{}; |
40 | } |
41 | |
42 | if (role == SortRole) { |
43 | if (index.row() == d->sortColumn) { |
44 | return d->sortOrder; |
45 | } else { |
46 | return QVariant{}; |
47 | } |
48 | } |
49 | |
50 | return sourceModel()->headerData(section: index.row(), orientation: Qt::Horizontal, role); |
51 | } |
52 | |
53 | QHash<int, QByteArray> KColumnHeadersModel::roleNames() const |
54 | { |
55 | if (!d->sourceModel) { |
56 | return QHash<int, QByteArray>{}; |
57 | } |
58 | |
59 | auto names = d->sourceModel->roleNames(); |
60 | names.insert(key: SortRole, value: "sort" ); |
61 | return names; |
62 | } |
63 | |
64 | QAbstractItemModel *KColumnHeadersModel::sourceModel() const |
65 | { |
66 | return d->sourceModel; |
67 | } |
68 | |
69 | void KColumnHeadersModel::setSourceModel(QAbstractItemModel *newSourceModel) |
70 | { |
71 | if (newSourceModel == d->sourceModel) { |
72 | return; |
73 | } |
74 | |
75 | if (d->sourceModel) { |
76 | d->sourceModel->disconnect(receiver: this); |
77 | } |
78 | |
79 | beginResetModel(); |
80 | d->sourceModel = newSourceModel; |
81 | endResetModel(); |
82 | |
83 | if (newSourceModel) { |
84 | connect(sender: newSourceModel, signal: &QAbstractItemModel::columnsAboutToBeInserted, context: this, slot: [this](const QModelIndex &, int first, int last) { |
85 | beginInsertRows(parent: QModelIndex{}, first, last); |
86 | }); |
87 | connect(sender: newSourceModel, signal: &QAbstractItemModel::columnsInserted, context: this, slot: [this]() { |
88 | endInsertRows(); |
89 | }); |
90 | connect(sender: newSourceModel, |
91 | signal: &QAbstractItemModel::columnsAboutToBeMoved, |
92 | context: this, |
93 | slot: [this](const QModelIndex &, int start, int end, const QModelIndex &, int destination) { |
94 | beginMoveRows(sourceParent: QModelIndex{}, sourceFirst: start, sourceLast: end, destinationParent: QModelIndex{}, destinationRow: destination); |
95 | }); |
96 | connect(sender: newSourceModel, signal: &QAbstractItemModel::columnsMoved, context: this, slot: [this]() { |
97 | endMoveRows(); |
98 | }); |
99 | connect(sender: newSourceModel, signal: &QAbstractItemModel::columnsAboutToBeRemoved, context: this, slot: [this](const QModelIndex &, int first, int last) { |
100 | beginRemoveRows(parent: QModelIndex{}, first, last); |
101 | }); |
102 | connect(sender: newSourceModel, signal: &QAbstractItemModel::columnsRemoved, context: this, slot: [this]() { |
103 | endRemoveRows(); |
104 | }); |
105 | connect(sender: newSourceModel, signal: &QAbstractItemModel::headerDataChanged, context: this, slot: [this](Qt::Orientation orientation, int first, int last) { |
106 | if (orientation == Qt::Horizontal) { |
107 | Q_EMIT dataChanged(topLeft: index(row: first, column: 0), bottomRight: index(row: last, column: 0)); |
108 | } |
109 | }); |
110 | connect(sender: newSourceModel, signal: &QAbstractItemModel::modelAboutToBeReset, context: this, slot: [this]() { |
111 | beginResetModel(); |
112 | }); |
113 | connect(sender: newSourceModel, signal: &QAbstractItemModel::modelReset, context: this, slot: [this]() { |
114 | endResetModel(); |
115 | }); |
116 | } |
117 | } |
118 | |
119 | int KColumnHeadersModel::sortColumn() const |
120 | { |
121 | return d->sortColumn; |
122 | } |
123 | |
124 | void KColumnHeadersModel::setSortColumn(int newSortColumn) |
125 | { |
126 | if (newSortColumn == d->sortColumn) { |
127 | return; |
128 | } |
129 | |
130 | auto previousSortColumn = d->sortColumn; |
131 | |
132 | d->sortColumn = newSortColumn; |
133 | |
134 | if (previousSortColumn >= 0) { |
135 | Q_EMIT dataChanged(topLeft: index(row: previousSortColumn), bottomRight: index(row: previousSortColumn), roles: {SortRole}); |
136 | } |
137 | |
138 | if (newSortColumn >= 0) { |
139 | Q_EMIT dataChanged(topLeft: index(row: newSortColumn), bottomRight: index(row: newSortColumn), roles: {SortRole}); |
140 | } |
141 | |
142 | Q_EMIT sortColumnChanged(); |
143 | } |
144 | |
145 | Qt::SortOrder KColumnHeadersModel::sortOrder() const |
146 | { |
147 | return d->sortOrder; |
148 | } |
149 | |
150 | void KColumnHeadersModel::setSortOrder(Qt::SortOrder newSortOrder) |
151 | { |
152 | if (newSortOrder == d->sortOrder) { |
153 | return; |
154 | } |
155 | |
156 | d->sortOrder = newSortOrder; |
157 | |
158 | if (d->sortColumn >= 0) { |
159 | Q_EMIT dataChanged(topLeft: index(row: d->sortColumn), bottomRight: index(row: d->sortColumn), roles: {SortRole}); |
160 | } |
161 | |
162 | Q_EMIT sortOrderChanged(); |
163 | } |
164 | |
165 | #include "moc_kcolumnheadersmodel.cpp" |
166 | |