Fix nepomukindexer usage, add minimal error handling.
[kdepim.git] / kdgantt2 / kdganttconstraintmodel.cpp
blob2ff28201ec83f7a04c7cca2639a9b5c908059d72
1 /****************************************************************************
2 ** Copyright (C) 2001-2006 Klarälvdalens Datakonsult AB. All rights reserved.
3 **
4 ** This file is part of the KD Gantt library.
5 **
6 ** This file may be distributed and/or modified under the terms of the
7 ** GNU General Public License version 2 as published by the Free Software
8 ** Foundation and appearing in the file LICENSE.GPL included in the
9 ** packaging of this file.
11 ** Licensees holding valid commercial KD Gantt licenses may use this file in
12 ** accordance with the KD Gantt Commercial License Agreement provided with
13 ** the Software.
15 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
18 ** See http://www.kdab.net/kdgantt for
19 ** information about KD Gantt Commercial License Agreements.
21 ** Contact info@kdab.net if any conditions of this
22 ** licensing are not clear to you.
24 **********************************************************************/
25 #include "kdganttconstraintmodel.h"
26 #include "kdganttconstraintmodel_p.h"
28 #include <QDebug>
30 #include <cassert>
32 using namespace KDGantt;
34 /*!\class KDGantt::ConstraintModel
35 *\ingroup KDGantt
36 * The ConstraintModel keeps track of the
37 * interdependencies between gantt items in
38 * a View.
42 ConstraintModel::Private::Private()
46 void ConstraintModel::Private::addConstraintToIndex( const QModelIndex& idx, const Constraint& c )
48 IndexType::iterator it = indexMap.find(idx);
49 while (it != indexMap.end() && it.key() == idx) {
50 // Check if we already have this
51 if ( *it == c ) return;
52 ++it;
55 indexMap.insert( idx, c );
58 void ConstraintModel::Private::removeConstraintFromIndex( const QModelIndex& idx, const Constraint& c )
60 IndexType::iterator it = indexMap.find(idx);
61 while (it != indexMap.end() && it.key() == idx) {
62 if ( *it == c ) {
63 it =indexMap.erase( it );
64 } else {
65 ++it;
70 /*! Constructor. Creates an empty ConstraintModel with parent \a parent
72 ConstraintModel::ConstraintModel( QObject* parent )
73 : QObject( parent ), _d( new Private )
75 init();
78 /*!\internal*/
79 ConstraintModel::ConstraintModel( Private* d_ptr, QObject* parent )
80 : QObject( parent ), _d( d_ptr )
82 init();
85 /*! Destroys this ConstraintModel */
86 ConstraintModel::~ConstraintModel()
88 delete _d;
91 #define d d_func()
93 void ConstraintModel::init()
97 /*! Adds the constraint \a c to this ConstraintModel
98 * If the Constraint \a c is already in this ConstraintModel,
99 * nothing happens.
101 void ConstraintModel::addConstraint( const Constraint& c )
103 //int size = d->constraints.size();
104 bool hasConstraint = d->constraints.contains( c );
105 //d->constraints.insert( c );
106 //if ( size != d->constraints.size() ) {
107 if ( !hasConstraint ) {
108 d->constraints.push_back( c );
109 d->addConstraintToIndex( c.startIndex(), c );
110 d->addConstraintToIndex( c.endIndex(), c );
111 emit constraintAdded( c );
115 /*! Removes the Constraint \a c from this
116 * ConstraintModel. If \a c was found and removed,
117 * the signal constraintRemoved(const Constraint&) is emitted.
119 * \returns If \a c was found and removed, it returns true,
120 * otherwise it returns false.
122 bool ConstraintModel::removeConstraint( const Constraint& c )
124 //qDebug() << "ConstraintModel::removeConstraint("<<c<<") from "<< d->constraints;
125 bool rc = d->constraints.removeAll( c );
126 //bool rc = d->constraints.remove( c );
127 if ( rc ) {
128 d->removeConstraintFromIndex( c.startIndex(), c );
129 d->removeConstraintFromIndex( c.endIndex(), c );
130 emit constraintRemoved( c );
132 return rc;
135 /*! Removes all Constraints from this model
136 * The signal constraintRemoved(const Constraint&) is emitted
137 * for every Constraint that is removed.
139 void ConstraintModel::clear()
141 QList<Constraint> lst = constraints();
142 Q_FOREACH( const Constraint& c, lst ) {
143 removeConstraint( c );
147 /*! Not used */
148 void ConstraintModel::cleanup()
150 #if 0
151 QSet<Constraint> orphans;
152 Q_FOREACH( const Constraint& c, d->constraints ) {
153 if ( !c.startIndex().isValid() || !c.endIndex().isValid() ) orphans.insert( c );
155 //qDebug() << "Constraint::cleanup() found" << orphans << "orphans";
156 d->constraints.subtract( orphans );
157 #endif
160 /*! \returns A list of all Constraints in this
161 * ConstraintModel.
163 QList<Constraint> ConstraintModel::constraints() const
165 //return d->constraints.toList();
166 return d->constraints;
169 /*! \returns A list of all Constraints in this ConstraintModel
170 * that have an endpoint at \a idx.
172 QList<Constraint> ConstraintModel::constraintsForIndex( const QModelIndex& idx ) const
174 assert( !idx.isValid() || d->indexMap.isEmpty() || !d->indexMap.keys().front().model() || idx.model() == d->indexMap.keys().front().model() );
175 if ( !idx.isValid() ) {
176 // Because of a Qt bug we need to treat this as a special case
177 QSet<Constraint> result;
178 Q_FOREACH( Constraint c, d->constraints ) {
179 if ( !c.startIndex().isValid() || !c.endIndex().isValid() ) result.insert( c );
181 return result.toList();
182 } else {
183 QList<Constraint> result;
184 Q_FOREACH( Constraint c, d->constraints ) {
185 if ( c.startIndex() == idx || c.endIndex() == idx ) result.push_back( c );
187 return result;
190 //return d->indexMap.values( idx );
193 /*! Returns true if a Constraint with start \a s and end \a e
194 * exists, otherwise false.
196 bool ConstraintModel::hasConstraint( const Constraint& c ) const
199 // Because of a Qt bug we have to search like this
200 Q_FOREACH( Constraint c2, d->constraints ) {
201 if ( c==c2 ) return true;
203 return false;
205 return d->constraints.contains( c );
208 #ifndef QT_NO_DEBUG_STREAM
210 QDebug operator<<( QDebug dbg, const KDGantt::ConstraintModel& model )
212 dbg << "KDGantt::ConstraintModel[ " << static_cast<const QObject*>( &model ) << ":"
213 << model.constraints() << "]";
214 return dbg;
217 #endif /* QT_NO_DEBUG_STREAM */
219 #undef d
221 #ifndef KDAB_NO_UNIT_TESTS
223 #include <QStandardItemModel>
225 #include "unittest/test.h"
227 std::ostream& operator<<( std::ostream& os, const QModelIndex& idx )
229 QString str;
230 QDebug( &str )<<idx;
231 #ifdef QT_NO_STL
232 os<<str.toLatin1().constData();
233 #else
234 os<<str.toStdString();
235 #endif
236 return os;
239 KDAB_SCOPED_UNITTEST_SIMPLE( KDGantt, ConstraintModel, "test" )
241 QStandardItemModel dummyModel( 100, 100 );
242 ConstraintModel model;
244 QModelIndex invalidIndex;
245 assertEqual( invalidIndex, invalidIndex );
247 assertEqual( model.constraints().count(), 0 );
249 model.addConstraint( Constraint( QModelIndex(), QModelIndex() ) );
250 assertEqual( model.constraints().count(), 1 );
252 model.addConstraint( Constraint( QModelIndex(), QModelIndex() ) );
253 assertEqual( model.constraints().count(), 1 );
255 QPersistentModelIndex idx1 = dummyModel.index( 7, 17, QModelIndex() );
256 QPersistentModelIndex idx2 = dummyModel.index( 42, 17, QModelIndex() );
258 model.addConstraint( Constraint( idx1, idx2 ) );
259 assertEqual( model.constraints().count(), 2 );
260 assertTrue( model.hasConstraint( Constraint( idx1, idx2 ) ) );
262 assertEqual( model.constraintsForIndex( QModelIndex() ).count(), 1 );
264 assertEqual( model.constraints().count(), 2 );
265 model.removeConstraint( Constraint( QModelIndex(), QModelIndex() ) );
266 assertEqual( model.constraints().count(), 1 );
267 assertFalse( model.hasConstraint( Constraint( QModelIndex(), QModelIndex() ) ) );
269 model.removeConstraint( Constraint( QModelIndex(), QModelIndex() ) );
270 assertEqual( model.constraints().count(), 1 );
272 model.removeConstraint( Constraint( idx1, idx2 ) );
273 assertEqual( model.constraints().count(), 0 );
274 assertFalse( model.hasConstraint( Constraint( idx1, idx2 ) ) );
276 model.addConstraint( Constraint( idx1, idx2 ) );
277 assertTrue( model.hasConstraint( Constraint( idx1, idx2 ) ) );
278 dummyModel.removeRow( 8 );
279 assertTrue( model.hasConstraint( Constraint( idx1, idx2 ) ) );
280 dummyModel.removeRow( 7 );
281 assertTrue( model.hasConstraint( Constraint( idx1, idx2 ) ) );
284 #endif /* KDAB_NO_UNIT_TESTS */
286 #include "moc_kdganttconstraintmodel.cpp"