• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

kdgantt2

  • sources
  • kde-4.12
  • kdepim
  • kdgantt2
kdganttsummaryhandlingproxymodel.cpp
Go to the documentation of this file.
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 distributed and/or modified under the terms of the
7  ** GNU General Public License version 2 as published by the Free Software
8  ** Foundation and appearing in the file LICENSE.GPL included in the
9  ** packaging of this file.
10  **
11  ** Licensees holding valid commercial KD Gantt licenses may use this file in
12  ** accordance with the KD Gantt Commercial License Agreement provided with
13  ** the Software.
14  **
15  ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17  **
18  ** See http://www.kdab.net/kdgantt for
19  ** information about KD Gantt Commercial License Agreements.
20  **
21  ** Contact info@kdab.net if any conditions of this
22  ** licensing are not clear to you.
23  **
24  **********************************************************************/
25 #include "kdganttsummaryhandlingproxymodel.h"
26 #include "kdganttsummaryhandlingproxymodel_p.h"
27 
28 #include <QDebug>
29 
30 #include <cassert>
31 
32 using namespace KDGantt;
33 
50 typedef ForwardingProxyModel BASE;
51 
52 bool SummaryHandlingProxyModel::Private::cacheLookup( const QModelIndex& idx,
53  QPair<QDateTime,QDateTime>* result ) const
54 {
55  //qDebug() << "cacheLookup("<<idx<<"), cache has " << cached_summary_items.count() << "items";
56  QHash<QModelIndex,QPair<QDateTime,QDateTime> >::const_iterator it =
57  cached_summary_items.constFind( idx );
58  if ( it != cached_summary_items.constEnd() ) {
59  *result = *it;
60  return true;
61  } else {
62  return false;
63  }
64 }
65 
66 void SummaryHandlingProxyModel::Private::insertInCache( const SummaryHandlingProxyModel* model,
67  const QModelIndex& sourceIdx ) const
68 {
69  QAbstractItemModel* sourceModel = model->sourceModel();
70  const QModelIndex& mainIdx = sourceIdx;
71  QDateTime st;
72  QDateTime et;
73 
74  for ( int r = 0; r < sourceModel->rowCount( mainIdx ); ++r ) {
75  QModelIndex pdIdx = model->mapFromSource( sourceModel->index( r, 0, mainIdx ) );
76  /* The probably results in recursive calls here */
77  QVariant tmpsv = model->data( pdIdx, StartTimeRole );
78  QVariant tmpev = model->data( pdIdx, EndTimeRole );
79  if( !qVariantCanConvert<QDateTime>(tmpsv) ||
80  !qVariantCanConvert<QDateTime>(tmpev) ) {
81  qDebug() << "Skipping item " << sourceIdx << " because it doesn't contain QDateTime";
82  continue;
83  }
84 
85  // We need to test for empty strings to
86  // avoid a stupid Qt warning
87  if( tmpsv.type() == QVariant::String && qVariantValue<QString>(tmpsv).isEmpty()) continue;
88  if( tmpev.type() == QVariant::String && qVariantValue<QString>(tmpev).isEmpty()) continue;
89  QDateTime tmpst = tmpsv.toDateTime();
90  QDateTime tmpet = tmpev.toDateTime();
91  if ( st.isNull() || st > tmpst ) st = tmpst;
92  if ( et.isNull() || et < tmpet ) et = tmpet;
93  }
94  QVariant tmpssv = sourceModel->data( mainIdx, StartTimeRole );
95  QVariant tmpsev = sourceModel->data( mainIdx, EndTimeRole );
96  if ( qVariantCanConvert<QDateTime>( tmpssv )
97  && !( qVariantCanConvert<QString>( tmpssv ) && qVariantValue<QString>( tmpssv ).isEmpty() )
98  && qVariantValue<QDateTime>( tmpssv ) != st )
99  sourceModel->setData( mainIdx, st, StartTimeRole );
100  if ( qVariantCanConvert<QDateTime>( tmpsev )
101  && !( qVariantCanConvert<QString>( tmpsev ) && qVariantValue<QString>( tmpsev ).isEmpty() )
102  && qVariantValue<QDateTime>( tmpsev ) != et )
103  sourceModel->setData( mainIdx, et, EndTimeRole );
104  cached_summary_items[sourceIdx]=qMakePair( st, et );
105 }
106 
107 void SummaryHandlingProxyModel::Private::removeFromCache( const QModelIndex& idx ) const
108 {
109  cached_summary_items.remove( idx );
110 }
111 
112 void SummaryHandlingProxyModel::Private::clearCache() const
113 {
114  cached_summary_items.clear();
115 }
116 
120 SummaryHandlingProxyModel::SummaryHandlingProxyModel( QObject* parent )
121  : BASE( parent ), _d( new Private )
122 {
123  init();
124 }
125 
126 #define d d_func()
127 SummaryHandlingProxyModel::~SummaryHandlingProxyModel()
128 {
129 }
130 
131 void SummaryHandlingProxyModel::init()
132 {
133 }
134 
135 namespace {
136 
137  // Think this is ugly? Well, it's not from me, it comes from QProxyModel
138  struct KDPrivateModelIndex {
139  int r, c;
140  void *p;
141  const QAbstractItemModel *m;
142  };
143 }
144 
149 void SummaryHandlingProxyModel::setSourceModel( QAbstractItemModel* model )
150 {
151  BASE::setSourceModel( model );
152  d->clearCache();
153 }
154 
155 void SummaryHandlingProxyModel::sourceModelReset()
156 {
157  d->clearCache();
158  BASE::sourceModelReset();
159 }
160 
161 void SummaryHandlingProxyModel::sourceLayoutChanged()
162 {
163  d->clearCache();
164  BASE::sourceLayoutChanged();
165 }
166 
167 void SummaryHandlingProxyModel::sourceDataChanged( const QModelIndex& from, const QModelIndex& to )
168 {
169  QAbstractItemModel* model = sourceModel();
170  QModelIndex parentIdx = from;
171  do {
172  const QModelIndex& dataIdx = parentIdx;
173  if ( model->data( dataIdx, ItemTypeRole )==TypeSummary ) {
174  //qDebug() << "removing " << parentIdx << "from cache";
175  d->removeFromCache( dataIdx );
176  QModelIndex proxyDataIdx = mapFromSource( dataIdx );
177  emit dataChanged( proxyDataIdx, proxyDataIdx );
178  }
179  } while ( ( parentIdx=model->parent( parentIdx ) ) != QModelIndex() );
180 
181  BASE::sourceDataChanged( from, to );
182 }
183 
184 void SummaryHandlingProxyModel::sourceColumnsAboutToBeInserted( const QModelIndex& parentIdx,
185  int start,
186  int end )
187 {
188  BASE::sourceColumnsAboutToBeInserted( parentIdx, start, end );
189  d->clearCache();
190 }
191 
192 void SummaryHandlingProxyModel::sourceColumnsAboutToBeRemoved( const QModelIndex& parentIdx,
193  int start,
194  int end )
195 {
196  BASE::sourceColumnsAboutToBeRemoved( parentIdx, start, end );
197  d->clearCache();
198 }
199 
200 void SummaryHandlingProxyModel::sourceRowsAboutToBeInserted( const QModelIndex & parentIdx, int start, int end )
201 {
202  BASE::sourceRowsAboutToBeInserted( parentIdx, start, end );
203  d->clearCache();
204 }
205 
206 void SummaryHandlingProxyModel::sourceRowsAboutToBeRemoved( const QModelIndex & parentIdx, int start, int end )
207 {
208  BASE::sourceRowsAboutToBeRemoved( parentIdx, start, end );
209  d->clearCache();
210 }
211 
213 Qt::ItemFlags SummaryHandlingProxyModel::flags( const QModelIndex& idx ) const
214 {
215  const QModelIndex sidx = mapToSource( idx );
216  const QAbstractItemModel* model = sourceModel();
217  Qt::ItemFlags f = model->flags( sidx );
218  if ( d->isSummary(sidx) ) {
219  f &= !Qt::ItemIsEditable;
220  }
221  return f;
222 }
223 
225 QVariant SummaryHandlingProxyModel::data( const QModelIndex& proxyIndex, int role) const
226 {
227  //qDebug() << "SummaryHandlingProxyModel::data("<<proxyIndex<<role<<")";
228  const QModelIndex sidx = mapToSource( proxyIndex );
229  const QAbstractItemModel* model = sourceModel();
230  if ( d->isSummary(sidx) && ( role==StartTimeRole || role==EndTimeRole )) {
231  //qDebug() << "requested summary";
232  QPair<QDateTime,QDateTime> result;
233  if ( d->cacheLookup( sidx, &result ) ) {
234  //qDebug() << "SummaryHandlingProxyModel::data(): Looking up summary for " << proxyIndex << role;
235  switch( role ) {
236  case StartTimeRole: return result.first;
237  case EndTimeRole: return result.second;
238  default: /* fall thru */;
239  }
240  } else {
241  d->insertInCache( this, sidx );
242  return data( proxyIndex, role ); /* TODO: Optimise */
243  }
244  }
245  return model->data( sidx, role );
246 }
247 
249 bool SummaryHandlingProxyModel::setData( const QModelIndex& index, const QVariant& value, int role )
250 {
251  QAbstractItemModel* model = sourceModel();
252  if ( role==StartTimeRole || role==EndTimeRole ) {
253  QModelIndex parentIdx = mapToSource( index );
254  do {
255  if ( d->isSummary(parentIdx) ) {
256  //qDebug() << "removing " << parentIdx << "from cache";
257  d->removeFromCache( parentIdx );
258  QModelIndex proxyParentIdx = mapFromSource( parentIdx );
259  emit dataChanged( proxyParentIdx, proxyParentIdx );
260  }
261  } while ( ( parentIdx=model->parent( parentIdx ) ) != QModelIndex() );
262  }
263  return BASE::setData( index, value, role );
264 }
265 
266 #undef d
267 
268 #ifndef KDAB_NO_UNIT_TESTS
269 
270 #include "unittest/test.h"
271 
272 #include <QStandardItemModel>
273 
274 namespace {
275  std::ostream& operator<<( std::ostream& os, const QDateTime& dt )
276  {
277 #ifdef QT_NO_STL
278  os << dt.toString().toLatin1().constData();
279 #else
280  os << dt.toString().toStdString();
281 #endif
282  return os;
283  }
284 }
285 
286 KDAB_SCOPED_UNITTEST_SIMPLE( KDGantt, SummaryHandlingProxyModel, "test" ) {
287  SummaryHandlingProxyModel model;
288  QStandardItemModel sourceModel;
289 
290  model.setSourceModel( &sourceModel );
291 
292  QStandardItem* topitem = new QStandardItem( QString::fromLatin1( "Summary" ) );
293  topitem->setData( KDGantt::TypeSummary, KDGantt::ItemTypeRole );
294  sourceModel.appendRow( topitem );
295 
296  QStandardItem* task1 = new QStandardItem( QString::fromLatin1( "Task1" ) );
297  task1->setData( KDGantt::TypeTask, KDGantt::ItemTypeRole );
298  QStandardItem* task2 = new QStandardItem( QString::fromLatin1( "Task2" ) );
299  task2->setData( KDGantt::TypeTask, KDGantt::ItemTypeRole );
300  topitem->appendRow( task1 );
301  topitem->appendRow( task2 );
302 
303 
304  QDateTime startdt = QDateTime::currentDateTime();
305  QDateTime enddt = startdt.addDays( 1 );
306 
307 
308  task1->setData( startdt, KDGantt::StartTimeRole );
309  task1->setData( enddt, KDGantt::EndTimeRole );
310  task2->setData( startdt, KDGantt::StartTimeRole );
311  task2->setData( enddt, KDGantt::EndTimeRole );
312 
313  const QModelIndex topidx = model.index( 0, 0, QModelIndex() );
314 
315  assertEqual( model.data( topidx, KDGantt::ItemTypeRole ).toInt(), KDGantt::TypeSummary );
316  assertEqual( model.data( model.index( 0, 0, topidx ), KDGantt::ItemTypeRole ).toInt(), KDGantt::TypeTask );
317 
318  QDateTime task1startdt = model.data( model.index( 0, 0, topidx ), KDGantt::StartTimeRole ).toDateTime();
319  assertEqual( task1startdt, startdt );
320 
321  QDateTime summarystartdt = model.data( topidx, KDGantt::StartTimeRole ).toDateTime();
322  assertEqual( summarystartdt, startdt );
323  assertTrue( model.flags( model.index( 0, 0, topidx ) ) & Qt::ItemIsEditable );
324  assertFalse( model.flags( topidx ) & Qt::ItemIsEditable );
325 }
326 
327 #endif /* KDAB_NO_UNIT_TESTS */
328 
329 #include "moc_kdganttsummaryhandlingproxymodel.cpp"
KDGantt::SummaryHandlingProxyModel::sourceColumnsAboutToBeRemoved
void sourceColumnsAboutToBeRemoved(const QModelIndex &idx, int start, int end)
Definition: kdganttsummaryhandlingproxymodel.cpp:192
KDGantt::SummaryHandlingProxyModel::~SummaryHandlingProxyModel
virtual ~SummaryHandlingProxyModel()
Definition: kdganttsummaryhandlingproxymodel.cpp:127
KDGantt::SummaryHandlingProxyModel::setData
bool setData(const QModelIndex &index, const QVariant &value, int role=Qt::EditRole)
Definition: kdganttsummaryhandlingproxymodel.cpp:249
KDGantt::TypeSummary
Definition: kdganttglobal.h:215
kdganttsummaryhandlingproxymodel.h
KDGantt::SummaryHandlingProxyModel::sourceRowsAboutToBeInserted
void sourceRowsAboutToBeInserted(const QModelIndex &idx, int start, int end)
Definition: kdganttsummaryhandlingproxymodel.cpp:200
KDGantt::SummaryHandlingProxyModel::Private::cacheLookup
bool cacheLookup(const QModelIndex &idx, QPair< QDateTime, QDateTime > *result) const
Definition: kdganttsummaryhandlingproxymodel.cpp:52
KDGantt::SummaryHandlingProxyModel::sourceModelReset
void sourceModelReset()
Definition: kdganttsummaryhandlingproxymodel.cpp:155
KDGantt::SummaryHandlingProxyModel::Private::cached_summary_items
QHash< QModelIndex, QPair< QDateTime, QDateTime > > cached_summary_items
Definition: kdganttsummaryhandlingproxymodel_p.h:49
KDGantt::StartTimeRole
Definition: kdganttglobal.h:204
KDGantt::ForwardingProxyModel::index
QModelIndex index(int row, int column, const QModelIndex &parent=QModelIndex()) const
Definition: kdganttforwardingproxymodel.cpp:261
KDGantt::SummaryHandlingProxyModel::setSourceModel
void setSourceModel(QAbstractItemModel *model)
Definition: kdganttsummaryhandlingproxymodel.cpp:149
QObject
KDGantt::ForwardingProxyModel::mapFromSource
QModelIndex mapFromSource(const QModelIndex &sourceIndex) const
Definition: kdganttforwardingproxymodel.cpp:46
operator<<
QDebug operator<<(QDebug dbg, const Constraint &c)
Definition: kdganttconstraint.cpp:154
KDGantt::SummaryHandlingProxyModel::flags
Qt::ItemFlags flags(const QModelIndex &idx) const
Definition: kdganttsummaryhandlingproxymodel.cpp:213
KDGantt::SummaryHandlingProxyModel::Private
Definition: kdganttsummaryhandlingproxymodel_p.h:36
KDGantt::TypeTask
Definition: kdganttglobal.h:214
KDGantt::SummaryHandlingProxyModel::Private::insertInCache
void insertInCache(const SummaryHandlingProxyModel *model, const QModelIndex &idx) const
Definition: kdganttsummaryhandlingproxymodel.cpp:66
KDGantt::ItemTypeRole
Definition: kdganttglobal.h:207
BASE
ForwardingProxyModel BASE
Definition: kdganttsummaryhandlingproxymodel.cpp:50
KDGantt::SummaryHandlingProxyModel::Private::clearCache
void clearCache() const
Definition: kdganttsummaryhandlingproxymodel.cpp:112
KDGantt::SummaryHandlingProxyModel::sourceDataChanged
void sourceDataChanged(const QModelIndex &from, const QModelIndex &to)
Definition: kdganttsummaryhandlingproxymodel.cpp:167
KDGantt::EndTimeRole
Definition: kdganttglobal.h:205
QAbstractProxyModel
KDGantt::SummaryHandlingProxyModel::sourceLayoutChanged
void sourceLayoutChanged()
Definition: kdganttsummaryhandlingproxymodel.cpp:161
KDGantt::SummaryHandlingProxyModel::data
QVariant data(const QModelIndex &proxyIndex, int role=Qt::DisplayRole) const
Definition: kdganttsummaryhandlingproxymodel.cpp:225
KDAB_SCOPED_UNITTEST_SIMPLE
KDAB_SCOPED_UNITTEST_SIMPLE(KDGantt, SummaryHandlingProxyModel,"test")
Definition: kdganttsummaryhandlingproxymodel.cpp:286
KDGantt::SummaryHandlingProxyModel
Proxy model that supports summary gantt items.
Definition: kdganttsummaryhandlingproxymodel.h:31
KDGantt::ForwardingProxyModel
Definition: kdganttforwardingproxymodel.h:33
KDGantt::ForwardingProxyModel::mapToSource
QModelIndex mapToSource(const QModelIndex &proxyIndex) const
Definition: kdganttforwardingproxymodel.cpp:67
KDGantt::ForwardingProxyModel::parent
QModelIndex parent(const QModelIndex &idx) const
Definition: kdganttforwardingproxymodel.cpp:267
d
#define d
Definition: kdganttsummaryhandlingproxymodel.cpp:126
KDGantt::SummaryHandlingProxyModel::SummaryHandlingProxyModel
SummaryHandlingProxyModel(QObject *parent=0)
Definition: kdganttsummaryhandlingproxymodel.cpp:120
KDGantt::SummaryHandlingProxyModel::sourceRowsAboutToBeRemoved
void sourceRowsAboutToBeRemoved(const QModelIndex &, int start, int end)
Definition: kdganttsummaryhandlingproxymodel.cpp:206
kdganttsummaryhandlingproxymodel_p.h
KDGantt::SummaryHandlingProxyModel::sourceColumnsAboutToBeInserted
void sourceColumnsAboutToBeInserted(const QModelIndex &idx, int start, int end)
Definition: kdganttsummaryhandlingproxymodel.cpp:184
KDGantt::SummaryHandlingProxyModel::Private::removeFromCache
void removeFromCache(const QModelIndex &idx) const
Definition: kdganttsummaryhandlingproxymodel.cpp:107
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:55:05 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kdgantt2

Skip menu "kdgantt2"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Modules
  • Related Pages

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal