00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "kdganttconstraintmodel.h"
00026 #include "kdganttconstraintmodel_p.h"
00027
00028 #include <QDebug>
00029
00030 #include <cassert>
00031
00032 using namespace KDGantt;
00033
00042 ConstraintModel::Private::Private()
00043 {
00044 }
00045
00046 void ConstraintModel::Private::addConstraintToIndex( const QModelIndex& idx, const Constraint& c )
00047 {
00048 IndexType::iterator it = indexMap.find(idx);
00049 while (it != indexMap.end() && it.key() == idx) {
00050
00051 if ( *it == c ) return;
00052 ++it;
00053 }
00054
00055 indexMap.insert( idx, c );
00056 }
00057
00058 void ConstraintModel::Private::removeConstraintFromIndex( const QModelIndex& idx, const Constraint& c )
00059 {
00060 IndexType::iterator it = indexMap.find(idx);
00061 while (it != indexMap.end() && it.key() == idx) {
00062 if ( *it == c ) {
00063 it =indexMap.erase( it );
00064 } else {
00065 ++it;
00066 }
00067 }
00068 }
00069
00072 ConstraintModel::ConstraintModel( QObject* parent )
00073 : QObject( parent ), _d( new Private )
00074 {
00075 init();
00076 }
00077
00079 ConstraintModel::ConstraintModel( Private* d_ptr, QObject* parent )
00080 : QObject( parent ), _d( d_ptr )
00081 {
00082 init();
00083 }
00084
00086 ConstraintModel::~ConstraintModel()
00087 {
00088 delete _d;
00089 }
00090
00091 #define d d_func()
00092
00093 void ConstraintModel::init()
00094 {
00095 }
00096
00101 void ConstraintModel::addConstraint( const Constraint& c )
00102 {
00103
00104 bool hasConstraint = d->constraints.contains( c );
00105
00106
00107 if ( !hasConstraint ) {
00108 d->constraints.push_back( c );
00109 d->addConstraintToIndex( c.startIndex(), c );
00110 d->addConstraintToIndex( c.endIndex(), c );
00111 emit constraintAdded( c );
00112 }
00113 }
00114
00122 bool ConstraintModel::removeConstraint( const Constraint& c )
00123 {
00124
00125 bool rc = d->constraints.removeAll( c );
00126
00127 if ( rc ) {
00128 d->removeConstraintFromIndex( c.startIndex(), c );
00129 d->removeConstraintFromIndex( c.endIndex(), c );
00130 emit constraintRemoved( c );
00131 }
00132 return rc;
00133 }
00134
00139 void ConstraintModel::clear()
00140 {
00141 QList<Constraint> lst = constraints();
00142 Q_FOREACH( const Constraint& c, lst ) {
00143 removeConstraint( c );
00144 }
00145 }
00146
00148 void ConstraintModel::cleanup()
00149 {
00150 #if 0
00151 QSet<Constraint> orphans;
00152 Q_FOREACH( const Constraint& c, d->constraints ) {
00153 if ( !c.startIndex().isValid() || !c.endIndex().isValid() ) orphans.insert( c );
00154 }
00155
00156 d->constraints.subtract( orphans );
00157 #endif
00158 }
00159
00163 QList<Constraint> ConstraintModel::constraints() const
00164 {
00165
00166 return d->constraints;
00167 }
00168
00172 QList<Constraint> ConstraintModel::constraintsForIndex( const QModelIndex& idx ) const
00173 {
00174
00175 assert( !idx.isValid() || d->indexMap.isEmpty() || !d->indexMap.keys().front().model() || idx.model() == d->indexMap.keys().front().model() );
00176 if ( !idx.isValid() ) {
00177
00178 QSet<Constraint> result;
00179 Q_FOREACH( Constraint c, d->constraints ) {
00180 if ( !c.startIndex().isValid() || !c.endIndex().isValid() ) result.insert( c );
00181 }
00182 return result.toList();
00183 } else {
00184 QList<Constraint> result;
00185 Q_FOREACH( Constraint c, d->constraints ) {
00186 if ( c.startIndex() == idx || c.endIndex() == idx ) result.push_back( c );
00187 }
00188 return result;
00189 }
00190
00191
00192 }
00193
00197 bool ConstraintModel::hasConstraint( const Constraint& c ) const
00198 {
00199
00200
00201
00202
00203
00204
00205
00206 return d->constraints.contains( c );
00207 }
00208
00209 #ifndef QT_NO_DEBUG_STREAM
00210
00211 QDebug operator<<( QDebug dbg, const KDGantt::ConstraintModel& model )
00212 {
00213 dbg << "KDGantt::ConstraintModel[ " << static_cast<const QObject*>( &model ) << ":"
00214 << model.constraints() << "]";
00215 return dbg;
00216 }
00217
00218 #endif
00219
00220 #undef d
00221
00222 #ifndef KDAB_NO_UNIT_TESTS
00223
00224 #include <QStandardItemModel>
00225
00226 #include "unittest/test.h"
00227
00228 std::ostream& operator<<( std::ostream& os, const QModelIndex& idx )
00229 {
00230 QString str;
00231 QDebug( &str )<<idx;
00232 #ifdef QT_NO_STL
00233 os<<str.toLatin1().constData();
00234 #else
00235 os<<str.toStdString();
00236 #endif
00237 return os;
00238 }
00239
00240 KDAB_SCOPED_UNITTEST_SIMPLE( KDGantt, ConstraintModel, "test" )
00241 {
00242 QStandardItemModel dummyModel( 100, 100 );
00243 ConstraintModel model;
00244
00245 QModelIndex invalidIndex;
00246 assertEqual( invalidIndex, invalidIndex );
00247
00248 assertEqual( model.constraints().count(), 0 );
00249
00250 model.addConstraint( Constraint( QModelIndex(), QModelIndex() ) );
00251 assertEqual( model.constraints().count(), 1 );
00252
00253 model.addConstraint( Constraint( QModelIndex(), QModelIndex() ) );
00254 assertEqual( model.constraints().count(), 1 );
00255
00256 QPersistentModelIndex idx1 = dummyModel.index( 7, 17, QModelIndex() );
00257 QPersistentModelIndex idx2 = dummyModel.index( 42, 17, QModelIndex() );
00258
00259 model.addConstraint( Constraint( idx1, idx2 ) );
00260 assertEqual( model.constraints().count(), 2 );
00261 assertTrue( model.hasConstraint( Constraint( idx1, idx2 ) ) );
00262
00263 assertEqual( model.constraintsForIndex( QModelIndex() ).count(), 1 );
00264
00265 assertEqual( model.constraints().count(), 2 );
00266 model.removeConstraint( Constraint( QModelIndex(), QModelIndex() ) );
00267 assertEqual( model.constraints().count(), 1 );
00268 assertFalse( model.hasConstraint( Constraint( QModelIndex(), QModelIndex() ) ) );
00269
00270 model.removeConstraint( Constraint( QModelIndex(), QModelIndex() ) );
00271 assertEqual( model.constraints().count(), 1 );
00272
00273 model.removeConstraint( Constraint( idx1, idx2 ) );
00274 assertEqual( model.constraints().count(), 0 );
00275 assertFalse( model.hasConstraint( Constraint( idx1, idx2 ) ) );
00276
00277 model.addConstraint( Constraint( idx1, idx2 ) );
00278 assertTrue( model.hasConstraint( Constraint( idx1, idx2 ) ) );
00279 dummyModel.removeRow( 8 );
00280 assertTrue( model.hasConstraint( Constraint( idx1, idx2 ) ) );
00281 dummyModel.removeRow( 7 );
00282 assertTrue( model.hasConstraint( Constraint( idx1, idx2 ) ) );
00283 }
00284
00285 #endif
00286
00287 #include "moc_kdganttconstraintmodel.cpp"