1 | /* This file is part of the KDE project |
2 | Copyright (C) 2007, 2012 Dag Andersen <danders@get2net> |
3 | |
4 | This library is free software; you can redistribute it and/or |
5 | modify it under the terms of the GNU Library General Public |
6 | License as published by the Free Software Foundation; either |
7 | version 2 of the License, or (at your option) any later version. |
8 | |
9 | This library is distributed in the hope that it will be useful, |
10 | but WITHOUT ANY WARRANTY; without even the implied warranty of |
11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
12 | Library General Public License for more details. |
13 | |
14 | You should have received a copy of the GNU Library General Public License |
15 | along with this library; see the file COPYING.LIB. If not, write to |
16 | the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
17 | * Boston, MA 02110-1301, USA. |
18 | */ |
19 | |
20 | #include "kptpertcpmmodel.h" |
21 | |
22 | #include "kptglobal.h" |
23 | #include "kptcommonstrings.h" |
24 | #include "kptproject.h" |
25 | #include "kpttask.h" |
26 | #include "kptnode.h" |
27 | #include "kptschedule.h" |
28 | #include "kptdebug.h" |
29 | |
30 | #include <QStringList> |
31 | #include <QMimeData> |
32 | |
33 | #include <kglobal.h> |
34 | #include <klocale.h> |
35 | |
36 | |
37 | namespace KPlato |
38 | { |
39 | |
40 | class Project; |
41 | class Node; |
42 | class Task; |
43 | |
44 | typedef QList<Node*> NodeList; |
45 | |
46 | CriticalPathItemModel::CriticalPathItemModel( QObject *parent ) |
47 | : ItemModelBase( parent ), |
48 | m_manager( 0 ) |
49 | { |
50 | /* connect( this, SIGNAL(modelAboutToBeReset()), SLOT(slotAboutToBeReset()) ); |
51 | connect( this, SIGNAL(modelReset()), SLOT(slotReset()) );*/ |
52 | } |
53 | |
54 | CriticalPathItemModel::~CriticalPathItemModel() |
55 | { |
56 | } |
57 | |
58 | void CriticalPathItemModel::slotNodeToBeInserted( Node *, int ) |
59 | { |
60 | //kDebug(planDbg())<<node->name(); |
61 | } |
62 | |
63 | void CriticalPathItemModel::slotNodeInserted( Node * /*node*/ ) |
64 | { |
65 | //kDebug(planDbg())<<node->getParent->name()<<"-->"<<node->name(); |
66 | } |
67 | |
68 | void CriticalPathItemModel::slotNodeToBeRemoved( Node *node ) |
69 | { |
70 | Q_UNUSED(node); |
71 | //kDebug(planDbg())<<node->name(); |
72 | /* if ( m_path.contains( node ) ) { |
73 | }*/ |
74 | } |
75 | |
76 | void CriticalPathItemModel::slotNodeRemoved( Node *node ) |
77 | { |
78 | Q_UNUSED(node); |
79 | //kDebug(planDbg())<<node->name(); |
80 | } |
81 | |
82 | void CriticalPathItemModel::setProject( Project *project ) |
83 | { |
84 | if ( m_project ) { |
85 | disconnect( m_project, SIGNAL(nodeChanged(Node*)), this, SLOT(slotNodeChanged(Node*)) ); |
86 | disconnect( m_project, SIGNAL(nodeToBeAdded(Node*,int)), this, SLOT(slotNodeToBeInserted(Node*,int)) ); |
87 | disconnect( m_project, SIGNAL(nodeToBeRemoved(Node*)), this, SLOT(slotNodeToBeRemoved(Node*)) ); |
88 | disconnect( m_project, SIGNAL(nodeToBeMoved(Node*,int,Node*,int)), this, SLOT(slotLayoutToBeChanged()) ); |
89 | |
90 | disconnect( m_project, SIGNAL(nodeAdded(Node*)), this, SLOT(slotNodeInserted(Node*)) ); |
91 | disconnect( m_project, SIGNAL(nodeRemoved(Node*)), this, SLOT(slotNodeRemoved(Node*)) ); |
92 | disconnect( m_project, SIGNAL(nodeMoved(Node*)), this, SLOT(slotLayoutChanged()) ); |
93 | } |
94 | m_project = project; |
95 | m_nodemodel.setProject( project ); |
96 | if ( project ) { |
97 | connect( m_project, SIGNAL(nodeChanged(Node*)), this, SLOT(slotNodeChanged(Node*)) ); |
98 | connect( m_project, SIGNAL(nodeToBeAdded(Node*,int)), this, SLOT(slotNodeToBeInserted(Node*,int)) ); |
99 | connect( m_project, SIGNAL(nodeToBeRemoved(Node*)), this, SLOT(slotNodeToBeRemoved(Node*)) ); |
100 | connect( m_project, SIGNAL(nodeToBeMoved(Node*,int,Node*,int)), this, SLOT(slotLayoutToBeChanged()) ); |
101 | |
102 | connect( m_project, SIGNAL(nodeAdded(Node*)), this, SLOT(slotNodeInserted(Node*)) ); |
103 | connect( m_project, SIGNAL(nodeRemoved(Node*)), this, SLOT(slotNodeRemoved(Node*)) ); |
104 | connect( m_project, SIGNAL(nodeMoved(Node*)), this, SLOT(slotLayoutChanged()) ); |
105 | } |
106 | reset(); |
107 | } |
108 | |
109 | void CriticalPathItemModel::setManager( ScheduleManager *sm ) |
110 | { |
111 | kDebug(planDbg())<<this; |
112 | m_manager = sm; |
113 | m_nodemodel.setManager( sm ); |
114 | if ( m_project == 0 || m_manager == 0 ) { |
115 | m_path.clear(); |
116 | } else { |
117 | m_path = m_project->criticalPath( m_manager->scheduleId(), 0 ); |
118 | } |
119 | kDebug(planDbg())<<m_path; |
120 | reset(); |
121 | } |
122 | |
123 | QModelIndex CriticalPathItemModel::parent( const QModelIndex & ) const |
124 | { |
125 | return QModelIndex(); |
126 | } |
127 | |
128 | QModelIndex CriticalPathItemModel::index( int row, int column, const QModelIndex &parent ) const |
129 | { |
130 | if ( m_project == 0 || column < 0 || column >= columnCount() || row < 0 ) { |
131 | return QModelIndex(); |
132 | } |
133 | if ( parent.isValid() ) { |
134 | return QModelIndex(); |
135 | } |
136 | Node *n = m_path.value( row ); |
137 | QModelIndex i = createIndex(row, column, n ); |
138 | return i; |
139 | } |
140 | |
141 | Duration::Unit CriticalPathItemModel::presentationUnit( const Duration &dur ) const |
142 | { |
143 | if ( dur.toDouble( Duration::Unit_d ) < 1.0 ) { |
144 | return Duration::Unit_h; |
145 | } |
146 | return Duration::Unit_d; |
147 | } |
148 | |
149 | QVariant CriticalPathItemModel::name( int role ) const |
150 | { |
151 | switch ( role ) { |
152 | case Qt::DisplayRole: |
153 | return i18n( "Path" ); |
154 | case Qt::ToolTipRole: |
155 | case Qt::EditRole: |
156 | case Qt::StatusTipRole: |
157 | case Qt::WhatsThisRole: |
158 | return QVariant(); |
159 | } |
160 | return QVariant(); |
161 | } |
162 | |
163 | QVariant CriticalPathItemModel::duration( int role ) const |
164 | { |
165 | switch ( role ) { |
166 | case Qt::DisplayRole: |
167 | case Qt::ToolTipRole: { |
168 | Duration v = m_project->duration( m_manager->scheduleId() ); |
169 | return QVariant(KGlobal::locale()->formatNumber( v.toDouble( presentationUnit( v ) ), 1 ) + Duration::unitToString( presentationUnit( v ) )); |
170 | } |
171 | case Qt::StatusTipRole: |
172 | case Qt::WhatsThisRole: |
173 | return QVariant(); |
174 | } |
175 | return QVariant(); |
176 | } |
177 | |
178 | QVariant CriticalPathItemModel::variance( int role ) const |
179 | { |
180 | switch ( role ) { |
181 | case Qt::DisplayRole: |
182 | case Qt::ToolTipRole: { |
183 | double v = 0.0; |
184 | foreach ( Node *n, m_path ) { |
185 | long id = m_manager->scheduleId(); |
186 | v += n->variance( id, presentationUnit( m_project->duration( id ) ) ); |
187 | } |
188 | return KGlobal::locale()->formatNumber( v, 1 ); |
189 | break; |
190 | } |
191 | case Qt::EditRole: { |
192 | double v = 0.0; |
193 | foreach ( Node *n, m_path ) { |
194 | v += n->variance( m_manager->scheduleId() ); |
195 | } |
196 | return v; |
197 | } |
198 | case Qt::StatusTipRole: |
199 | case Qt::WhatsThisRole: |
200 | return QVariant(); |
201 | } |
202 | return QVariant(); |
203 | } |
204 | |
205 | QVariant CriticalPathItemModel::notUsed( int role ) const |
206 | { |
207 | switch ( role ) { |
208 | case Qt::DisplayRole: |
209 | return "" ; |
210 | default: |
211 | return QVariant(); |
212 | } |
213 | return QVariant(); |
214 | } |
215 | |
216 | QVariant CriticalPathItemModel::data( const QModelIndex &index, int role ) const |
217 | { |
218 | QVariant result; |
219 | if ( ! index.isValid() ) { |
220 | return result; |
221 | } |
222 | if ( role == Qt::TextAlignmentRole ) { |
223 | return alignment( index.column() ); |
224 | } |
225 | Node *n = node( index ); |
226 | if ( n == 0 ) { |
227 | switch ( index.column() ) { |
228 | case NodeModel::NodeName: result = name( role ); break; |
229 | case NodeModel::NodeDuration: result = duration( role ); break; |
230 | case NodeModel::NodeVarianceDuration: result = variance( role ); break; |
231 | default: |
232 | result = notUsed( role ); break; |
233 | } |
234 | } else { |
235 | result = m_nodemodel.data( n, index.column(), role ); |
236 | } |
237 | if ( result.isValid() ) { |
238 | if ( role == Qt::DisplayRole && result.type() == QVariant::String && result.toString().isEmpty()) { |
239 | // HACK to show focus in empty cells |
240 | result = ' '; |
241 | } |
242 | return result; |
243 | } |
244 | return result; |
245 | } |
246 | |
247 | QVariant CriticalPathItemModel::( int section, Qt::Orientation orientation, int role ) const |
248 | { |
249 | if ( orientation == Qt::Horizontal ) { |
250 | if ( role == Qt::DisplayRole ) { |
251 | return m_nodemodel.headerData( section, role ); |
252 | } else if ( role == Qt::TextAlignmentRole ) { |
253 | return alignment( section ); |
254 | } |
255 | } |
256 | if ( role == Qt::ToolTipRole ) { |
257 | return m_nodemodel.headerData( section, role ); |
258 | } else if ( role == Qt::WhatsThisRole ) { |
259 | return m_nodemodel.headerData( section, role ); |
260 | } |
261 | return ItemModelBase::headerData(section, orientation, role); |
262 | } |
263 | |
264 | QVariant CriticalPathItemModel::alignment( int column ) const |
265 | { |
266 | return m_nodemodel.headerData( column, Qt::TextAlignmentRole ); |
267 | } |
268 | |
269 | int CriticalPathItemModel::columnCount( const QModelIndex & ) const |
270 | { |
271 | return m_nodemodel.propertyCount(); |
272 | } |
273 | |
274 | int CriticalPathItemModel::rowCount( const QModelIndex &parent ) const |
275 | { |
276 | if ( parent.isValid() ) { |
277 | return 0; |
278 | } |
279 | if ( m_manager && m_manager->expected() && m_manager->expected()->criticalPathList() ) { |
280 | return m_path.count() + 1; |
281 | } |
282 | return 0; |
283 | } |
284 | |
285 | Node *CriticalPathItemModel::node( const QModelIndex &index ) const |
286 | { |
287 | if ( ! index.isValid() ) { |
288 | return 0; |
289 | } |
290 | return m_path.value( index.row() ); |
291 | } |
292 | |
293 | void CriticalPathItemModel::slotNodeChanged( Node *node ) |
294 | { |
295 | kDebug(planDbg()); |
296 | if ( node == 0 || node->type() == Node::Type_Project || ! m_path.contains( node ) ) { |
297 | return; |
298 | } |
299 | int row = m_path.indexOf( node ); |
300 | emit dataChanged( createIndex( row, 0, node ), createIndex( row, columnCount() - 1, node ) ); |
301 | } |
302 | |
303 | |
304 | //----------------------------- |
305 | PertResultItemModel::PertResultItemModel( QObject *parent ) |
306 | : ItemModelBase( parent ), |
307 | m_manager( 0 ) |
308 | { |
309 | /* connect( this, SIGNAL(modelAboutToBeReset()), SLOT(slotAboutToBeReset()) ); |
310 | connect( this, SIGNAL(modelReset()), SLOT(slotReset()) );*/ |
311 | } |
312 | |
313 | PertResultItemModel::~PertResultItemModel() |
314 | { |
315 | } |
316 | |
317 | void PertResultItemModel::slotAboutToBeReset() |
318 | { |
319 | kDebug(planDbg()); |
320 | clear(); |
321 | } |
322 | |
323 | void PertResultItemModel::slotReset() |
324 | { |
325 | kDebug(planDbg()); |
326 | refresh(); |
327 | } |
328 | |
329 | void PertResultItemModel::slotNodeToBeInserted( Node *, int ) |
330 | { |
331 | //kDebug(planDbg())<<node->name(); |
332 | clear(); |
333 | } |
334 | |
335 | void PertResultItemModel::slotNodeInserted( Node * /*node*/ ) |
336 | { |
337 | //kDebug(planDbg())<<node->getParent->name()<<"-->"<<node->name(); |
338 | refresh(); |
339 | } |
340 | |
341 | void PertResultItemModel::slotNodeToBeRemoved( Node * /*node*/ ) |
342 | { |
343 | //kDebug(planDbg())<<node->name(); |
344 | clear(); |
345 | } |
346 | |
347 | void PertResultItemModel::slotNodeRemoved( Node * /*node*/ ) |
348 | { |
349 | //kDebug(planDbg())<<node->name(); |
350 | refresh(); |
351 | } |
352 | |
353 | void PertResultItemModel::setProject( Project *project ) |
354 | { |
355 | clear(); |
356 | if ( m_project ) { |
357 | disconnect( m_project, SIGNAL(nodeChanged(Node*)), this, SLOT(slotNodeChanged(Node*)) ); |
358 | disconnect( m_project, SIGNAL(nodeToBeAdded(Node*,int)), this, SLOT(slotNodeToBeInserted(Node*,int)) ); |
359 | disconnect( m_project, SIGNAL(nodeToBeRemoved(Node*)), this, SLOT(slotNodeToBeRemoved(Node*)) ); |
360 | disconnect( m_project, SIGNAL(nodeToBeMoved(Node*,int,Node*,int)), this, SLOT(slotLayoutToBeChanged()) ); |
361 | |
362 | disconnect( m_project, SIGNAL(nodeAdded(Node*)), this, SLOT(slotNodeInserted(Node*)) ); |
363 | disconnect( m_project, SIGNAL(nodeRemoved(Node*)), this, SLOT(slotNodeRemoved(Node*)) ); |
364 | disconnect( m_project, SIGNAL(nodeMoved(Node*)), this, SLOT(slotLayoutChanged()) ); |
365 | } |
366 | m_project = project; |
367 | m_nodemodel.setProject( project ); |
368 | if ( project ) { |
369 | connect( m_project, SIGNAL(nodeChanged(Node*)), this, SLOT(slotNodeChanged(Node*)) ); |
370 | connect( m_project, SIGNAL(nodeToBeAdded(Node*,int)), this, SLOT(slotNodeToBeInserted(Node*,int)) ); |
371 | connect( m_project, SIGNAL(nodeToBeRemoved(Node*)), this, SLOT(slotNodeToBeRemoved(Node*)) ); |
372 | connect( m_project, SIGNAL(nodeToBeMoved(Node*,int,Node*,int)), this, SLOT(slotLayoutToBeChanged()) ); |
373 | |
374 | connect( m_project, SIGNAL(nodeAdded(Node*)), this, SLOT(slotNodeInserted(Node*)) ); |
375 | connect( m_project, SIGNAL(nodeRemoved(Node*)), this, SLOT(slotNodeRemoved(Node*)) ); |
376 | connect( m_project, SIGNAL(nodeMoved(Node*)), this, SLOT(slotLayoutChanged()) ); |
377 | } |
378 | refresh(); |
379 | } |
380 | |
381 | void PertResultItemModel::setManager( ScheduleManager *sm ) |
382 | { |
383 | m_manager = sm; |
384 | m_nodemodel.setManager( sm ); |
385 | refresh(); |
386 | } |
387 | |
388 | void PertResultItemModel::clear() |
389 | { |
390 | kDebug(planDbg())<<this; |
391 | foreach ( NodeList *l, m_top ) { |
392 | int c = l->count(); |
393 | if ( c > 0 ) { |
394 | // FIXME: gives error msg: |
395 | // Can't select indexes from different model or with different parents |
396 | QModelIndex i = index( l ); |
397 | kDebug(planDbg())<<i<<": " <<c; |
398 | // beginRemoveRows( i, 0, c-1 ); |
399 | // endRemoveRows(); |
400 | } |
401 | } |
402 | m_critical.clear(); |
403 | m_noncritical.clear(); |
404 | if ( ! m_top.isEmpty() ) { |
405 | beginRemoveRows( QModelIndex(), 0, m_top.count() - 1 ); |
406 | m_top.clear(); |
407 | m_topNames.clear(); |
408 | endRemoveRows(); |
409 | } |
410 | } |
411 | |
412 | void PertResultItemModel::refresh() |
413 | { |
414 | clear(); |
415 | if ( m_project == 0 ) { |
416 | return; |
417 | } |
418 | long id = m_manager == 0 ? -1 : m_manager->scheduleId(); |
419 | kDebug(planDbg())<<id; |
420 | if ( id == -1 ) { |
421 | return; |
422 | } |
423 | m_topNames << i18n( "Project" ); |
424 | m_top << &m_dummyList; // dummy |
425 | const QList< NodeList > *lst = m_project->criticalPathList( id ); |
426 | if ( lst ) { |
427 | for ( int i = 0; i < lst->count(); ++i ) { |
428 | m_topNames << i18n( "Critical Path" ); |
429 | m_top.append( const_cast<NodeList*>( &( lst->at( i ) ) ) ); |
430 | kDebug(planDbg())<<m_topNames.last()<<lst->at( i ); |
431 | } |
432 | if ( lst->isEmpty() ) kDebug(planDbg())<<"No critical path" ; |
433 | } |
434 | foreach( Node* n, m_project->allNodes() ) { |
435 | if ( n->type() != Node::Type_Task && n->type() != Node::Type_Milestone ) { |
436 | continue; |
437 | } |
438 | Task *t = static_cast<Task*>( n ); |
439 | if ( t->inCriticalPath( id ) ) { |
440 | continue; |
441 | } else if ( t->isCritical( id ) ) { |
442 | m_critical.append( t ); |
443 | } else { |
444 | m_noncritical.append( t ); |
445 | } |
446 | } |
447 | if ( ! m_critical.isEmpty() ) { |
448 | m_topNames << i18n( "Critical" ); |
449 | m_top.append(&m_critical ); |
450 | } |
451 | if ( ! m_noncritical.isEmpty() ) { |
452 | m_topNames << i18n( "Non-critical" ); |
453 | m_top.append(&m_noncritical ); |
454 | } |
455 | if ( ! m_top.isEmpty() ) { |
456 | kDebug(planDbg())<<m_top; |
457 | beginInsertRows( QModelIndex(), 0, m_top.count() -1 ); |
458 | endInsertRows(); |
459 | foreach ( NodeList *l, m_top ) { |
460 | int c = l->count(); |
461 | if ( c > 0 ) { |
462 | beginInsertRows( index( l ), 0, c-1 ); |
463 | endInsertRows(); |
464 | } |
465 | } |
466 | } |
467 | } |
468 | |
469 | Qt::ItemFlags PertResultItemModel::flags( const QModelIndex &index ) const |
470 | { |
471 | Qt::ItemFlags flags = QAbstractItemModel::flags( index ); |
472 | flags &= ~( Qt::ItemIsEditable | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled ); |
473 | return flags; |
474 | } |
475 | |
476 | |
477 | QModelIndex PertResultItemModel::parent( const QModelIndex &index ) const |
478 | { |
479 | if ( !index.isValid() ) { |
480 | return QModelIndex(); |
481 | } |
482 | //kDebug(planDbg())<<index.internalPointer()<<": "<<index.row()<<", "<<index.column(); |
483 | int row = index.internalId(); |
484 | if ( row < 0 ) { |
485 | return QModelIndex(); // top level has no parent |
486 | } |
487 | if ( m_top.value( row ) == 0 ) { |
488 | return QModelIndex(); |
489 | } |
490 | return createIndex( row, 0, -1 ); |
491 | } |
492 | |
493 | QModelIndex PertResultItemModel::index( int row, int column, const QModelIndex &parent ) const |
494 | { |
495 | if ( m_project == 0 || column < 0 || column >= columnCount() || row < 0 ) { |
496 | return QModelIndex(); |
497 | } |
498 | if ( ! parent.isValid() ) { |
499 | if ( row == 0 ) { |
500 | QModelIndex idx = createIndex(row, column, -2 ); // project |
501 | return idx; |
502 | } |
503 | if ( row >= m_top.count() ) { |
504 | return QModelIndex(); // shouldn't happend |
505 | } |
506 | QModelIndex idx = createIndex(row, column, -1 ); |
507 | //kDebug(planDbg())<<parent<<", "<<idx; |
508 | return idx; |
509 | } |
510 | if ( parent.row() == 0 ) { |
511 | return QModelIndex(); |
512 | } |
513 | NodeList *l = m_top.value( parent.row() ); |
514 | if ( l == 0 ) { |
515 | return QModelIndex(); |
516 | } |
517 | QModelIndex i = createIndex(row, column, parent.row() ); |
518 | return i; |
519 | } |
520 | |
521 | // QModelIndex PertResultItemModel::index( const Node *node ) const |
522 | // { |
523 | // if ( m_project == 0 || node == 0 ) { |
524 | // return QModelIndex(); |
525 | // } |
526 | // foreach( NodeList *l, m_top ) { |
527 | // int row = l->indexOf( const_cast<Node*>( node ) ); |
528 | // if ( row != -1 ) { |
529 | // return createIndex( row, 0, const_cast<Node*>( node ) ); |
530 | // } |
531 | // } |
532 | // return QModelIndex(); |
533 | // } |
534 | |
535 | QModelIndex PertResultItemModel::index( const NodeList *lst ) const |
536 | { |
537 | if ( m_project == 0 || lst == 0 ) { |
538 | return QModelIndex(); |
539 | } |
540 | NodeList *l = const_cast<NodeList*>( lst ); |
541 | int row = m_top.indexOf( l ); |
542 | if ( row <= 0 ) { |
543 | return QModelIndex(); |
544 | } |
545 | return createIndex( row, 0, -1 ); |
546 | } |
547 | |
548 | QVariant PertResultItemModel::name( int row, int role ) const |
549 | { |
550 | |
551 | switch ( role ) { |
552 | case Qt::DisplayRole: |
553 | case Qt::EditRole: |
554 | case Qt::ToolTipRole: |
555 | return m_topNames.value( row ); |
556 | case Qt::StatusTipRole: |
557 | case Qt::WhatsThisRole: |
558 | return QVariant(); |
559 | } |
560 | return QVariant(); |
561 | } |
562 | |
563 | QVariant PertResultItemModel::name( const Node *node, int role ) const |
564 | { |
565 | switch ( role ) { |
566 | case Qt::DisplayRole: |
567 | case Qt::EditRole: |
568 | case Qt::ToolTipRole: |
569 | return node->name(); |
570 | case Qt::StatusTipRole: |
571 | case Qt::WhatsThisRole: |
572 | return QVariant(); |
573 | } |
574 | return QVariant(); |
575 | } |
576 | |
577 | QVariant PertResultItemModel::earlyStart( const Task *node, int role ) const |
578 | { |
579 | switch ( role ) { |
580 | case Qt::DisplayRole: |
581 | return node->earlyStart( m_manager->scheduleId() ); |
582 | case Qt::ToolTipRole: |
583 | return KGlobal::locale()->formatDate( node->earlyStart( m_manager->scheduleId() ).date() ); |
584 | case Qt::EditRole: |
585 | case Qt::StatusTipRole: |
586 | case Qt::WhatsThisRole: |
587 | return QVariant(); |
588 | } |
589 | return QVariant(); |
590 | } |
591 | |
592 | QVariant PertResultItemModel::earlyFinish( const Task *node, int role ) const |
593 | { |
594 | switch ( role ) { |
595 | case Qt::DisplayRole: |
596 | return node->earlyFinish( m_manager->scheduleId() ); |
597 | case Qt::ToolTipRole: |
598 | return KGlobal::locale()->formatDate( node->earlyFinish( m_manager->scheduleId() ).date() ); |
599 | case Qt::EditRole: |
600 | case Qt::StatusTipRole: |
601 | case Qt::WhatsThisRole: |
602 | return QVariant(); |
603 | } |
604 | return QVariant(); |
605 | } |
606 | |
607 | QVariant PertResultItemModel::lateStart( const Task *node, int role ) const |
608 | { |
609 | switch ( role ) { |
610 | case Qt::DisplayRole: |
611 | return node->lateStart( m_manager->scheduleId() ); |
612 | case Qt::ToolTipRole: |
613 | return KGlobal::locale()->formatDate( node->lateStart( m_manager->scheduleId() ).date() ); |
614 | case Qt::EditRole: |
615 | break; |
616 | case Qt::StatusTipRole: |
617 | case Qt::WhatsThisRole: |
618 | return QVariant(); |
619 | } |
620 | return QVariant(); |
621 | } |
622 | |
623 | QVariant PertResultItemModel::lateFinish( const Task *node, int role ) const |
624 | { |
625 | switch ( role ) { |
626 | case Qt::DisplayRole: |
627 | return node->lateFinish( m_manager->scheduleId() ); |
628 | case Qt::ToolTipRole: |
629 | return KGlobal::locale()->formatDate( node->lateFinish( m_manager->scheduleId() ).date() ); |
630 | case Qt::EditRole: |
631 | break; |
632 | case Qt::StatusTipRole: |
633 | case Qt::WhatsThisRole: |
634 | return QVariant(); |
635 | } |
636 | return QVariant(); |
637 | } |
638 | |
639 | QVariant PertResultItemModel::positiveFloat( const Task *node, int role ) const |
640 | { |
641 | switch ( role ) { |
642 | case Qt::DisplayRole: |
643 | return node->positiveFloat( m_manager->scheduleId() ).toString( Duration::Format_i18nHourFraction ); |
644 | case Qt::ToolTipRole: |
645 | return node->positiveFloat( m_manager->scheduleId() ).toString( Duration::Format_i18nDayTime ); |
646 | case Qt::EditRole: |
647 | case Qt::StatusTipRole: |
648 | case Qt::WhatsThisRole: |
649 | return QVariant(); |
650 | } |
651 | return QVariant(); |
652 | } |
653 | |
654 | QVariant PertResultItemModel::freeFloat( const Task *node, int role ) const |
655 | { |
656 | switch ( role ) { |
657 | case Qt::DisplayRole: |
658 | return node->freeFloat( m_manager->scheduleId() ).toString( Duration::Format_i18nHourFraction ); |
659 | case Qt::ToolTipRole: |
660 | return node->freeFloat( m_manager->scheduleId() ).toString( Duration::Format_i18nDayTime ); |
661 | case Qt::EditRole: |
662 | case Qt::StatusTipRole: |
663 | case Qt::WhatsThisRole: |
664 | return QVariant(); |
665 | } |
666 | return QVariant(); |
667 | } |
668 | |
669 | QVariant PertResultItemModel::negativeFloat( const Task *node, int role ) const |
670 | { |
671 | switch ( role ) { |
672 | case Qt::DisplayRole: |
673 | return node->negativeFloat( m_manager->scheduleId() ).toString( Duration::Format_i18nHourFraction ); |
674 | case Qt::ToolTipRole: |
675 | return node->negativeFloat( m_manager->scheduleId() ).toString( Duration::Format_i18nDayTime ); |
676 | case Qt::EditRole: |
677 | case Qt::StatusTipRole: |
678 | case Qt::WhatsThisRole: |
679 | return QVariant(); |
680 | } |
681 | return QVariant(); |
682 | } |
683 | |
684 | QVariant PertResultItemModel::startFloat( const Task *node, int role ) const |
685 | { |
686 | switch ( role ) { |
687 | case Qt::DisplayRole: |
688 | return node->startFloat( m_manager->scheduleId() ).toString( Duration::Format_i18nHourFraction ); |
689 | case Qt::ToolTipRole: |
690 | return node->startFloat( m_manager->scheduleId() ).toString( Duration::Format_i18nDayTime ); |
691 | case Qt::EditRole: |
692 | case Qt::StatusTipRole: |
693 | case Qt::WhatsThisRole: |
694 | return QVariant(); |
695 | } |
696 | return QVariant(); |
697 | } |
698 | |
699 | QVariant PertResultItemModel::finishFloat( const Task *node, int role ) const |
700 | { |
701 | switch ( role ) { |
702 | case Qt::DisplayRole: |
703 | return node->finishFloat( m_manager->scheduleId() ).toString( Duration::Format_i18nHourFraction ); |
704 | case Qt::ToolTipRole: |
705 | return node->finishFloat( m_manager->scheduleId() ).toString( Duration::Format_i18nDayTime ); |
706 | case Qt::EditRole: |
707 | case Qt::StatusTipRole: |
708 | case Qt::WhatsThisRole: |
709 | return QVariant(); |
710 | } |
711 | return QVariant(); |
712 | } |
713 | |
714 | QVariant PertResultItemModel::data( const QModelIndex &index, int role ) const |
715 | { |
716 | QVariant result; |
717 | if ( ! index.isValid() ) { |
718 | return result; |
719 | } |
720 | if ( role == Qt::TextAlignmentRole ) { |
721 | return alignment( index.column() ); |
722 | } |
723 | Node *n = node( index ); |
724 | if ( n == 0 ) { |
725 | switch ( index.column() ) { |
726 | case 0: return name( index.row(), role ); |
727 | default: break; |
728 | } |
729 | return QVariant(); |
730 | } |
731 | if ( n->type() == Node::Type_Task || n->type() == Node::Type_Milestone ) { |
732 | result = m_nodemodel.data( n, index.column(), role ); |
733 | } |
734 | if ( n->type() == Node::Type_Project ) { |
735 | //Project *p = static_cast<Project*>( n ); |
736 | switch ( index.column() ) { |
737 | case NodeModel::NodeName: result = name( NodeModel::NodeName, role ); break; |
738 | default: |
739 | //kDebug(planDbg())<<"data: invalid display value column "<<index.column(); |
740 | return QVariant(); |
741 | } |
742 | } |
743 | if ( result.isValid() ) { |
744 | if ( role == Qt::DisplayRole && result.type() == QVariant::String && result.toString().isEmpty()) { |
745 | // HACK to show focus in empty cells |
746 | result = ' '; |
747 | } |
748 | return result; |
749 | } |
750 | return QVariant(); |
751 | } |
752 | |
753 | QVariant PertResultItemModel::( int section, Qt::Orientation orientation, int role ) const |
754 | { |
755 | if ( orientation == Qt::Horizontal ) { |
756 | if ( role == Qt::DisplayRole ) { |
757 | return m_nodemodel.headerData( section, role ); |
758 | } else if ( role == Qt::TextAlignmentRole ) { |
759 | return alignment( section ); |
760 | } |
761 | } |
762 | if ( role == Qt::ToolTipRole ) { |
763 | return m_nodemodel.headerData( section, role ); |
764 | } else if ( role == Qt::WhatsThisRole ) { |
765 | return m_nodemodel.headerData( section, role ); |
766 | } |
767 | return ItemModelBase::headerData(section, orientation, role); |
768 | } |
769 | |
770 | QVariant PertResultItemModel::alignment( int column ) const |
771 | { |
772 | return m_nodemodel.headerData( column, Qt::TextAlignmentRole ); |
773 | } |
774 | |
775 | QAbstractItemDelegate *PertResultItemModel::createDelegate( int column, QWidget * /*parent*/ ) const |
776 | { |
777 | switch ( column ) { |
778 | default: return 0; |
779 | } |
780 | return 0; |
781 | } |
782 | |
783 | int PertResultItemModel::columnCount( const QModelIndex & ) const |
784 | { |
785 | return m_nodemodel.propertyCount(); |
786 | } |
787 | |
788 | int PertResultItemModel::rowCount( const QModelIndex &parent ) const |
789 | { |
790 | if ( ! parent.isValid() ) { |
791 | //kDebug(planDbg())<<"top="<<m_top.count(); |
792 | return m_top.count(); |
793 | } |
794 | NodeList *l = list( parent ); |
795 | if ( l ) { |
796 | //kDebug(planDbg())<<"list "<<parent.row()<<": "<<l->count(); |
797 | return l->count(); |
798 | } |
799 | //kDebug(planDbg())<<"node "<<parent.row(); |
800 | return 0; // nodes don't have children |
801 | } |
802 | |
803 | Qt::DropActions PertResultItemModel::supportedDropActions() const |
804 | { |
805 | return (Qt::DropActions)Qt::CopyAction | Qt::MoveAction; |
806 | } |
807 | |
808 | |
809 | QStringList PertResultItemModel::mimeTypes() const |
810 | { |
811 | return QStringList(); |
812 | } |
813 | |
814 | QMimeData *PertResultItemModel::mimeData( const QModelIndexList & ) const |
815 | { |
816 | QMimeData *m = new QMimeData(); |
817 | return m; |
818 | } |
819 | |
820 | bool PertResultItemModel::dropAllowed( Node *, const QMimeData * ) |
821 | { |
822 | return false; |
823 | } |
824 | |
825 | bool PertResultItemModel::dropMimeData( const QMimeData *, Qt::DropAction , int , int , const QModelIndex & ) |
826 | { |
827 | return false; |
828 | } |
829 | |
830 | NodeList *PertResultItemModel::list( const QModelIndex &index ) const |
831 | { |
832 | if ( index.isValid() && index.internalId() == -1 ) { |
833 | //kDebug(planDbg())<<index<<"is list: "<<m_top.value( index.row() ); |
834 | return m_top.value( index.row() ); |
835 | } |
836 | //kDebug(planDbg())<<index<<"is not list"; |
837 | return 0; |
838 | } |
839 | |
840 | Node *PertResultItemModel::node( const QModelIndex &index ) const |
841 | { |
842 | if ( ! index.isValid() ) { |
843 | return 0; |
844 | } |
845 | if ( index.internalId() == -2 ) { |
846 | return m_project; |
847 | } |
848 | if ( index.internalId() == 0 ) { |
849 | return 0; |
850 | } |
851 | NodeList *l = m_top.value( index.internalId() ); |
852 | if ( l ) { |
853 | return l->value( index.row() ); |
854 | } |
855 | return 0; |
856 | } |
857 | |
858 | void PertResultItemModel::slotNodeChanged( Node *) |
859 | { |
860 | kDebug(planDbg()); |
861 | refresh(); |
862 | /* if ( node == 0 || node->type() == Node::Type_Project ) { |
863 | return; |
864 | } |
865 | int row = node->getParent()->findChildNode( node ); |
866 | emit dataChanged( createIndex( row, 0, node ), createIndex( row, columnCount() - 1, node ) );*/ |
867 | } |
868 | |
869 | |
870 | } // namespace KPlato |
871 | |
872 | #include "kptpertcpmmodel.moc" |
873 | |