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 assert( idx.isValid() || !d->indexMap.isEmpty() || d->indexMap.keys().front().model() || idx.model() == d->indexMap.keys().front().model() );
00173 if ( !idx.isValid() ) {
00174
00175 QSet<Constraint> result;
00176 Q_FOREACH( Constraint c, d->constraints ) {
00177 if ( !c.startIndex().isValid() || !c.endIndex().isValid() ) result.insert( c );
00178 }
00179 return result.toList();
00180 } else {
00181 QList<Constraint> result;
00182 Q_FOREACH( Constraint c, d->constraints ) {
00183 if ( c.startIndex() == idx || c.endIndex() == idx ) result.push_back( c );
00184 }
00185 return result;
00186 }
00187
00188
00189 }
00190
00194 bool ConstraintModel::hasConstraint( const Constraint& c ) const
00195 {
00196
00197
00198
00199
00200
00201
00202
00203 return d->constraints.contains( c );
00204 }
00205
00206 #ifndef QT_NO_DEBUG_STREAM
00207
00208 QDebug operator<<( QDebug dbg, const KDGantt::ConstraintModel& model )
00209 {
00210 dbg << "KDGantt::ConstraintModel[ " << static_cast<const QObject*>( &model ) << ":"
00211 << model.constraints() << "]";
00212 return dbg;
00213 }
00214
00215 #endif
00216
00217 #undef d
00218
00219 #ifndef KDAB_NO_UNIT_TESTS
00220
00221 #include <QStandardItemModel>
00222
00223 #include "unittest/test.h"
00224
00225 std::ostream& operator<<( std::ostream& os, const QModelIndex& idx )
00226 {
00227 QString str;
00228 QDebug( &str )<<idx;
00229 os<<str.toStdString();
00230 return os;
00231 }
00232
00233 KDAB_SCOPED_UNITTEST_SIMPLE( KDGantt, ConstraintModel, "test" )
00234 {
00235 QStandardItemModel dummyModel( 100, 100 );
00236 ConstraintModel model;
00237
00238 QModelIndex invalidIndex;
00239 assertEqual( invalidIndex, invalidIndex );
00240
00241 assertEqual( model.constraints().count(), 0 );
00242
00243 model.addConstraint( Constraint( QModelIndex(), QModelIndex() ) );
00244 assertEqual( model.constraints().count(), 1 );
00245
00246 model.addConstraint( Constraint( QModelIndex(), QModelIndex() ) );
00247 assertEqual( model.constraints().count(), 1 );
00248
00249 QPersistentModelIndex idx1 = dummyModel.index( 7, 17, QModelIndex() );
00250 QPersistentModelIndex idx2 = dummyModel.index( 42, 17, QModelIndex() );
00251
00252 model.addConstraint( Constraint( idx1, idx2 ) );
00253 assertEqual( model.constraints().count(), 2 );
00254 assertTrue( model.hasConstraint( Constraint( idx1, idx2 ) ) );
00255
00256 assertEqual( model.constraintsForIndex( QModelIndex() ).count(), 1 );
00257
00258 assertEqual( model.constraints().count(), 2 );
00259 model.removeConstraint( Constraint( QModelIndex(), QModelIndex() ) );
00260 assertEqual( model.constraints().count(), 1 );
00261 assertFalse( model.hasConstraint( Constraint( QModelIndex(), QModelIndex() ) ) );
00262
00263 model.removeConstraint( Constraint( QModelIndex(), QModelIndex() ) );
00264 assertEqual( model.constraints().count(), 1 );
00265
00266 model.removeConstraint( Constraint( idx1, idx2 ) );
00267 assertEqual( model.constraints().count(), 0 );
00268 assertFalse( model.hasConstraint( Constraint( idx1, idx2 ) ) );
00269
00270 model.addConstraint( Constraint( idx1, idx2 ) );
00271 assertTrue( model.hasConstraint( Constraint( idx1, idx2 ) ) );
00272 dummyModel.removeRow( 8 );
00273 assertTrue( model.hasConstraint( Constraint( idx1, idx2 ) ) );
00274 dummyModel.removeRow( 7 );
00275 assertTrue( model.hasConstraint( Constraint( idx1, idx2 ) ) );
00276 }
00277
00278 #endif
00279
00280 #include "moc_kdganttconstraintmodel.cpp"