28 : QAbstractListModel(parent)
34 if (!parent.isValid()) {
35 return m_items.size();
42 if (!index.isValid() || index.row() >= m_items.count() || index.model() !=
this) {
43 return Qt::ItemIsDropEnabled;
45 return QAbstractListModel::flags(index) | Qt::ItemIsUserCheckable | Qt::ItemIsDragEnabled;
50 if (index.isValid() && index.row() < m_items.size()) {
53 return m_items.at(index.row()).label();
54 case Qt::CheckStateRole:
55 return m_items.at(index.row()).checkState();
57 return m_items.at(index.row()).id();
66 QMap<int, QVariant> roles;
67 roles.insert(Qt::DisplayRole,
data(index, Qt::DisplayRole));
68 roles.insert(Qt::CheckStateRole,
data(index, Qt::CheckStateRole));
76 QVector<int> roles{ role };
77 if (index.isValid() && index.row() < m_items.size()) {
80 m_items[index.row()].m_label = value.toString();
83 case Qt::CheckStateRole:
85 #if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
88 QMetaType::fromType<int>()
91 m_items[index.row()].m_checkState =
static_cast<Qt::CheckState
>(value.toInt());
96 m_items[index.row()].m_id = value;
99 if (!label.isEmpty()) {
100 m_items[index.row()].m_label = std::move(label);
101 roles << Qt::DisplayRole;
109 emit dataChanged(index, index, roles);
116 for (QMap<int, QVariant>::ConstIterator it = roles.constBegin(); it != roles.constEnd(); ++it) {
117 setData(index, it.value(), it.key());
127 if (row < 0 || row >= m_items.size()) {
130 m_items[row].m_checkState = checked ? Qt::Checked : Qt::Unchecked;
131 const auto index(this->index(row));
132 emit dataChanged(index, index, QVector<int>{ Qt::CheckStateRole });
156 return Qt::MoveAction;
161 if (count < 1 || row < 0 || row >
rowCount() || parent.isValid()) {
164 beginInsertRows(QModelIndex(), row, row + count - 1);
165 for (
int index = row, end = row + count; index < end; ++index) {
174 if (count < 1 || row < 0 || (row + count) >
rowCount() || parent.isValid()) {
177 beginRemoveRows(QModelIndex(), row, row + count - 1);
178 for (
int index = row, end = row + count; index < end; ++index) {
179 m_items.removeAt(index);
192 for (
auto &item : m_items) {
193 if (item.m_label.isEmpty()) {
213 auto currentItems = m_items;
214 QList<QVariant> restoredIds;
216 int rows = settings.beginReadArray(name);
217 m_items.reserve(rows);
218 for (
int i = 0; i < rows; ++i) {
219 settings.setArrayIndex(i);
220 const auto id = settings.value(QStringLiteral(
"id"));
221 const auto isIdValid = [&] {
222 for (
const auto &item : currentItems) {
223 if (item.id() ==
id) {
232 const auto selected = settings.value(QStringLiteral(
"selected"));
233 if (!
id.isNull() && !selected.isNull()
234 && selected.canConvert(
235 #
if (QT_VERSION < QT_VERSION_CHECK(6, 0, 0))
238 QMetaType::fromType<bool>()
241 && !restoredIds.contains(
id)) {
248 if (!restoredIds.contains(item.id())) {
264 settings.beginWriteArray(name, m_items.size());
267 settings.setArrayIndex(index);
268 settings.setValue(QStringLiteral(
"id"), item.id());
269 settings.setValue(QStringLiteral(
"selected"), item.isChecked());
280 QVariantList checkedIds;
281 checkedIds.reserve(m_items.size());
282 for (
const auto &item : m_items) {
283 if (item.isChecked()) {
284 checkedIds << item.id();
295 for (
auto &item : m_items) {
296 item.m_checkState = checkedIds.contains(item.id()) ? Qt::Checked : Qt::Unchecked;
298 emit dataChanged(index(0), index(m_items.size()), { Qt::CheckStateRole });