Developer documentation
Version 3.0.3-105-gd3941f44
list_model_base.h
Go to the documentation of this file.
1/* Copyright (c) 2008-2022 the MRtrix3 contributors.
2 *
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 *
7 * Covered Software is provided under this License on an "as is"
8 * basis, without warranty of any kind, either expressed, implied, or
9 * statutory, including, without limitation, warranties that the
10 * Covered Software is free of defects, merchantable, fit for a
11 * particular purpose or non-infringing.
12 * See the Mozilla Public License v. 2.0 for more details.
13 *
14 * For more details, see http://www.mrtrix.org/.
15 */
16
17#ifndef __gui_mrview_tool_list_model_base_h__
18#define __gui_mrview_tool_list_model_base_h__
19
21
22namespace MR
23{
24 namespace GUI
25 {
26 namespace MRView
27 {
28 namespace Tool
29 {
30
31 class ListModelBase : public QAbstractItemModel
33 public:
34
35 ListModelBase (QObject* parent) :
36 QAbstractItemModel (parent) { }
37
38 QVariant data (const QModelIndex& index, int role) const override {
39 // The item may (temporarily) be null during an intermediate step of reordering items
40 // see insertRows / removeRows
41 if (!index.isValid()) return QVariant();
42 if (role == Qt::CheckStateRole) {
43 return items[index.row()] && items[index.row()]->show ? Qt::Checked : Qt::Unchecked;
44 }
45 if (role != Qt::DisplayRole && role != Qt::ToolTipRole) return QVariant();
46 return items[index.row()] ? qstr (items[index.row()]->get_filename()) : QString();
47 }
48
49 bool setData (const QModelIndex& idx, const QVariant& value, int role) override {
50 if (role == Qt::CheckStateRole) {
51 Qt::KeyboardModifiers keyMod = QApplication::keyboardModifiers ();
52 if (keyMod.testFlag (Qt::ShiftModifier)) {
53 for (int i = 0; i < (int)items.size(); ++i) {
54 if (i == idx.row())
55 items[i]->show = true;
56 else
57 items[i]->show = false;
58 }
59 emit dataChanged (index(0, 0), index(items.size(), 0));
60 } else {
61 items[idx.row()]->show = (value == Qt::Checked);
62 emit dataChanged (idx, idx);
63 }
64 return true;
65 }
66 return QAbstractItemModel::setData (idx, value, role);
67 }
68
69 Qt::DropActions supportedDropActions () const override
70 {
71 return Qt::CopyAction | Qt::MoveAction;
72 }
73
74 // For some reason, Qt calls insertRows prior to removeRows in the event of a drag-n-drop
75 // item reordering within a given model.
76 // Hence at this point, we simply want to cache where the rows should be moved
77 bool insertRows(int row, int count, const QModelIndex &) override {
78 if (count < 1 || row < 0 || row > rowCount ()) {
79 swapped_rows = { 0, 0 };
80 return false;
81 }
82
83 swapped_rows = { row, count };
84
85 return true;
86 }
87
88 // As alluded above in insertRows, in the case of a drag-n-drop item reordering,
89 // we have to manually perform the swap within our underlying data store
90 bool removeRows (int row, int count, const QModelIndex& parent = QModelIndex()) override {
91 if (count < 1 || row < 0 || row > rowCount () || count != swapped_rows.second)
92 return false;
93
95
96 swapped_items.insert ( swapped_items.begin(),
97 std::make_move_iterator (items.begin() + row),
98 std::make_move_iterator (items.begin() + row + count));
99
100 beginRemoveRows (parent, row, row + count - 1);
101 items.erase (items.begin() + row, items.begin() + row + count);
102 endRemoveRows ();
103
104 // Cached row index was prior to removal, so may need to adjust offset
105 if (swapped_rows.first >= row)
106 swapped_rows.first -= count;
107
108 beginInsertRows (parent, swapped_rows.first, swapped_rows.first + swapped_rows.second - 1);
109 items.insert (items.begin() + swapped_rows.first,
110 std::make_move_iterator (swapped_items.begin ()),
111 std::make_move_iterator (swapped_items.end ()));
112 endInsertRows ();
113
114 return true;
115 }
116
117 Qt::ItemFlags flags (const QModelIndex& index) const override {
118
119 static const auto valid_flags = Qt::ItemIsDragEnabled | Qt::ItemIsEnabled |
120 Qt::ItemIsSelectable | Qt::ItemIsUserCheckable;
121 static const auto invalid_flags = valid_flags | Qt::ItemIsDropEnabled;
122
123 if (!index.isValid()) return invalid_flags;
124 return valid_flags;
125 }
126
127 QModelIndex index (int row, int column, const QModelIndex& parent = QModelIndex()) const override {
128 (void) parent; // to suppress warnings about unused parameters
129 return createIndex (row, column);
130 }
131
132 QModelIndex parent (const QModelIndex&) const override { return QModelIndex(); }
133
134 int rowCount (const QModelIndex& parent = QModelIndex()) const override {
135 (void) parent; // to suppress warnings about unused parameters
136 return items.size();
137 }
138
139 int columnCount (const QModelIndex& parent = QModelIndex()) const override {
140 (void) parent; // to suppress warnings about unused parameters
141 return 1;
142 }
143
144 void remove_item (QModelIndex& index) {
145 beginRemoveRows (QModelIndex(), index.row(), index.row());
146 items.erase (items.begin() + index.row());
147 endRemoveRows();
148 }
149
151 private:
152 std::pair<int, int> swapped_rows;
153 };
154
155
156 }
157 }
158 }
159}
160
161#endif
162
163
164
165
Qt::DropActions supportedDropActions() const override
int rowCount(const QModelIndex &parent=QModelIndex()) const override
QModelIndex parent(const QModelIndex &) const override
vector< std::unique_ptr< Displayable > > items
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const override
int columnCount(const QModelIndex &parent=QModelIndex()) const override
QVariant data(const QModelIndex &index, int role) const override
void remove_item(QModelIndex &index)
bool insertRows(int row, int count, const QModelIndex &) override
bool removeRows(int row, int count, const QModelIndex &parent=QModelIndex()) override
Qt::ItemFlags flags(const QModelIndex &index) const override
bool setData(const QModelIndex &idx, const QVariant &value, int role) override
VectorType::Scalar value(const VectorType &coefs, typename VectorType::Scalar cos_elevation, typename VectorType::Scalar cos_azimuth, typename VectorType::Scalar sin_azimuth, int lmax)
Definition: SH.h:233
#define NOMEMALIGN
Definition: memory.h:22
QString qstr(const std::string &s)
Definition: gui.h:31
Definition: base.h:24