1 /*
2 SPDX-FileCopyrightText: 2009 Ben Cooksley <ben@eclipse.endoftheinternet.org>
3 SPDX-FileCopyrightText: 2007 Will Stephenson <wstephenson@kde.org>
4
5 SPDX-License-Identifier: GPL-2.0-or-later
6 */
7
8 #include "PredicateModel.h"
9
10 #include "PredicateItem.h"
11
12 class PredicateModel::Private
13 {
14 public:
Private()15 Private()
16 {
17 }
18
19 PredicateItem *rootItem;
20 };
21
PredicateModel(PredicateItem * menuRoot,QObject * parent)22 PredicateModel::PredicateModel(PredicateItem *menuRoot, QObject *parent)
23 : QAbstractItemModel(parent)
24 , d(new Private())
25 {
26 d->rootItem = menuRoot;
27 }
28
~PredicateModel()29 PredicateModel::~PredicateModel()
30 {
31 delete d;
32 }
33
columnCount(const QModelIndex & parent) const34 int PredicateModel::columnCount(const QModelIndex &parent) const
35 {
36 Q_UNUSED(parent);
37 return 1;
38 }
39
rowCount(const QModelIndex & parent) const40 int PredicateModel::rowCount(const QModelIndex &parent) const
41 {
42 PredicateItem *mi;
43 if (parent.isValid()) {
44 mi = static_cast<PredicateItem *>(parent.internalPointer());
45 } else {
46 mi = d->rootItem;
47 }
48
49 return mi->children().count();
50 }
51
data(const QModelIndex & index,int role) const52 QVariant PredicateModel::data(const QModelIndex &index, int role) const
53 {
54 PredicateItem *mi = nullptr;
55 QVariant theData;
56 if (!index.isValid()) {
57 return QVariant();
58 }
59
60 mi = static_cast<PredicateItem *>(index.internalPointer());
61 switch (role) {
62 case Qt::DisplayRole:
63 theData.setValue(mi->prettyName());
64 break;
65 case Qt::UserRole:
66 theData.setValue(mi);
67 break;
68 default:
69 break;
70 }
71 return theData;
72 }
73
flags(const QModelIndex & index) const74 Qt::ItemFlags PredicateModel::flags(const QModelIndex &index) const
75 {
76 if (!index.isValid()) {
77 return Qt::ItemFlags();
78 }
79
80 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
81 }
82
index(int row,int column,const QModelIndex & parent) const83 QModelIndex PredicateModel::index(int row, int column, const QModelIndex &parent) const
84 {
85 if (!hasIndex(row, column, parent)) {
86 return QModelIndex();
87 }
88
89 PredicateItem *parentItem;
90 if (!parent.isValid()) {
91 parentItem = d->rootItem;
92 } else {
93 parentItem = static_cast<PredicateItem *>(parent.internalPointer());
94 }
95
96 PredicateItem *childItem = parentItem->children().value(row);
97 if (childItem) {
98 return createIndex(row, column, childItem);
99 } else {
100 return QModelIndex();
101 }
102 }
103
parent(const QModelIndex & index) const104 QModelIndex PredicateModel::parent(const QModelIndex &index) const
105 {
106 PredicateItem *childItem = static_cast<PredicateItem *>(index.internalPointer());
107 if (!childItem) {
108 return QModelIndex();
109 }
110
111 PredicateItem *parent = childItem->parent();
112 PredicateItem *grandParent = parent->parent();
113
114 int childRow = 0;
115 if (grandParent) {
116 childRow = grandParent->children().indexOf(parent);
117 }
118
119 if (parent == d->rootItem) {
120 return QModelIndex();
121 }
122 return createIndex(childRow, 0, parent);
123 }
124
rootItem() const125 PredicateItem *PredicateModel::rootItem() const
126 {
127 return d->rootItem;
128 }
129
setRootPredicate(PredicateItem * item)130 void PredicateModel::setRootPredicate(PredicateItem *item)
131 {
132 beginResetModel();
133 d->rootItem = item;
134 endResetModel();
135 }
136
itemUpdated(const QModelIndex & item)137 void PredicateModel::itemUpdated(const QModelIndex &item)
138 {
139 Q_EMIT dataChanged(item, item);
140 }
141
childrenChanging(const QModelIndex & item,Solid::Predicate::Type oldType)142 void PredicateModel::childrenChanging(const QModelIndex &item, Solid::Predicate::Type oldType)
143 {
144 PredicateItem *currentItem = static_cast<PredicateItem *>(item.internalPointer());
145 Solid::Predicate::Type newType = currentItem->itemType;
146
147 if (oldType == newType) {
148 return;
149 }
150
151 if (rowCount(item) != 0 && newType != Solid::Predicate::Conjunction && newType != Solid::Predicate::Disjunction) {
152 beginRemoveRows(item, 0, 1);
153 currentItem->updateChildrenStatus();
154 endRemoveRows();
155 return;
156 }
157
158 bool hasChildren = (newType == Solid::Predicate::Conjunction || newType == Solid::Predicate::Disjunction);
159
160 if (rowCount(item) == 0 && hasChildren) {
161 beginInsertRows(item, 0, 1);
162 currentItem->updateChildrenStatus();
163 endInsertRows();
164 }
165 }
166