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