~ubuntu-branches/ubuntu/raring/calligra/raring-proposed

« back to all changes in this revision

Viewing changes to 3rdparty/kdgantt/kdganttconstraintmodel.cpp

  • Committer: Package Import Robot
  • Author(s): Jonathan Riddell
  • Date: 2013-01-15 17:26:10 UTC
  • mfrom: (1.1.17)
  • Revision ID: package-import@ubuntu.com-20130115172610-b193s9546hyssmym
Tags: 1:2.5.94-0ubuntu1
New upstream RC release

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 used under the terms of the GNU General Public
 
7
 ** License versions 2.0 or 3.0 as published by the Free Software
 
8
 ** Foundation and appearing in the files LICENSE.GPL2 and LICENSE.GPL3
 
9
 ** included in the packaging of this file.  Alternatively you may (at
 
10
 ** your option) use any later version of the GNU General Public
 
11
 ** License if such license has been publicly approved by
 
12
 ** Klarälvdalens Datakonsult AB (or its successors, if any).
 
13
 ** 
 
14
 ** This file is provided "AS IS" with NO WARRANTY OF ANY KIND,
 
15
 ** INCLUDING THE WARRANTIES OF DESIGN, MERCHANTABILITY AND FITNESS FOR
 
16
 ** A PARTICULAR PURPOSE. Klarälvdalens Datakonsult AB reserves all rights
 
17
 ** not expressly granted herein.
 
18
 ** 
 
19
 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
 
20
 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 
21
 **
 
22
 **********************************************************************/
 
23
#include "kdganttconstraintmodel.h"
 
24
#include "kdganttconstraintmodel_p.h"
 
25
 
 
26
#include <QDebug>
 
27
 
 
28
#include <cassert>
 
29
 
 
30
using namespace KDGantt;
 
31
 
 
32
/*!\class KDGantt::ConstraintModel
 
33
 *\ingroup KDGantt
 
34
 * The ConstraintModel keeps track of the
 
35
 * interdependencies between gantt items in
 
36
 * a View.
 
37
 *
 
38
 */
 
39
 
 
40
ConstraintModel::Private::Private()
 
41
{
 
42
}
 
43
 
 
44
void ConstraintModel::Private::addConstraintToIndex( const QModelIndex& idx, const Constraint& c )
 
45
{
 
46
    IndexType::iterator it = indexMap.find(idx);
 
47
    while (it != indexMap.end() && it.key() == idx) {
 
48
        // Check if we already have this
 
49
        if ( *it == c ) return;
 
50
        ++it;
 
51
    }
 
52
 
 
53
    indexMap.insert( idx, c );
 
54
}
 
55
 
 
56
void ConstraintModel::Private::removeConstraintFromIndex( const QModelIndex& idx,  const Constraint& c )
 
57
{
 
58
    IndexType::iterator it = indexMap.find(idx);
 
59
    while (it != indexMap.end() && it.key() == idx) {
 
60
        if ( *it == c ) {
 
61
            it =indexMap.erase( it );
 
62
        } else {
 
63
            ++it;
 
64
        }
 
65
    }
 
66
}
 
67
 
 
68
/*! Constructor. Creates an empty ConstraintModel with parent \a parent
 
69
 */
 
70
ConstraintModel::ConstraintModel( QObject* parent )
 
71
    : QObject( parent ), _d( new Private )
 
72
{
 
73
    init();
 
74
}
 
75
 
 
76
/*!\internal*/
 
77
ConstraintModel::ConstraintModel( Private* d_ptr, QObject* parent )
 
78
    : QObject( parent ), _d( d_ptr )
 
79
{
 
80
    init();
 
81
}
 
82
 
 
83
/*! Destroys this ConstraintModel */
 
84
ConstraintModel::~ConstraintModel()
 
85
{
 
86
    delete _d;
 
87
}
 
88
 
 
89
#define d d_func()
 
90
 
 
91
void ConstraintModel::init()
 
92
{
 
93
}
 
94
 
 
95
/*! Adds the constraint \a c to this ConstraintModel
 
96
 *  If the Constraint \a c is already in this ConstraintModel,
 
97
 *  nothing happens.
 
98
 */
 
99
void ConstraintModel::addConstraint( const Constraint& c )
 
100
{
 
101
    //int size = d->constraints.size();
 
102
    bool hasConstraint = d->constraints.contains( c );
 
103
    //d->constraints.insert( c );
 
104
    //if ( size != d->constraints.size() ) {
 
105
    if ( !hasConstraint ) {
 
106
        d->constraints.push_back( c );
 
107
        d->addConstraintToIndex( c.startIndex(), c );
 
108
        d->addConstraintToIndex( c.endIndex(), c );
 
109
        emit constraintAdded( c );
 
110
    }
 
111
}
 
112
 
 
113
/*! Removes the Constraint \a c from this
 
114
 * ConstraintModel. If \a c was found and removed,
 
115
 * the signal constraintRemoved(const Constraint&) is emitted.
 
116
 *
 
117
 * \returns If \a c was found and removed, it returns true,
 
118
 * otherwise it returns false.
 
119
 */
 
120
bool ConstraintModel::removeConstraint( const Constraint& c )
 
121
{
 
122
    //qDebug() << "ConstraintModel::removeConstraint("<<c<<") from "<< d->constraints;
 
123
    bool rc = d->constraints.removeAll( c );
 
124
    //bool rc = d->constraints.remove( c );
 
125
    if ( rc ) {
 
126
        d->removeConstraintFromIndex( c.startIndex(), c );
 
127
        d->removeConstraintFromIndex( c.endIndex(), c );
 
128
        emit constraintRemoved( c );
 
129
    }
 
130
    return rc;
 
131
}
 
132
 
 
133
/*! Removes all Constraints from this model
 
134
 * The signal constraintRemoved(const Constraint&) is emitted
 
135
 * for every Constraint that is removed.
 
136
 */
 
137
void ConstraintModel::clear()
 
138
{
 
139
    QList<Constraint> lst = constraints();
 
140
    Q_FOREACH( const Constraint& c, lst ) {
 
141
        removeConstraint( c );
 
142
    }
 
143
}
 
144
 
 
145
/*! Not used */
 
146
void ConstraintModel::cleanup()
 
147
{
 
148
#if 0
 
149
    QSet<Constraint> orphans;
 
150
    Q_FOREACH( const Constraint& c, d->constraints ) {
 
151
        if ( !c.startIndex().isValid() || !c.endIndex().isValid() ) orphans.insert( c );
 
152
    }
 
153
    //qDebug() << "Constraint::cleanup() found" << orphans << "orphans";
 
154
    d->constraints.subtract( orphans );
 
155
#endif
 
156
}
 
157
 
 
158
/*! \returns A list of all Constraints in this
 
159
 * ConstraintModel.
 
160
 */
 
161
QList<Constraint> ConstraintModel::constraints() const
 
162
{
 
163
    //return d->constraints.toList();
 
164
    return d->constraints;
 
165
}
 
166
 
 
167
/*! \returns A list of all Constraints in this ConstraintModel
 
168
 * that have an endpoint at \a idx.
 
169
 */
 
170
QList<Constraint> ConstraintModel::constraintsForIndex( const QModelIndex& idx ) const
 
171
{
 
172
    assert( idx.isValid() || !d->indexMap.isEmpty() || d->indexMap.keys().front().model() || idx.model() == d->indexMap.keys().front().model() );
 
173
    if ( !idx.isValid() ) { //Why the assert idx.isValid() above? (dag)
 
174
        // Because of a Qt bug we need to treat this as a special case
 
175
        QSet<Constraint> result;
 
176
        Q_FOREACH( Constraint c, d->constraints ) {
 
177
            if ( !c.startIndex().isValid() || !c.endIndex().isValid() ) result.insert( c );
 
178
        }
 
179
        return result.toList();
 
180
    } else {
 
181
        QList<Constraint> result;
 
182
        Q_FOREACH( Constraint c, d->constraints ) {
 
183
            if ( c.startIndex() == idx || c.endIndex() == idx ) result.push_back( c );
 
184
        }
 
185
        return result;
 
186
    }
 
187
 
 
188
    //return d->indexMap.values( idx );
 
189
}
 
190
 
 
191
/*! Returns true if a Constraint with start \a s and end \a e
 
192
 * exists, otherwise false.
 
193
 */
 
194
bool ConstraintModel::hasConstraint( const Constraint& c ) const
 
195
{
 
196
    /*
 
197
    // Because of a Qt bug we have to search like this
 
198
    Q_FOREACH( Constraint c2, d->constraints ) {
 
199
        if ( c==c2 ) return true;
 
200
    }
 
201
    return false;
 
202
    */
 
203
    return d->constraints.contains( c );
 
204
}
 
205
 
 
206
#ifndef QT_NO_DEBUG_STREAM
 
207
 
 
208
QDebug operator<<( QDebug dbg, const KDGantt::ConstraintModel& model )
 
209
{
 
210
    dbg << "KDGantt::ConstraintModel[ " << static_cast<const QObject*>( &model ) << ":"
 
211
        << model.constraints() << "]";
 
212
    return dbg;
 
213
}
 
214
 
 
215
#endif /* QT_NO_DEBUG_STREAM */
 
216
 
 
217
#undef d
 
218
 
 
219
#ifndef KDAB_NO_UNIT_TESTS
 
220
 
 
221
#include <QStandardItemModel>
 
222
 
 
223
#include "unittest/test.h"
 
224
 
 
225
std::ostream& operator<<( std::ostream& os, const QModelIndex& idx )
 
226
{
 
227
    QString str;
 
228
    QDebug( &str )<<idx;
 
229
    os<<str.toStdString();
 
230
    return os;
 
231
}
 
232
 
 
233
KDAB_SCOPED_UNITTEST_SIMPLE( KDGantt, ConstraintModel, "test" )
 
234
{
 
235
    QStandardItemModel dummyModel( 100, 100 );
 
236
    ConstraintModel model;
 
237
 
 
238
    QModelIndex invalidIndex;
 
239
    assertEqual( invalidIndex, invalidIndex );
 
240
 
 
241
    assertEqual( model.constraints().count(), 0 );
 
242
 
 
243
    model.addConstraint( Constraint( QModelIndex(), QModelIndex() ) );
 
244
    assertEqual( model.constraints().count(), 1 );
 
245
 
 
246
    model.addConstraint( Constraint( QModelIndex(), QModelIndex() ) );
 
247
    assertEqual( model.constraints().count(), 1 );
 
248
 
 
249
    QPersistentModelIndex idx1 = dummyModel.index( 7, 17, QModelIndex() );
 
250
    QPersistentModelIndex idx2 = dummyModel.index( 42, 17, QModelIndex() );
 
251
 
 
252
    model.addConstraint( Constraint( idx1, idx2 ) );
 
253
    assertEqual( model.constraints().count(), 2 );
 
254
    assertTrue( model.hasConstraint( Constraint( idx1, idx2 ) ) );
 
255
 
 
256
    assertEqual( model.constraintsForIndex( QModelIndex() ).count(), 1 );
 
257
 
 
258
    assertEqual( model.constraints().count(), 2 );
 
259
    model.removeConstraint( Constraint( QModelIndex(), QModelIndex() ) );
 
260
    assertEqual( model.constraints().count(), 1 );
 
261
    assertFalse( model.hasConstraint( Constraint( QModelIndex(), QModelIndex() ) ) );
 
262
 
 
263
    model.removeConstraint( Constraint( QModelIndex(), QModelIndex() ) );
 
264
    assertEqual( model.constraints().count(), 1 );
 
265
 
 
266
    model.removeConstraint( Constraint( idx1, idx2 ) );
 
267
    assertEqual( model.constraints().count(), 0 );
 
268
    assertFalse( model.hasConstraint( Constraint( idx1, idx2 ) ) );
 
269
 
 
270
    model.addConstraint( Constraint( idx1, idx2 ) );
 
271
    assertTrue( model.hasConstraint( Constraint( idx1, idx2 ) ) );
 
272
    dummyModel.removeRow( 8 );
 
273
    assertTrue( model.hasConstraint( Constraint( idx1, idx2 ) ) );
 
274
    dummyModel.removeRow( 7 );
 
275
    assertTrue( model.hasConstraint( Constraint( idx1, idx2 ) ) );
 
276
}
 
277
 
 
278
#endif /* KDAB_NO_UNIT_TESTS */
 
279
 
 
280
#include "moc_kdganttconstraintmodel.cpp"