Qt Utilities  6.0.2
Common Qt related C++ classes and routines used by my applications such as dialogs, widgets and models
checklistmodel.cpp
Go to the documentation of this file.
1 #include "./checklistmodel.h"
2 
3 #include <QSettings>
4 
10 namespace QtUtilities {
11 
28  : QAbstractListModel(parent)
29 {
30 }
31 
32 int ChecklistModel::rowCount(const QModelIndex &parent) const
33 {
34  if (!parent.isValid()) {
35  return m_items.size();
36  }
37  return 0;
38 }
39 
40 Qt::ItemFlags ChecklistModel::flags(const QModelIndex &index) const
41 {
42  if (!index.isValid() || index.row() >= m_items.count() || index.model() != this) {
43  return Qt::ItemIsDropEnabled; // allows drops outside the items
44  }
45  return QAbstractListModel::flags(index) | Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled;
46 }
47 
48 QVariant ChecklistModel::data(const QModelIndex &index, int role) const
49 {
50  if (index.isValid() && index.row() < m_items.size()) {
51  switch (role) {
52  case Qt::DisplayRole:
53  return m_items.at(index.row()).label();
54  case Qt::CheckStateRole:
55  return m_items.at(index.row()).checkState();
56  case idRole():
57  return m_items.at(index.row()).id();
58  default:;
59  }
60  }
61  return QVariant();
62 }
63 
64 QMap<int, QVariant> ChecklistModel::itemData(const QModelIndex &index) const
65 {
66  QMap<int, QVariant> roles;
67  roles.insert(Qt::DisplayRole, data(index, Qt::DisplayRole));
68  roles.insert(Qt::CheckStateRole, data(index, Qt::CheckStateRole));
69  roles.insert(idRole(), data(index, idRole()));
70  return roles;
71 }
72 
73 bool ChecklistModel::setData(const QModelIndex &index, const QVariant &value, int role)
74 {
75  bool success = false;
76  QVector<int> roles{ role };
77  if (index.isValid() && index.row() < m_items.size()) {
78  switch (role) {
79  case Qt::DisplayRole:
80  m_items[index.row()].m_label = value.toString();
81  success = true;
82  break;
83  case Qt::CheckStateRole:
84  if (value.canConvert(QMetaType::Int)) {
85  m_items[index.row()].m_checkState = static_cast<Qt::CheckState>(value.toInt());
86  success = true;
87  }
88  break;
89  case idRole(): {
90  m_items[index.row()].m_id = value;
91  success = true;
92  auto label = labelForId(value);
93  if (!label.isEmpty()) {
94  m_items[index.row()].m_label = std::move(label);
95  roles << Qt::DisplayRole;
96  }
97  break;
98  }
99  default:;
100  }
101  }
102  if (success) {
103  dataChanged(index, index, roles);
104  }
105  return success;
106 }
107 
108 bool ChecklistModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles)
109 {
110  for (QMap<int, QVariant>::ConstIterator it = roles.constBegin(); it != roles.constEnd(); ++it) {
111  setData(index, it.value(), it.key());
112  }
113  return true;
114 }
115 
119 bool ChecklistModel::setChecked(int row, Qt::CheckState checked)
120 {
121  if (row < 0 || row >= m_items.size()) {
122  return false;
123  }
124  m_items[row].m_checkState = checked ? Qt::Checked : Qt::Unchecked;
125  const auto index(this->index(row));
126  dataChanged(index, index, QVector<int>{ Qt::CheckStateRole });
127  return true;
128 }
129 
143 QString ChecklistModel::labelForId(const QVariant &) const
144 {
145  return QString();
146 }
147 
149 {
150  return Qt::MoveAction;
151 }
152 
153 bool ChecklistModel::insertRows(int row, int count, const QModelIndex &parent)
154 {
155  if (count < 1 || row < 0 || row > rowCount() || parent.isValid()) {
156  return false;
157  }
158  beginInsertRows(QModelIndex(), row, row + count - 1);
159  for (int index = row, end = row + count; index < end; ++index) {
160  m_items.insert(index, ChecklistItem());
161  }
162  endInsertRows();
163  return true;
164 }
165 
166 bool ChecklistModel::removeRows(int row, int count, const QModelIndex &parent)
167 {
168  if (count < 1 || row < 0 || (row + count) > rowCount() || parent.isValid()) {
169  return false;
170  }
171  beginRemoveRows(QModelIndex(), row, row + count - 1);
172  for (int index = row, end = row + count; index < end; ++index) {
173  m_items.removeAt(index);
174  }
175  endRemoveRows();
176  return true;
177 }
178 
182 void ChecklistModel::setItems(const QList<ChecklistItem> &items)
183 {
184  beginResetModel();
185  m_items = items;
186  for (auto &item : m_items) {
187  if (item.m_label.isEmpty()) {
188  item.m_label = labelForId(item.id());
189  }
190  }
191  endResetModel();
192 }
193 
204 void ChecklistModel::restore(QSettings &settings, const QString &name)
205 {
206  beginResetModel();
207  auto currentItems = m_items;
208  QList<QVariant> restoredIds;
209  m_items.clear();
210  int rows = settings.beginReadArray(name);
211  m_items.reserve(rows);
212  for (int i = 0; i < rows; ++i) {
213  settings.setArrayIndex(i);
214  QVariant id = settings.value(QStringLiteral("id"));
215  QVariant selected = settings.value(QStringLiteral("selected"));
216  if (!id.isNull() && !selected.isNull() && selected.canConvert(QMetaType::Bool) && !restoredIds.contains(id)) {
217  m_items << ChecklistItem(id, labelForId(id), selected.toBool() ? Qt::Checked : Qt::Unchecked);
218  restoredIds << id;
219  }
220  }
221  settings.endArray();
222  for (const ChecklistItem &item : currentItems) {
223  if (!restoredIds.contains(item.id())) {
224  m_items << item;
225  }
226  }
227  endResetModel();
228 }
229 
237 void ChecklistModel::save(QSettings &settings, const QString &name) const
238 {
239  settings.beginWriteArray(name, m_items.size());
240  int index = 0;
241  for (const ChecklistItem &item : m_items) {
242  settings.setArrayIndex(index);
243  settings.setValue(QStringLiteral("id"), item.id());
244  settings.setValue(QStringLiteral("selected"), item.isChecked());
245  ++index;
246  }
247  settings.endArray();
248 }
249 
253 QVariantList ChecklistModel::toVariantList() const
254 {
255  QVariantList checkedIds;
256  checkedIds.reserve(m_items.size());
257  for (const auto &item : m_items) {
258  if (item.isChecked()) {
259  checkedIds << item.id();
260  }
261  }
262  return checkedIds;
263 }
264 
268 void ChecklistModel::applyVariantList(const QVariantList &checkedIds)
269 {
270  for (auto &item : m_items) {
271  item.m_checkState = checkedIds.contains(item.id()) ? Qt::Checked : Qt::Unchecked;
272  }
273  emit dataChanged(index(0), index(m_items.size()), { Qt::CheckStateRole });
274 }
275 
276 } // namespace QtUtilities
QtUtilities::ChecklistModel::flags
Qt::ItemFlags flags(const QModelIndex &index) const override
Definition: checklistmodel.cpp:40
QtUtilities::ChecklistModel::save
void save(QSettings &settings, const QString &name) const
Saves the IDs and checkstates to the specified settings object.
Definition: checklistmodel.cpp:237
QtUtilities::ChecklistModel::rowCount
int rowCount(const QModelIndex &parent=QModelIndex()) const override
Definition: checklistmodel.cpp:32
QtUtilities::ChecklistModel::supportedDropActions
Qt::DropActions supportedDropActions() const override
Definition: checklistmodel.cpp:148
checklistmodel.h
QtUtilities::ChecklistModel::setChecked
bool setChecked(int row, bool checked)
Sets the checked state of the specified item.
Definition: checklistmodel.h:112
QtUtilities::ChecklistModel::ChecklistModel
ChecklistModel(QObject *parent=nullptr)
Constructs a new checklist model.
Definition: checklistmodel.cpp:27
QtUtilities::ChecklistModel::insertRows
bool insertRows(int row, int count, const QModelIndex &parent) override
Definition: checklistmodel.cpp:153
QtUtilities::ChecklistModel::idRole
static constexpr int idRole()
Returns the role used to get or set the item ID.
Definition: checklistmodel.h:120
QtUtilities::ChecklistModel::itemData
QMap< int, QVariant > itemData(const QModelIndex &index) const override
Definition: checklistmodel.cpp:64
QtUtilities::ChecklistModel::setData
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::DisplayRole) override
Definition: checklistmodel.cpp:73
QtUtilities
!
Definition: trylocker.h:8
QtUtilities::ChecklistModel::labelForId
virtual QString labelForId(const QVariant &id) const
Returns the label for the specified id.
Definition: checklistmodel.cpp:143
QtUtilities::ChecklistItem
Definition: checklistmodel.h:15
QtUtilities::ChecklistModel::applyVariantList
void applyVariantList(const QVariantList &checkedIds)
Checks all items contained by checkedIds and unchecks other items.
Definition: checklistmodel.cpp:268
QtUtilities::ChecklistModel::data
QVariant data(const QModelIndex &index, int role=Qt::DisplayRole) const override
Definition: checklistmodel.cpp:48
QtUtilities::ChecklistModel::setItems
void setItems(const QList< ChecklistItem > &items)
Sets the items.
Definition: checklistmodel.cpp:182
QtUtilities::ChecklistModel::restore
void restore(QSettings &settings, const QString &name)
Restores the IDs and checkstates read from the specified settings object.
Definition: checklistmodel.cpp:204
QtUtilities::ChecklistModel::setItemData
bool setItemData(const QModelIndex &index, const QMap< int, QVariant > &roles) override
Definition: checklistmodel.cpp:108
QtUtilities::ChecklistModel::removeRows
bool removeRows(int row, int count, const QModelIndex &parent) override
Definition: checklistmodel.cpp:166
QtUtilities::ChecklistModel::items
const QList< ChecklistItem > & items() const
Returns the items.
Definition: checklistmodel.h:104
QtUtilities::ChecklistModel::toVariantList
QVariantList toVariantList() const
Returns the checked IDs.
Definition: checklistmodel.cpp:253