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