1/**************************************************************************
2 * Copyright (C) 2009 Ben Cooksley <ben@eclipse.endoftheinternet.org> *
3 * Copyright (C) 2007 Will Stephenson <wstephenson@kde.org> *
4 * *
5 * This program is free software; you can redistribute it and/or *
6 * modify it under the terms of the GNU General Public License *
7 * as published by the Free Software Foundation; either version 2 *
8 * of the License, or (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the Free Software *
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA *
18 * 02110-1301, USA. *
19***************************************************************************/
20
21#include "PredicateModel.h"
22
23#include "PredicateItem.h"
24
25class PredicateModel::Private {
26public:
27 Private() {}
28
29 PredicateItem * rootItem;
30};
31
32PredicateModel::PredicateModel( PredicateItem * menuRoot, QObject *parent )
33 : QAbstractItemModel( parent )
34 , d( new Private() )
35{
36 d->rootItem = menuRoot;
37}
38
39PredicateModel::~PredicateModel()
40{
41 delete d;
42}
43
44int PredicateModel::columnCount( const QModelIndex &parent ) const
45{
46 Q_UNUSED( parent );
47 return 1;
48}
49
50int PredicateModel::rowCount( const QModelIndex &parent ) const
51{
52 PredicateItem * mi;
53 if ( parent.isValid() ) {
54 mi = static_cast<PredicateItem*>( parent.internalPointer() );
55 } else {
56 mi = d->rootItem;
57 }
58
59 return mi->children().count();
60}
61
62QVariant PredicateModel::data( const QModelIndex &index, int role ) const
63{
64 PredicateItem * mi = 0;
65 QVariant theData;
66 if ( !index.isValid() ) {
67 return QVariant();
68 }
69
70 mi = static_cast<PredicateItem*>( index.internalPointer() );
71 switch ( role ) {
72 case Qt::DisplayRole:
73 theData.setValue( mi->prettyName() );
74 break;
75 case Qt::UserRole:
76 theData.setValue( mi );
77 break;
78 default:
79 break;
80 }
81 return theData;
82}
83
84Qt::ItemFlags PredicateModel::flags( const QModelIndex &index ) const
85{
86 if ( !index.isValid() ) {
87 return 0;
88 }
89
90 return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
91}
92
93QModelIndex PredicateModel::index( int row, int column, const QModelIndex &parent ) const
94{
95 if ( !hasIndex(row, column, parent) ) {
96 return QModelIndex();
97 }
98
99 PredicateItem *parentItem;
100 if ( !parent.isValid() ) {
101 parentItem = d->rootItem;
102 } else {
103 parentItem = static_cast<PredicateItem*>( parent.internalPointer() );
104 }
105
106 PredicateItem *childItem = parentItem->children().value(row);
107 if ( childItem ) {
108 return createIndex( row, column, childItem );
109 } else {
110 return QModelIndex();
111 }
112}
113
114QModelIndex PredicateModel::parent( const QModelIndex &index ) const
115{
116 PredicateItem *childItem = static_cast<PredicateItem*>( index.internalPointer() );
117 if( !childItem ) {
118 return QModelIndex();
119 }
120
121 PredicateItem * parent = childItem->parent();
122 PredicateItem * grandParent = parent->parent();
123
124 int childRow = 0;
125 if( grandParent ) {
126 childRow = grandParent->children().indexOf( parent );
127 }
128
129 if ( parent == d->rootItem ) {
130 return QModelIndex();
131 }
132 return createIndex( childRow, 0, parent );
133}
134
135PredicateItem * PredicateModel::rootItem() const
136{
137 return d->rootItem;
138}
139
140void PredicateModel::setRootPredicate( PredicateItem * item )
141{
142 d->rootItem = item;
143 reset();
144}
145
146void PredicateModel::itemUpdated( const QModelIndex& item )
147{
148 emit dataChanged( item, item );
149}
150
151void PredicateModel::childrenChanging( const QModelIndex& item, Solid::Predicate::Type oldType )
152{
153 PredicateItem * currentItem = static_cast<PredicateItem*>( item.internalPointer() );
154 Solid::Predicate::Type newType = currentItem->itemType;
155
156 if( oldType == newType ) {
157 return;
158 }
159
160 if( rowCount(item) != 0 && newType != Solid::Predicate::Conjunction && newType != Solid::Predicate::Disjunction ) {
161 emit beginRemoveRows( item, 0, 1 );
162 currentItem->updateChildrenStatus();
163 emit endRemoveRows();
164 return;
165 }
166
167 bool hasChildren = (newType == Solid::Predicate::Conjunction || newType == Solid::Predicate::Disjunction);
168
169 if( rowCount(item) == 0 && hasChildren ) {
170 emit beginInsertRows( item, 0, 1 );
171 currentItem->updateChildrenStatus();
172 emit endInsertRows();
173 }
174}
175
176#include "PredicateModel.moc"
177