kdganttconstraintmodel.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002  ** Copyright (C) 2001-2006 Klarälvdalens Datakonsult AB.  All rights reserved.
00003  **
00004  ** This file is part of the KD Gantt library.
00005  **
00006  ** This file may be distributed and/or modified under the terms of the
00007  ** GNU General Public License version 2 as published by the Free Software
00008  ** Foundation and appearing in the file LICENSE.GPL included in the
00009  ** packaging of this file.
00010  **
00011  ** Licensees holding valid commercial KD Gantt licenses may use this file in
00012  ** accordance with the KD Gantt Commercial License Agreement provided with
00013  ** the Software.
00014  **
00015  ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00016  ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00017  **
00018  ** See http://www.kdab.net/kdgantt for
00019  **   information about KD Gantt Commercial License Agreements.
00020  **
00021  ** Contact info@kdab.net if any conditions of this
00022  ** licensing are not clear to you.
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         // Check if we already have this
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     //int size = d->constraints.size();
00104     bool hasConstraint = d->constraints.contains( c );
00105     //d->constraints.insert( c );
00106     //if ( size != d->constraints.size() ) {
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     //qDebug() << "ConstraintModel::removeConstraint("<<c<<") from "<< d->constraints;
00125     bool rc = d->constraints.removeAll( c );
00126     //bool rc = d->constraints.remove( c );
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     //qDebug() << "Constraint::cleanup() found" << orphans << "orphans";
00156     d->constraints.subtract( orphans );
00157 #endif
00158 }
00159 
00163 QList<Constraint> ConstraintModel::constraints() const
00164 {
00165     //return d->constraints.toList();
00166     return d->constraints;
00167 }
00168 
00172 QList<Constraint> ConstraintModel::constraintsForIndex( const QModelIndex& idx ) const
00173 {
00174     // TODO: @Steffen: Please comment on this assert, it's long and not obvious (Johannes)
00175     assert( !idx.isValid() || d->indexMap.isEmpty() || !d->indexMap.keys().front().model() || idx.model() == d->indexMap.keys().front().model() );
00176     if ( !idx.isValid() ) {
00177         // Because of a Qt bug we need to treat this as a special case
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     //return d->indexMap.values( idx );
00192 }
00193 
00197 bool ConstraintModel::hasConstraint( const Constraint& c ) const
00198 {
00199     /*
00200     // Because of a Qt bug we have to search like this
00201     Q_FOREACH( Constraint c2, d->constraints ) {
00202         if ( c==c2 ) return true;
00203     }
00204     return false;
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 /* QT_NO_DEBUG_STREAM */
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 /* KDAB_NO_UNIT_TESTS */
00286 
00287 #include "moc_kdganttconstraintmodel.cpp"

Generated on Thu Mar 4 23:19:13 2010 for KD Chart 2 by  doxygen 1.5.4