1/* This file is part of the KDE project
2 Copyright (C) 2007, 2011, 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 "kptresourceappointmentsmodel.h"
21
22#include "kptglobal.h"
23#include "kptcommonstrings.h"
24#include "kptappointment.h"
25#include "kptcommand.h"
26#include "kpteffortcostmap.h"
27#include "kptitemmodelbase.h"
28#include "kptcalendar.h"
29#include "kptduration.h"
30#include "kptnode.h"
31#include "kptproject.h"
32#include "kpttask.h"
33#include "kptresource.h"
34#include "kptdatetime.h"
35#include "kptdebug.h"
36
37#include <QDate>
38#include <QList>
39#include <QObject>
40#include <QStringList>
41
42
43#include <kglobal.h>
44#include <klocale.h>
45
46#include "kdganttglobal.h"
47
48
49namespace KPlato
50{
51
52ResourceAppointmentsItemModel::ResourceAppointmentsItemModel( QObject *parent )
53 : ItemModelBase( parent ),
54 m_group( 0 ),
55 m_resource( 0 ),
56 m_showInternal( true ),
57 m_showExternal( true )
58{
59}
60
61ResourceAppointmentsItemModel::~ResourceAppointmentsItemModel()
62{
63}
64
65void ResourceAppointmentsItemModel::slotResourceToBeInserted( const ResourceGroup *group, int row )
66{
67 kDebug(planDbg())<<group->name()<<row;
68 Q_ASSERT( m_group == 0 );
69 m_group = const_cast<ResourceGroup*>(group);
70 QModelIndex i = index( group );
71 beginInsertRows( i, row, row );
72}
73
74void ResourceAppointmentsItemModel::slotResourceInserted( const Resource *r )
75{
76 kDebug(planDbg())<<r->name();
77 Q_ASSERT( r->parentGroup() == m_group );
78 endInsertRows();
79 m_group = 0;
80 refresh();
81 connect( r, SIGNAL(externalAppointmentToBeAdded(Resource*,int)), this, SLOT(slotAppointmentToBeInserted(Resource*,int)) );
82 connect( r, SIGNAL(externalAppointmentAdded(Resource*,Appointment*)), this, SLOT(slotAppointmentInserted(Resource*,Appointment*)) );
83 connect( r, SIGNAL(externalAppointmentToBeRemoved(Resource*,int)), this, SLOT(slotAppointmentToBeRemoved(Resource*,int)) );
84 connect( r, SIGNAL(externalAppointmentRemoved()), this, SLOT(slotAppointmentRemoved()) );
85 connect( r, SIGNAL(externalAppointmentChanged(Resource*,Appointment*)), this, SLOT(slotAppointmentChanged(Resource*,Appointment*)) );
86}
87
88void ResourceAppointmentsItemModel::slotResourceToBeRemoved( const Resource *r )
89{
90 kDebug(planDbg())<<r->name();
91 int row = r->parentGroup()->indexOf( r );
92 beginRemoveRows( index( r->parentGroup() ), row, row );
93 disconnect( r, SIGNAL(externalAppointmentToBeAdded(Resource*,int)), this, SLOT(slotAppointmentToBeInserted(Resource*,int)) );
94 disconnect( r, SIGNAL(externalAppointmentAdded(Resource*,Appointment*)), this, SLOT(slotAppointmentInserted(Resource*,Appointment*)) );
95 disconnect( r, SIGNAL(externalAppointmentToBeRemoved(Resource*,int)), this, SLOT(slotAppointmentToBeRemoved(Resource*,int)) );
96 disconnect( r, SIGNAL(externalAppointmentRemoved()), this, SLOT(slotAppointmentRemoved()) );
97 disconnect( r, SIGNAL(externalAppointmentChanged(Resource*,Appointment*)), this, SLOT(slotAppointmentChanged(Resource*,Appointment*)) );
98
99}
100
101void ResourceAppointmentsItemModel::slotResourceRemoved( const Resource *resource )
102{
103 Q_UNUSED(resource);
104 //kDebug(planDbg())<<resource->name();
105 endRemoveRows();
106 refresh();
107}
108
109void ResourceAppointmentsItemModel::slotResourceGroupToBeInserted( const ResourceGroup *group, int row )
110{
111 //kDebug(planDbg())<<group->name()<<endl;
112 Q_ASSERT( m_group == 0 );
113 m_group = const_cast<ResourceGroup*>(group);
114 beginInsertRows( QModelIndex(), row, row );
115}
116
117void ResourceAppointmentsItemModel::slotResourceGroupInserted( const ResourceGroup *group )
118{
119 //kDebug(planDbg())<<group->name()<<endl;
120 Q_ASSERT( group == m_group ); Q_UNUSED( group );
121 endInsertRows();
122 m_group = 0;
123}
124
125void ResourceAppointmentsItemModel::slotResourceGroupToBeRemoved( const ResourceGroup *group )
126{
127 //kDebug(planDbg())<<group->name()<<endl;
128 Q_ASSERT( m_group == 0 );
129 m_group = const_cast<ResourceGroup*>(group);
130 int row = index( group ).row();
131 beginRemoveRows( QModelIndex(), row, row );
132}
133
134void ResourceAppointmentsItemModel::slotResourceGroupRemoved( const ResourceGroup *group )
135{
136 //kDebug(planDbg())<<group->name()<<endl;
137 Q_ASSERT( group == m_group ); Q_UNUSED( group );
138 endRemoveRows();
139 m_group = 0;
140}
141
142void ResourceAppointmentsItemModel::slotAppointmentToBeInserted( Resource *r, int row )
143{
144 Q_UNUSED(r);
145 Q_UNUSED(row);
146}
147
148void ResourceAppointmentsItemModel::slotAppointmentInserted( Resource *r, Appointment *a )
149{
150 Q_UNUSED(r);
151 Q_UNUSED(a);
152 refreshData();
153 reset();
154}
155
156void ResourceAppointmentsItemModel::slotAppointmentToBeRemoved( Resource *r, int row )
157{
158 Q_UNUSED(r);
159 Q_UNUSED(row);
160}
161
162void ResourceAppointmentsItemModel::slotAppointmentRemoved()
163{
164 refreshData();
165 reset();
166}
167
168void ResourceAppointmentsItemModel::slotAppointmentChanged( Resource *r, Appointment *a )
169{
170 int row = rowNumber( r, a );
171 Q_ASSERT( row >= 0 );
172 refreshData();
173 emit dataChanged( createExternalAppointmentIndex( row, 0, a ), createExternalAppointmentIndex( row, columnCount() - 1, a ) );
174}
175
176void ResourceAppointmentsItemModel::slotProjectCalculated( ScheduleManager *sm )
177{
178 if ( sm == m_manager ) {
179 setScheduleManager( sm );
180 }
181}
182
183int ResourceAppointmentsItemModel::rowNumber( Resource *res, Appointment *a ) const
184{
185 int r = 0;
186 if ( m_showInternal ) {
187 r = res->appointments( id() ).indexOf( a );
188 if ( r > -1 ) {
189 return r;
190 }
191 r = res->numAppointments();
192 }
193 if ( m_showExternal ) {
194 int rr = res->externalAppointmentList().indexOf( a );
195 if ( rr > -1 ) {
196 return r + rr;
197 }
198 }
199 return -1;
200}
201
202void ResourceAppointmentsItemModel::setShowInternalAppointments( bool show )
203{
204 if ( m_showInternal == show ) {
205 return;
206 }
207 m_showInternal = show;
208 refreshData();
209 reset();
210}
211
212void ResourceAppointmentsItemModel::setShowExternalAppointments( bool show )
213{
214 if ( m_showExternal == show ) {
215 return;
216 }
217 m_showExternal = show;
218 refreshData();
219 reset();
220}
221
222void ResourceAppointmentsItemModel::setProject( Project *project )
223{
224 kDebug(planDbg());
225 if ( m_project ) {
226 disconnect( m_project, SIGNAL(resourceChanged(Resource*)), this, SLOT(slotResourceChanged(Resource*)) );
227 disconnect( m_project, SIGNAL(resourceGroupChanged(ResourceGroup*)), this, SLOT(slotResourceGroupChanged(ResourceGroup*)) );
228
229 disconnect( m_project, SIGNAL(resourceGroupToBeAdded(const ResourceGroup*,int)), this, SLOT(slotResourceGroupToBeInserted(const ResourceGroup*,int)) );
230
231 disconnect( m_project, SIGNAL(resourceGroupToBeRemoved(const ResourceGroup*)), this, SLOT(slotResourceGroupToBeRemoved(const ResourceGroup*)) );
232
233 disconnect( m_project, SIGNAL(resourceToBeAdded(const ResourceGroup*,int)), this, SLOT(slotResourceToBeInserted(const ResourceGroup*,int)) );
234
235 disconnect( m_project, SIGNAL(resourceToBeRemoved(const Resource*)), this, SLOT(slotResourceToBeRemoved(const Resource*)) );
236
237 disconnect( m_project, SIGNAL(resourceGroupAdded(const ResourceGroup*)), this, SLOT(slotResourceGroupInserted(const ResourceGroup*)) );
238
239 disconnect( m_project, SIGNAL(resourceGroupRemoved(const ResourceGroup*)), this, SLOT(slotResourceGroupRemoved(const ResourceGroup*)) );
240
241 disconnect( m_project, SIGNAL(resourceAdded(const Resource*)), this, SLOT(slotResourceInserted(const Resource*)) );
242
243 disconnect( m_project, SIGNAL(resourceRemoved(const Resource*)), this, SLOT(slotResourceRemoved(const Resource*)) );
244
245 disconnect( m_project, SIGNAL(defaultCalendarChanged(Calendar*)), this, SLOT(slotCalendarChanged(Calendar*)) );
246
247 disconnect( m_project, SIGNAL(projectCalculated(ScheduleManager*)), this, SLOT(slotProjectCalculated(ScheduleManager*)) );
248
249 disconnect( m_project, SIGNAL(scheduleManagerChanged(ScheduleManager*)), this, SLOT(slotProjectCalculated(ScheduleManager*)) );
250
251 foreach ( Resource *r, m_project->resourceList() ) {
252 disconnect( r, SIGNAL(externalAppointmentToBeAdded(Resource*,int)), this, SLOT(slotAppointmentToBeInserted(Resource*,int)) );
253 disconnect( r, SIGNAL(externalAppointmentAdded(Resource*,Appointment*)), this, SLOT(slotAppointmentInserted(Resource*,Appointment*)) );
254 disconnect( r, SIGNAL(externalAppointmentToBeRemoved(Resource*,int)), this, SLOT(slotAppointmentToBeRemoved(Resource*,int)) );
255 disconnect( r, SIGNAL(externalAppointmentRemoved()), this, SLOT(slotAppointmentRemoved()) );
256 disconnect( r, SIGNAL(externalAppointmentChanged(Resource*,Appointment*)), this, SLOT(slotAppointmentChanged(Resource*,Appointment*)) );
257 }
258 }
259 m_project = project;
260 if ( m_project ) {
261 connect( m_project, SIGNAL(resourceChanged(Resource*)), this, SLOT(slotResourceChanged(Resource*)) );
262 connect( m_project, SIGNAL(resourceGroupChanged(ResourceGroup*)), this, SLOT(slotResourceGroupChanged(ResourceGroup*)) );
263
264 connect( m_project, SIGNAL(resourceGroupToBeAdded(const ResourceGroup*,int)), this, SLOT(slotResourceGroupToBeInserted(const ResourceGroup*,int)) );
265
266 connect( m_project, SIGNAL(resourceGroupToBeRemoved(const ResourceGroup*)), this, SLOT(slotResourceGroupToBeRemoved(const ResourceGroup*)) );
267
268 connect( m_project, SIGNAL(resourceToBeAdded(const ResourceGroup*,int)), this, SLOT(slotResourceToBeInserted(const ResourceGroup*,int)) );
269
270 connect( m_project, SIGNAL(resourceToBeRemoved(const Resource*)), this, SLOT(slotResourceToBeRemoved(const Resource*)) );
271
272 connect( m_project, SIGNAL(resourceGroupAdded(const ResourceGroup*)), this, SLOT(slotResourceGroupInserted(const ResourceGroup*)) );
273
274 connect( m_project, SIGNAL(resourceGroupRemoved(const ResourceGroup*)), this, SLOT(slotResourceGroupRemoved(const ResourceGroup*)) );
275
276 connect( m_project, SIGNAL(resourceAdded(const Resource*)), this, SLOT(slotResourceInserted(const Resource*)) );
277
278 connect( m_project, SIGNAL(resourceRemoved(const Resource*)), this, SLOT(slotResourceRemoved(const Resource*)) );
279
280 connect( m_project, SIGNAL(defaultCalendarChanged(Calendar*)), this, SLOT(slotCalendarChanged(Calendar*)) );
281
282 connect( m_project, SIGNAL(projectCalculated(ScheduleManager*)), this, SLOT(slotProjectCalculated(ScheduleManager*)) );
283
284 connect( m_project, SIGNAL(scheduleManagerChanged(ScheduleManager*)), this, SLOT(slotProjectCalculated(ScheduleManager*)) );
285
286 foreach ( Resource *r, m_project->resourceList() ) {
287 connect( r, SIGNAL(externalAppointmentToBeAdded(Resource*,int)), this, SLOT(slotAppointmentToBeInserted(Resource*,int)) );
288 connect( r, SIGNAL(externalAppointmentAdded(Resource*,Appointment*)), this, SLOT(slotAppointmentInserted(Resource*,Appointment*)) );
289 connect( r, SIGNAL(externalAppointmentToBeRemoved(Resource*,int)), this, SLOT(slotAppointmentToBeRemoved(Resource*,int)) );
290 connect( r, SIGNAL(externalAppointmentRemoved()), this, SLOT(slotAppointmentRemoved()) );
291 connect( r, SIGNAL(externalAppointmentChanged(Resource*,Appointment*)), this, SLOT(slotAppointmentChanged(Resource*,Appointment*)) );
292 }
293 }
294 refreshData();
295 reset();
296 emit refreshed();
297}
298
299QDate ResourceAppointmentsItemModel::startDate() const
300{
301 if ( m_project && m_manager ) {
302 return m_project->startTime( id() ).date();
303 }
304 return QDate::currentDate();
305}
306
307QDate ResourceAppointmentsItemModel::endDate() const
308{
309 if ( m_project && m_manager ) {
310 return m_project->endTime( id() ).date();
311 }
312 return QDate::currentDate();
313}
314
315void ResourceAppointmentsItemModel::setScheduleManager( ScheduleManager *sm )
316{
317 kDebug(planDbg())<<sm;
318 m_manager = sm;
319 refreshData();
320 reset();
321 emit refreshed();
322}
323
324long ResourceAppointmentsItemModel::id() const
325{
326 return m_manager == 0 ? -1 : m_manager->scheduleId();
327}
328
329Qt::ItemFlags ResourceAppointmentsItemModel::flags( const QModelIndex &index ) const
330{
331 Qt::ItemFlags flags = ItemModelBase::flags( index );
332 return flags &= ~Qt::ItemIsEditable;
333}
334
335
336QModelIndex ResourceAppointmentsItemModel::parent( const QModelIndex &idx ) const
337{
338 if ( !idx.isValid() || m_project == 0 || m_manager == 0 ) {
339 kWarning()<<"No data "<<idx;
340 return QModelIndex();
341 }
342
343 QModelIndex p;
344 if ( ! p.isValid() ) {
345 Resource *r = resource( idx );
346 if ( r ) {
347 int row = m_project->indexOf( r->parentGroup() );
348 p = createGroupIndex( row, 0, r->parentGroup() );
349 //kDebug(planDbg())<<"Parent:"<<p<<r->parentGroup()->name();
350 Q_ASSERT( p.isValid() );
351 }
352 }
353 if ( ! p.isValid() && m_showInternal ) {
354 Appointment *a = appointment( idx );
355 if ( a && a->resource() && a->resource()->resource() ) {
356 Resource *r = a->resource()->resource();
357 int row = r->parentGroup()->indexOf( r );
358 p = createResourceIndex( row, 0, r );
359 //kDebug(planDbg())<<"Parent:"<<p<<r->name();
360 Q_ASSERT( p.isValid() );
361 }
362 }
363 if ( ! p.isValid() && m_showExternal ) {
364 Appointment *a = externalAppointment( idx );
365 Resource *r = parent( a );
366 if ( r ) {
367 int row = r->parentGroup()->indexOf( r );
368 p = createResourceIndex( row, 0, r );
369 }
370 }
371 if ( ! p.isValid() ) {
372 //kDebug(planDbg())<<"Parent:"<<p;
373 }
374 //kDebug(planDbg())<<"Child :"<<idx;
375 return p;
376}
377
378Resource *ResourceAppointmentsItemModel::parent( const Appointment *a ) const
379{
380 if ( a == 0 || m_project == 0 ) {
381 return 0;
382 }
383 foreach ( Resource *r, m_project->resourceList() ) {
384 if ( r->appointments( id() ).contains( const_cast<Appointment*>( a ) ) ) {
385 return r;
386 }
387 if ( r->externalAppointmentList().contains( const_cast<Appointment*>( a ) ) ) {
388 return r;
389 }
390 }
391 return 0;
392}
393
394QModelIndex ResourceAppointmentsItemModel::index( int row, int column, const QModelIndex &parent ) const
395{
396 if ( m_project == 0 || m_manager == 0 ) {
397 return QModelIndex();
398 }
399 if ( ! parent.isValid() ) {
400 if ( row < m_project->numResourceGroups() ) {
401 //kDebug(planDbg())<<"Group: "<<m_project->resourceGroupAt( row )<<endl;
402 return createGroupIndex( row, column, m_project->resourceGroupAt( row ) );
403 }
404 return QModelIndex();
405 }
406 ResourceGroup *g = resourcegroup( parent );
407 if ( g ) {
408 if ( row < g->numResources() ) {
409 //kDebug(planDbg())<<"Resource: "<<g->resourceAt( row )<<endl;
410 return createResourceIndex( row, column, g->resourceAt( row ) );
411 }
412 return QModelIndex();
413 }
414 Resource *r = resource( parent );
415 if ( r && ( m_showInternal || m_showExternal ) ) {
416 int num = m_showInternal ? r->numAppointments( id() ) : 0;
417 if ( row < num ) {
418 //kDebug(planDbg())<<"Appointment: "<<r->appointmentAt( row, m_manager->scheduleId() );
419 return createAppointmentIndex( row, column, r->appointmentAt( row, id() ) );
420 }
421 int extRow = row - num;
422 //kDebug(planDbg())<<"Appointment: "<<r->externalAppointmentList().value( extRow );
423 Q_ASSERT( extRow >= 0 && extRow < r->externalAppointmentList().count() );
424 return createExternalAppointmentIndex( row, column, r->externalAppointmentList().value( extRow ) );
425 }
426 return QModelIndex();
427}
428
429QModelIndex ResourceAppointmentsItemModel::index( const Resource *resource ) const
430{
431 if ( m_project == 0 || resource == 0 ) {
432 return QModelIndex();
433 }
434 Resource *r = const_cast<Resource*>(resource);
435 int row = -1;
436 ResourceGroup *par = r->parentGroup();
437 if ( par ) {
438 row = par->indexOf( r );
439 return createResourceIndex( row, 0, r );
440 }
441 return QModelIndex();
442}
443
444QModelIndex ResourceAppointmentsItemModel::index( const ResourceGroup *group ) const
445{
446 if ( m_project == 0 || group == 0 ) {
447 return QModelIndex();
448 }
449 ResourceGroup *g = const_cast<ResourceGroup*>(group);
450 int row = m_project->indexOf( g );
451 return createGroupIndex( row, 0, g );
452
453}
454
455void ResourceAppointmentsItemModel::refresh()
456{
457 refreshData();
458 emit refreshed();
459}
460
461void ResourceAppointmentsItemModel::refreshData()
462{
463 long id = m_manager == 0 ? -1 : m_manager->scheduleId();
464 //kDebug(planDbg())<<"Schedule id: "<<id<<endl;
465 QDate start;
466 QDate end;
467 QMap<const Appointment*, EffortCostMap> ec;
468 QMap<const Appointment*, EffortCostMap> extEff;
469 foreach ( Resource *r, m_project->resourceList() ) {
470 foreach (Appointment* a, r->appointments( id )) {
471 QDate s = a->startTime().date();
472 QDate e = a->endTime().date();
473 ec[ a ] = a->plannedPrDay( s, e );
474 if ( ! start.isValid() || s < start ) {
475 start = s;
476 }
477 if ( ! end.isValid() || e > end ) {
478 end = e;
479 }
480 //kDebug(planDbg())<<a->node()->node()->name()<<": "<<s<<e<<": "<<m_effortMap[ a ].totalEffort().toDouble(Duration::Unit_h);
481 }
482 // add external appointments
483 foreach (Appointment* a, r->externalAppointmentList() ) {
484 extEff[ a ] = a->plannedPrDay( startDate(), endDate() );
485 //kDebug(planDbg())<<r->name()<<a->auxcilliaryInfo()<<": "<<extEff[ a ].totalEffort().toDouble(Duration::Unit_h);
486 //kDebug(planDbg())<<r->name()<<a->auxcilliaryInfo()<<": "<<extEff[ a ].startDate()<<extEff[ a ].endDate();
487 }
488 }
489 m_effortMap.clear();
490 m_externalEffortMap.clear();
491 m_effortMap = ec;
492 m_externalEffortMap = extEff;
493 return;
494}
495
496int ResourceAppointmentsItemModel::columnCount( const QModelIndex &/*parent*/ ) const
497{
498 return 3 + startDate().daysTo( endDate() );
499}
500
501int ResourceAppointmentsItemModel::rowCount( const QModelIndex &parent ) const
502{
503 if ( m_project == 0 || m_manager == 0 ) {
504 return 0;
505 }
506 //kDebug(planDbg())<<parent.row()<<", "<<parent.column()<<endl;
507 if ( ! parent.isValid() ) {
508 //kDebug(planDbg())<<m_project->name()<<": "<<m_project->numResourceGroups()<<endl;
509 return m_project->numResourceGroups();
510 }
511 ResourceGroup *g = resourcegroup( parent );
512 if ( g ) {
513 //kDebug(planDbg())<<g->name()<<": "<<g->numResources()<<endl;
514 return g->numResources();
515 }
516 Resource *r = resource( parent );
517 if ( r ) {
518 int rows = m_showInternal ? r->numAppointments( id() ) : 0;
519 rows += m_showExternal ? r->numExternalAppointments() : 0;
520 return rows;
521 }
522 return 0;
523}
524
525QVariant ResourceAppointmentsItemModel::name( const Resource *res, int role ) const
526{
527 switch ( role ) {
528 case Qt::DisplayRole:
529 case Qt::EditRole:
530 case Qt::ToolTipRole:
531 return res->name();
532 break;
533 case Qt::StatusTipRole:
534 case Qt::WhatsThisRole:
535 return QVariant();
536 }
537 return QVariant();
538}
539
540QVariant ResourceAppointmentsItemModel::name( const ResourceGroup *res, int role ) const
541{
542 switch ( role ) {
543 case Qt::DisplayRole:
544 case Qt::EditRole:
545 case Qt::ToolTipRole:
546 return res->name();
547 break;
548 case Qt::StatusTipRole:
549 case Qt::WhatsThisRole:
550 return QVariant();
551 }
552 return QVariant();
553}
554
555QVariant ResourceAppointmentsItemModel::name( const Node *node, int role ) const
556{
557 switch ( role ) {
558 case Qt::DisplayRole:
559 case Qt::EditRole:
560 case Qt::ToolTipRole:
561 return node->name();
562 break;
563 case Qt::StatusTipRole:
564 case Qt::WhatsThisRole:
565 return QVariant();
566 }
567 return QVariant();
568}
569
570QVariant ResourceAppointmentsItemModel::name( const Appointment *app, int role ) const
571{
572 switch ( role ) {
573 case Qt::DisplayRole:
574 case Qt::EditRole:
575 return app->auxcilliaryInfo();
576 case Qt::ToolTipRole:
577 return i18n( "External project: %1", app->auxcilliaryInfo() );
578 case Qt::StatusTipRole:
579 case Qt::WhatsThisRole:
580 return QVariant();
581 case Qt::ForegroundRole:
582 if ( m_externalEffortMap.contains( app ) ) {
583 return QVariant( Qt::blue );
584 }
585 break;
586 }
587 return QVariant();
588}
589
590
591QVariant ResourceAppointmentsItemModel::total( const Resource *res, int role ) const
592{
593 switch ( role ) {
594 case Qt::DisplayRole: {
595 Duration d;
596 if ( m_showInternal ) {
597 QList<Appointment*> lst = res->appointments( m_manager->scheduleId() );
598 foreach ( Appointment *a, lst ) {
599 if ( m_effortMap.contains( a ) ) {
600 d += m_effortMap[ a ].totalEffort();
601 }
602 }
603 }
604 if ( m_showExternal ) {
605 QList<Appointment*> lst = res->externalAppointmentList();
606 foreach ( Appointment *a, lst ) {
607 if ( m_externalEffortMap.contains( a ) ) {
608 d += m_externalEffortMap[ a ].totalEffort();
609 }
610 }
611 }
612 return KGlobal::locale()->formatNumber( d.toDouble( Duration::Unit_h ), 1 );
613 }
614 case Qt::EditRole:
615 case Qt::ToolTipRole:
616 case Qt::StatusTipRole:
617 case Qt::WhatsThisRole:
618 return QVariant();
619 case Qt::TextAlignmentRole:
620 return (int)(Qt::AlignRight|Qt::AlignVCenter);
621 }
622 return QVariant();
623}
624
625QVariant ResourceAppointmentsItemModel::total( const Resource *res, const QDate &date, int role ) const
626{
627 switch ( role ) {
628 case Qt::DisplayRole: {
629 Duration d;
630 if ( m_showInternal ) {
631 QList<Appointment*> lst = res->appointments( id() );
632 foreach ( Appointment *a, lst ) {
633 if ( m_effortMap.contains( a ) ) {
634 d += m_effortMap[ a ].effortOnDate( date );
635 }
636 }
637 }
638 if ( m_showExternal ) {
639 QList<Appointment*> lst = res->externalAppointmentList();
640 foreach ( Appointment *a, lst ) {
641 if ( m_externalEffortMap.contains( a ) ) {
642 d += m_externalEffortMap[ a ].effortOnDate( date );
643 }
644 }
645 }
646 QString ds = KGlobal::locale()->formatNumber( d.toDouble( Duration::Unit_h ), 1 );
647 Duration avail = res->effort( 0, DateTime( date, QTime(0,0,0) ), Duration( 1.0, Duration::Unit_d ) );
648 QString avails = KGlobal::locale()->formatNumber( avail.toDouble( Duration::Unit_h ), 1 );
649 return QString( "%1(%2)").arg( ds).arg( avails );
650 }
651 case Qt::EditRole:
652 case Qt::ToolTipRole:
653 return i18n( "The total booking on %1, along with the maximum hours for the resource", KGlobal::locale()->formatDate( date ) );
654 case Qt::StatusTipRole:
655 case Qt::WhatsThisRole:
656 return QVariant();
657 case Qt::TextAlignmentRole:
658 return (int)(Qt::AlignRight|Qt::AlignVCenter);
659 case Qt::BackgroundRole: {
660 if ( res->calendar() && res->calendar()->state( date ) != CalendarDay::Working ) {
661 QColor c( 0xf0f0f0 );
662 return QVariant::fromValue( c );
663 //return QVariant( Qt::cyan );
664 }
665 break;
666 }
667 }
668 return QVariant();
669}
670
671QVariant ResourceAppointmentsItemModel::total( const Appointment *a, int role ) const
672{
673 switch ( role ) {
674 case Qt::DisplayRole: {
675 Duration d;
676 if ( m_effortMap.contains( a ) ) {
677 d = m_effortMap[ a ].totalEffort();
678 } else if ( m_externalEffortMap.contains( a ) ) {
679 d = m_externalEffortMap[ a ].totalEffort();
680 }
681 return KGlobal::locale()->formatNumber( d.toDouble( Duration::Unit_h ), 1 );
682 }
683 case Qt::ToolTipRole: {
684 if ( m_effortMap.contains( a ) ) {
685 return i18n( "Total booking by this task" );
686 } else if ( m_externalEffortMap.contains( a ) ) {
687 return i18n( "Total booking by the external project" );
688 }
689 return QVariant();
690 }
691 case Qt::EditRole:
692 case Qt::StatusTipRole:
693 case Qt::WhatsThisRole:
694 return QVariant();
695 case Qt::TextAlignmentRole:
696 return (int)(Qt::AlignRight|Qt::AlignVCenter);
697 case Qt::ForegroundRole:
698 if ( m_externalEffortMap.contains( a ) ) {
699 return QVariant( Qt::blue );
700 }
701 break;
702 }
703 return QVariant();
704}
705
706
707QVariant ResourceAppointmentsItemModel::assignment( const Appointment *a, const QDate &date, int role ) const
708{
709 switch ( role ) {
710 case Qt::DisplayRole: {
711 Duration d;
712 if ( m_effortMap.contains( a ) ) {
713 if ( date < m_effortMap[ a ].startDate() || date > m_effortMap[ a ].endDate() ) {
714 return QVariant();
715 }
716 d = m_effortMap[ a ].effortOnDate( date );
717 return KGlobal::locale()->formatNumber( d.toDouble( Duration::Unit_h ), 1 );
718 } else if ( m_externalEffortMap.contains( a ) ) {
719 if ( date < m_externalEffortMap[ a ].startDate() || date > m_externalEffortMap[ a ].endDate() ) {
720 return QVariant();
721 }
722 d = m_externalEffortMap[ a ].effortOnDate( date );
723 return KGlobal::locale()->formatNumber( d.toDouble( Duration::Unit_h ), 1 );
724 }
725 return QVariant();
726 }
727 case Qt::EditRole:
728 case Qt::ToolTipRole: {
729 if ( m_effortMap.contains( a ) ) {
730 return i18n( "Booking by this task on %1", KGlobal::locale()->formatDate( date ) );
731 } else if ( m_externalEffortMap.contains( a ) ) {
732 return i18n( "Booking by external project on %1",KGlobal::locale()->formatDate( date ) );
733 }
734 return QVariant();
735 }
736 case Qt::StatusTipRole:
737 case Qt::WhatsThisRole:
738 return QVariant();
739 case Qt::TextAlignmentRole:
740 return (int)(Qt::AlignRight|Qt::AlignVCenter);
741 case Qt::ForegroundRole:
742 if ( m_externalEffortMap.contains( a ) ) {
743 return QVariant( Qt::blue );
744 }
745 break;
746 case Qt::BackgroundRole: {
747 Resource *r = parent( a );
748 if ( r && r->calendar() && r->calendar()->state( date ) != CalendarDay::Working ) {
749 QColor c( 0xf0f0f0 );
750 return QVariant::fromValue( c );
751 //return QVariant( Qt::cyan );
752 }
753 break;
754 }
755 }
756 return QVariant();
757}
758
759QVariant ResourceAppointmentsItemModel::notUsed( const ResourceGroup *, int role ) const
760{
761 switch ( role ) {
762 case Qt::DisplayRole:
763 return QString(" ");
764 case Qt::TextAlignmentRole:
765 return Qt::AlignCenter;
766 case Qt::EditRole:
767 case Qt::ToolTipRole:
768 case Qt::StatusTipRole:
769 case Qt::WhatsThisRole:
770 return QVariant();
771 }
772 return QVariant();
773}
774
775QVariant ResourceAppointmentsItemModel::data( const QModelIndex &index, int role ) const
776{
777 if ( m_project == 0 || m_manager == 0 ) {
778 return QVariant();
779 }
780 QVariant result;
781 if ( index.column() >= columnCount() ) {
782 kDebug(planDbg())<<"invalid display value column "<<index;
783 return result;
784 }
785 if ( ! index.isValid() ) {
786 kDebug(planDbg())<<"Invalid index:"<<index;
787 return result;
788 }
789 if ( role == Qt::TextAlignmentRole ) {
790 return headerData( index.column(), Qt::Horizontal, role );
791 }
792 Resource *r = resource( index );
793 if ( r ) {
794 switch ( index.column() ) {
795 case 0: result = name( r, role ); break;
796 case 1: result = total( r, role ); break;
797 default:
798 QDate d = startDate().addDays( index.column() - 2 );
799 result = total( r, d, role );
800 break;
801 }
802 if ( result.isValid() ) {
803 if ( role == Qt::DisplayRole && result.type() == QVariant::String && result.toString().isEmpty()) {
804 // HACK to show focus in empty cells
805 result = ' ';
806 }
807 return result;
808 }
809 return QVariant();
810 }
811 ResourceGroup *g = resourcegroup( index );
812 if ( g ) {
813 switch ( index.column() ) {
814 case 0: result = name( g, role ); break;
815 default:
816 result = notUsed( g, role );
817 break;
818 }
819 if ( result.isValid() ) {
820 if ( role == Qt::DisplayRole && result.type() == QVariant::String && result.toString().isEmpty()) {
821 // HACK to show focus in empty cells
822 result = ' ';
823 }
824 return result;
825 }
826 return QVariant();
827 }
828 Appointment *a = appointment( index );
829 if ( a ) {
830 switch ( index.column() ) {
831 case 0: result = name( a->node()->node(), role ); break;
832 case 1: result = total( a, role ); break;
833 default: {
834 QDate d = startDate().addDays( index.column()-2 );
835 result = assignment( a, d, role );
836 break;
837 }
838 }
839 if ( result.isValid() ) {
840 if ( role == Qt::DisplayRole && result.type() == QVariant::String && result.toString().isEmpty()) {
841 // HACK to show focus in empty cells
842 result = ' ';
843 }
844 return result;
845 }
846 return QVariant();
847 }
848 a = externalAppointment( index );
849 if ( a ) {
850 //kDebug(planDbg())<<"external"<<a->auxcilliaryInfo()<<index;
851 switch ( index.column() ) {
852 case 0: result = name( a, role ); break;
853 case 1: result = total( a, role ); break;
854 default: {
855 QDate d = startDate().addDays( index.column()-2 );
856 result = assignment( a, d, role );
857 break;
858 }
859 }
860 if ( result.isValid() ) {
861 if ( role == Qt::DisplayRole && result.type() == QVariant::String && result.toString().isEmpty()) {
862 // HACK to show focus in empty cells
863 result = ' ';
864 }
865 return result;
866 }
867 return QVariant();
868 }
869 kDebug(planDbg())<<"Could not find ptr:"<<index;
870 return QVariant();
871}
872
873bool ResourceAppointmentsItemModel::setData( const QModelIndex &index, const QVariant &value, int role )
874{
875 if ( ! index.isValid() ) {
876 return ItemModelBase::setData( index, value, role );
877 }
878 if ( ( flags( index ) &Qt::ItemIsEditable ) == 0 || role != Qt::EditRole ) {
879 return false;
880 }
881 Resource *r = resource( index );
882 if ( r ) {
883 switch (index.column()) {
884 default:
885 qWarning("data: invalid display value column %d", index.column());
886 break;
887 }
888 return false;
889 }
890 ResourceGroup *g = resourcegroup( index );
891 if ( g ) {
892 switch (index.column()) {
893 default:
894 qWarning("data: invalid display value column %d", index.column());
895 break;
896 }
897 return false;
898 }
899 return false;
900}
901
902QVariant ResourceAppointmentsItemModel::headerData( int section, Qt::Orientation orientation, int role ) const
903{
904 if ( orientation == Qt::Horizontal ) {
905 if ( role == Qt::DisplayRole ) {
906 switch ( section ) {
907 case 0: return i18n( "Name" );
908 case 1: return i18n( "Total" );
909 default: {
910 //kDebug(planDbg())<<section<<", "<<startDate()<<endDate();
911 if ( section < columnCount() ) {
912 QDate d = startDate().addDays( section - 2 );
913 if ( d <= endDate() ) {
914 return d;
915 }
916 }
917 return QVariant();
918 }
919 }
920 } else if ( role == Qt::ToolTipRole ) {
921 switch ( section ) {
922 case 0: return i18n( "Name" );
923 case 1: return i18n( "The total hours booked" );
924 default: {
925 //kDebug(planDbg())<<section<<", "<<startDate()<<endDate();
926 QDate d = startDate().addDays( section - 2 );
927 return i18n( "Bookings on %1", KGlobal::locale()->formatDate( d ) );
928 }
929 return QVariant();
930 }
931 } else if ( role == Qt::TextAlignmentRole ) {
932 switch (section) {
933 case 0: return QVariant();
934 default: return (int)(Qt::AlignRight|Qt::AlignVCenter);
935 }
936 }
937 }
938 if ( role == Qt::ToolTipRole ) {
939 switch ( section ) {
940 default: return QVariant();
941 }
942 }
943 return ItemModelBase::headerData(section, orientation, role);
944}
945
946QObject *ResourceAppointmentsItemModel::object( const QModelIndex &index ) const
947{
948 QObject *o = 0;
949 if ( index.isValid() ) {
950 o = dynamic_cast<QObject*>( resource( index ) );
951 if ( o ) {
952 return o;
953 }
954 o = dynamic_cast<QObject*>( resourcegroup( index ) );
955 }
956 return o;
957}
958
959Node *ResourceAppointmentsItemModel::node( const QModelIndex &index ) const
960{
961 Appointment *a = appointment( index );
962 if ( a == 0 ) {
963 return 0;
964 }
965 return a->node()->node();
966}
967
968Appointment *ResourceAppointmentsItemModel::appointment( const QModelIndex &index ) const
969{
970 if ( m_project == 0 || m_manager == 0 ) {
971 return 0;
972 }
973 foreach ( Resource *r, m_project->resourceList() ) {
974 foreach ( Appointment *a, r->appointments( id() ) ) {
975 if ( a == index.internalPointer() ) {
976 return a;
977 }
978 }
979 }
980 return 0;
981}
982
983Appointment *ResourceAppointmentsItemModel::externalAppointment( const QModelIndex &index ) const
984{
985 if ( m_project == 0 || m_manager == 0 ) {
986 return 0;
987 }
988 foreach ( Resource *r, m_project->resourceList() ) {
989 foreach ( Appointment *a, r->externalAppointmentList() ) {
990 if ( a == index.internalPointer() ) {
991 return a;
992 }
993 }
994 }
995 return 0;
996}
997
998QModelIndex ResourceAppointmentsItemModel::createAppointmentIndex( int row, int col, void *ptr ) const
999{
1000 return createIndex( row, col, ptr );
1001}
1002
1003QModelIndex ResourceAppointmentsItemModel::createExternalAppointmentIndex( int row, int col, void *ptr ) const
1004{
1005 if ( m_project == 0 || m_manager == 0 ) {
1006 return QModelIndex();
1007 }
1008 QModelIndex i = createIndex( row, col, ptr );
1009 //kDebug(planDbg())<<i;
1010 return i;
1011}
1012
1013Resource *ResourceAppointmentsItemModel::resource( const QModelIndex &index ) const
1014{
1015 if ( m_project == 0 ) {
1016 return 0;
1017 }
1018 foreach ( Resource *r, m_project->resourceList() ) {
1019 if ( r == index.internalPointer() ) {
1020 return r;
1021 }
1022 }
1023 return 0;
1024}
1025
1026QModelIndex ResourceAppointmentsItemModel::createResourceIndex( int row, int col, void *ptr ) const
1027{
1028 return createIndex( row, col, ptr );
1029}
1030
1031ResourceGroup *ResourceAppointmentsItemModel::resourcegroup( const QModelIndex &index ) const
1032{
1033 if ( m_project == 0 ) {
1034 return 0;
1035 }
1036 foreach ( ResourceGroup *r, m_project->resourceGroups() ) {
1037 if ( r == index.internalPointer() ) {
1038 return r;
1039 }
1040 }
1041 return 0;
1042}
1043
1044QModelIndex ResourceAppointmentsItemModel::createGroupIndex( int row, int col, void *ptr ) const
1045{
1046 return createIndex( row, col, ptr );
1047}
1048
1049void ResourceAppointmentsItemModel::slotCalendarChanged( Calendar* )
1050{
1051 foreach ( Resource *r, m_project->resourceList() ) {
1052 if ( r->calendar( true ) == 0 ) {
1053 slotResourceChanged( r );
1054 }
1055 }
1056}
1057
1058void ResourceAppointmentsItemModel::slotResourceChanged( Resource *res )
1059{
1060 ResourceGroup *g = res->parentGroup();
1061 if ( g ) {
1062 int row = g->indexOf( res );
1063 emit dataChanged( createResourceIndex( row, 0, res ), createResourceIndex( row, columnCount() - 1, res ) );
1064 return;
1065 }
1066}
1067
1068void ResourceAppointmentsItemModel::slotResourceGroupChanged( ResourceGroup *res )
1069{
1070 Project *p = res->project();
1071 if ( p ) {
1072 int row = p->resourceGroups().indexOf( res );
1073 emit dataChanged( createGroupIndex( row, 0, res ), createGroupIndex( row, columnCount() - 1, res ) );
1074 }
1075}
1076
1077//-------------------------------------------------------
1078class ResourceAppointmentsRowModel::Private
1079{
1080public:
1081 Private( Private *par=0, void *p=0, KPlato::ObjectType t=OT_None ) : parent( par ), ptr( p ), type( t ), internalCached( false ), externalCached( false ), intervalRow( -1 )
1082 {}
1083 ~Private()
1084 {
1085 qDeleteAll( intervals );
1086 }
1087
1088 QVariant data( int column, long id = -1, int role = Qt::DisplayRole ) const;
1089
1090 Private *parent;
1091 void *ptr;
1092 KPlato::ObjectType type;
1093 bool internalCached;
1094 bool externalCached;
1095
1096 Private *intervalAt( int row ) const;
1097 // used by interval
1098 AppointmentInterval interval;
1099
1100protected:
1101 QVariant groupData( int column, int role ) const;
1102 QVariant resourceData( int column, long id, int role ) const;
1103 QVariant appointmentData( int column, int role ) const;
1104 QVariant externalData( int column, int role ) const;
1105 QVariant intervalData( int column, int role ) const;
1106
1107private:
1108 // used by resource
1109 Appointment internal;
1110 Appointment external;
1111
1112 // used by appointment
1113 int intervalRow;
1114 mutable QMap<int, Private*> intervals;
1115};
1116
1117QVariant ResourceAppointmentsRowModel::Private::data( int column, long id, int role ) const
1118{
1119 if ( role == Role::ObjectType ) {
1120 return (int)type;
1121 }
1122 switch ( type ) {
1123 case OT_ResourceGroup: return groupData( column, role );
1124 case OT_Resource: return resourceData( column, id, role );
1125 case OT_Appointment: return appointmentData( column, role );
1126 case OT_External: return externalData( column, role );
1127 case OT_Interval: return intervalData( column, role );
1128 default: break;
1129 }
1130 return QVariant();
1131}
1132
1133QVariant ResourceAppointmentsRowModel::Private::groupData( int column, int role ) const
1134{
1135 ResourceGroup *g = static_cast<ResourceGroup*>( ptr );
1136 if ( role == Qt::DisplayRole ) {
1137 switch ( column ) {
1138 case ResourceAppointmentsRowModel::Name: return g->name();
1139 case ResourceAppointmentsRowModel::Type: return g->typeToString( true );
1140 case ResourceAppointmentsRowModel::StartTime: return " ";
1141 case ResourceAppointmentsRowModel::EndTime: return " ";
1142 case ResourceAppointmentsRowModel::Load: return " ";
1143 }
1144 } else if ( role == Role::Maximum ) {
1145 return g->units(); //TODO: Maximum Load
1146 }
1147 return QVariant();
1148}
1149
1150QVariant ResourceAppointmentsRowModel::Private::resourceData( int column, long id, int role ) const
1151{
1152 KPlato::Resource *r = static_cast<KPlato::Resource*>( ptr );
1153 if ( role == Qt::DisplayRole ) {
1154 switch ( column ) {
1155 case ResourceAppointmentsRowModel::Name: return r->name();
1156 case ResourceAppointmentsRowModel::Type: return r->typeToString( true );
1157 case ResourceAppointmentsRowModel::StartTime: return " ";
1158 case ResourceAppointmentsRowModel::EndTime: return " ";
1159 case ResourceAppointmentsRowModel::Load: return " ";
1160 }
1161 } else if ( role == Role::Maximum ) {
1162 return r->units(); //TODO: Maximum Load
1163 } else if ( role == Role::InternalAppointments ) {
1164 if ( ! internalCached ) {
1165 Resource *r = static_cast<Resource*>( ptr );
1166 const_cast<Private*>( this )->internal.clear();
1167 foreach ( Appointment *a, r->appointments( id ) ) {
1168 const_cast<Private*>( this )->internal += *a;
1169 }
1170 const_cast<Private*>( this )->internalCached = true;
1171 }
1172 return QVariant::fromValue( (void*)(&internal) );
1173 } else if ( role == Role::ExternalAppointments ) {
1174 if ( ! externalCached ) {
1175 Resource *r = static_cast<Resource*>( ptr );
1176 const_cast<Private*>( this )->external.clear();
1177 foreach ( Appointment *a, r->externalAppointmentList() ) {
1178 Appointment e;
1179 e.setIntervals( a->intervals( r->startTime( id ), r->endTime( id ) ) );
1180 const_cast<Private*>( this )->external += e;
1181 }
1182 const_cast<Private*>( this )->externalCached = true;
1183 }
1184 return QVariant::fromValue( (void*)(&external) );
1185 }
1186 return QVariant();
1187}
1188
1189QVariant ResourceAppointmentsRowModel::Private::appointmentData( int column, int role ) const
1190{
1191 KPlato::Appointment *a = static_cast<KPlato::Appointment*>( ptr );
1192 if ( role == Qt::DisplayRole ) {
1193 switch ( column ) {
1194 case ResourceAppointmentsRowModel::Name: return a->node()->node()->name();
1195 case ResourceAppointmentsRowModel::Type: return a->node()->node()->typeToString( true );
1196 case ResourceAppointmentsRowModel::StartTime: return KGlobal::locale()->formatDateTime( a->startTime() );
1197 case ResourceAppointmentsRowModel::EndTime: return KGlobal::locale()->formatDateTime( a->endTime() );
1198 case ResourceAppointmentsRowModel::Load: return " ";
1199 }
1200 } else if ( role == Qt::ToolTipRole ) {
1201 Node *n = a->node()->node();
1202 return i18nc( "@info:tooltip", "%1: %2<nl/>%3: %4",
1203 n->wbsCode(),
1204 n->name(),
1205 KGlobal::locale()->formatDateTime( a->startTime() ),
1206 KGlobal::locale()->formatDuration( ( a->endTime() - a->startTime() ).milliseconds() )
1207 );
1208 } else if ( role == Role::Maximum ) {
1209 return a->resource()->resource()->units(); //TODO: Maximum Load
1210 }
1211 return QVariant();
1212}
1213
1214QVariant ResourceAppointmentsRowModel::Private::externalData( int column, int role ) const
1215{
1216 KPlato::Appointment *a = static_cast<KPlato::Appointment*>( ptr );
1217 if ( role == Qt::DisplayRole ) {
1218 switch ( column ) {
1219 case ResourceAppointmentsRowModel::Name: return a->auxcilliaryInfo();
1220 case ResourceAppointmentsRowModel::Type: return i18n( "Project" );
1221 case ResourceAppointmentsRowModel::StartTime: return KGlobal::locale()->formatDateTime( a->startTime() );
1222 case ResourceAppointmentsRowModel::EndTime: return KGlobal::locale()->formatDateTime( a->endTime() );
1223 case ResourceAppointmentsRowModel::Load: return " ";
1224 }
1225 } else if ( role == Qt::ForegroundRole ) {
1226 return QColor( Qt::blue );
1227 } else if ( role == Role::Maximum ) {
1228 KPlato::Resource *r = static_cast<KPlato::Resource*>( parent->ptr );
1229 return r->units(); //TODO: Maximum Load
1230 }
1231 return QVariant();
1232}
1233
1234ResourceAppointmentsRowModel::Private *ResourceAppointmentsRowModel::Private::intervalAt( int row ) const
1235{
1236 Q_ASSERT( type == OT_Appointment || type == OT_External );
1237 Private *p = intervals.value( row );
1238 if ( p ) {
1239 return p;
1240 }
1241 Appointment *a = static_cast<Appointment*>( ptr );
1242 p = new Private( const_cast<Private*>( this ), 0, OT_Interval );
1243 p->intervalRow = row;
1244 p->interval = a->intervalAt( row );
1245 intervals.insert( row, p );
1246 return p;
1247}
1248
1249
1250QVariant ResourceAppointmentsRowModel::Private::intervalData( int column, int role ) const
1251{
1252 if ( role == Qt::DisplayRole ) {
1253 switch ( column ) {
1254 case ResourceAppointmentsRowModel::Name: return QVariant();
1255 case ResourceAppointmentsRowModel::Type: return i18n( "Interval" );
1256 case ResourceAppointmentsRowModel::StartTime: return KGlobal::locale()->formatDateTime( interval.startTime() );
1257 case ResourceAppointmentsRowModel::EndTime: return KGlobal::locale()->formatDateTime( interval.endTime() );
1258 case ResourceAppointmentsRowModel::Load: return interval.load();
1259 }
1260 } else if ( role == Qt::ToolTipRole ) {
1261 Appointment *a = static_cast<Appointment*>( parent->ptr );
1262 Node *n = a->node()->node();
1263 return i18nc( "@info:tooltip", "%1: %2<nl/>%3: %4<nl/>Assigned: %5<nl/>Available: %6",
1264 n->wbsCode(),
1265 n->name(),
1266 KGlobal::locale()->formatDateTime( a->startTime() ),
1267 KGlobal::locale()->formatDuration( ( a->endTime() - a->startTime() ).milliseconds() ),
1268 interval.load(),
1269 a->resource()->resource()->units()
1270 );
1271 } else if ( role == Role::Maximum ) {
1272 return parent->appointmentData( column, role );
1273 }
1274 return QVariant();
1275}
1276
1277int ResourceAppointmentsRowModel::sortRole( int column ) const
1278{
1279 switch ( column ) {
1280 case ResourceAppointmentsRowModel::StartTime:
1281 case ResourceAppointmentsRowModel::EndTime:
1282 return Qt::EditRole;
1283 default:
1284 break;
1285 }
1286 return Qt::DisplayRole;
1287}
1288
1289#ifndef QT_NO_DEBUG_STREAM
1290QDebug operator<<( QDebug dbg, KPlato::ObjectType t)
1291{
1292 switch(t){
1293 case KPlato::OT_None: dbg << "None"; break;
1294 case KPlato::OT_ResourceGroup: dbg << "Group"; break;
1295 case KPlato::OT_Resource: dbg << "Resource"; break;
1296 case KPlato::OT_Appointment: dbg << "Appointment"; break;
1297 case KPlato::OT_External: dbg << "External"; break;
1298 case KPlato::OT_Interval: dbg << "Interval"; break;
1299 default: dbg << "Unknown";
1300 }
1301 return dbg;
1302}
1303QDebug operator<<( QDebug dbg, const ResourceAppointmentsRowModel::Private& s )
1304{
1305 dbg <<&s;
1306 return dbg;
1307}
1308QDebug operator<<( QDebug dbg, const ResourceAppointmentsRowModel::Private* s )
1309{
1310 if ( s == 0 ) {
1311 dbg<<"ResourceAppointmentsRowModel::Private[ ("<<(void*)s<<") ]";
1312 } else {
1313 dbg << "ResourceAppointmentsRowModel::Private[ ("<<(void*)s<<") Type="<<s->type<<" parent=";
1314 switch( s->type ) {
1315 case KPlato::OT_ResourceGroup:
1316 dbg<<static_cast<ResourceGroup*>(s->ptr)->project()<<static_cast<ResourceGroup*>(s->ptr)->project()->name();
1317 dbg<<" ptr="<<static_cast<ResourceGroup*>(s->ptr)<<static_cast<ResourceGroup*>(s->ptr)->name();
1318 break;
1319 case KPlato::OT_Resource:
1320 dbg<<static_cast<ResourceGroup*>(s->parent->ptr)<<static_cast<ResourceGroup*>(s->parent->ptr)->name();
1321 dbg<<" ptr="<<static_cast<Resource*>(s->ptr)<<static_cast<Resource*>(s->ptr)->name();
1322 break;
1323 case KPlato::OT_Appointment:
1324 case KPlato::OT_External:
1325 dbg<<static_cast<Resource*>(s->parent->ptr)<<static_cast<Resource*>(s->parent->ptr)->name();
1326 dbg<<" ptr="<<static_cast<Appointment*>(s->ptr);
1327 break;
1328 case KPlato::OT_Interval:
1329 dbg<<static_cast<Appointment*>(s->parent->ptr)<<" ptr="<<static_cast<AppointmentInterval*>(s->ptr);
1330 break;
1331 default:
1332 dbg<<s->parent<<" ptr="<<s->ptr;
1333 break;
1334 }
1335 dbg<<" ]";
1336 }
1337
1338 return dbg;
1339}
1340#endif
1341
1342ResourceAppointmentsRowModel::ResourceAppointmentsRowModel( QObject *parent )
1343 : ItemModelBase( parent ),
1344 m_schedule( 0 )
1345{
1346}
1347
1348ResourceAppointmentsRowModel::~ResourceAppointmentsRowModel()
1349{
1350 qDeleteAll( m_datamap );
1351}
1352
1353void ResourceAppointmentsRowModel::setProject( Project *project )
1354{
1355 //kDebug(planDbg())<<project;
1356 if ( m_project ) {
1357 disconnect( m_project, SIGNAL(resourceGroupToBeAdded(const ResourceGroup*,int)), this, SLOT(slotResourceGroupToBeInserted(const ResourceGroup*,int)) );
1358
1359 disconnect( m_project, SIGNAL(resourceGroupToBeRemoved(const ResourceGroup*)), this, SLOT(slotResourceGroupToBeRemoved(const ResourceGroup*)) );
1360
1361 disconnect( m_project, SIGNAL(resourceToBeAdded(const ResourceGroup*,int)), this, SLOT(slotResourceToBeInserted(const ResourceGroup*,int)) );
1362
1363 disconnect( m_project, SIGNAL(resourceToBeRemoved(const Resource*)), this, SLOT(slotResourceToBeRemoved(const Resource*)) );
1364
1365 disconnect( m_project, SIGNAL(resourceGroupAdded(const ResourceGroup*)), this, SLOT(slotResourceGroupInserted(const ResourceGroup*)) );
1366
1367 disconnect( m_project, SIGNAL(resourceGroupRemoved(const ResourceGroup*)), this, SLOT(slotResourceGroupRemoved(const ResourceGroup*)) );
1368
1369 disconnect( m_project, SIGNAL(resourceAdded(const Resource*)), this, SLOT(slotResourceInserted(const Resource*)) );
1370
1371 disconnect( m_project, SIGNAL(resourceRemoved(const Resource*)), this, SLOT(slotResourceRemoved(const Resource*)) );
1372
1373 disconnect( m_project, SIGNAL(projectCalculated(ScheduleManager*)), this, SLOT(slotProjectCalculated(ScheduleManager*)) );
1374
1375 foreach ( Resource *r, m_project->resourceList() ) {
1376 disconnect( r, SIGNAL(externalAppointmentToBeAdded(Resource*,int)), this, SLOT(slotAppointmentToBeInserted(Resource*,int)) );
1377 disconnect( r, SIGNAL(externalAppointmentAdded(Resource*,Appointment*)), this, SLOT(slotAppointmentInserted(Resource*,Appointment*)) );
1378 disconnect( r, SIGNAL(externalAppointmentToBeRemoved(Resource*,int)), this, SLOT(slotAppointmentToBeRemoved(Resource*,int)) );
1379 disconnect( r, SIGNAL(externalAppointmentRemoved()), this, SLOT(slotAppointmentRemoved()) );
1380 disconnect( r, SIGNAL(externalAppointmentChanged(Resource*,Appointment*)), this, SLOT(slotAppointmentChanged(Resource*,Appointment*)) );
1381 }
1382 }
1383 m_project = project;
1384 if ( m_project ) {
1385 connect( m_project, SIGNAL(resourceGroupToBeAdded(const ResourceGroup*,int)), this, SLOT(slotResourceGroupToBeInserted(const ResourceGroup*,int)) );
1386
1387 connect( m_project, SIGNAL(resourceGroupToBeRemoved(const ResourceGroup*)), this, SLOT(slotResourceGroupToBeRemoved(const ResourceGroup*)) );
1388
1389 connect( m_project, SIGNAL(resourceToBeAdded(const ResourceGroup*,int)), this, SLOT(slotResourceToBeInserted(const ResourceGroup*,int)) );
1390
1391 connect( m_project, SIGNAL(resourceToBeRemoved(const Resource*)), this, SLOT(slotResourceToBeRemoved(const Resource*)) );
1392
1393 connect( m_project, SIGNAL(resourceGroupAdded(const ResourceGroup*)), this, SLOT(slotResourceGroupInserted(const ResourceGroup*)) );
1394
1395 connect( m_project, SIGNAL(resourceGroupRemoved(const ResourceGroup*)), this, SLOT(slotResourceGroupRemoved(const ResourceGroup*)) );
1396
1397 connect( m_project, SIGNAL(resourceAdded(const Resource*)), this, SLOT(slotResourceInserted(const Resource*)) );
1398
1399 connect( m_project, SIGNAL(resourceRemoved(const Resource*)), this, SLOT(slotResourceRemoved(const Resource*)) );
1400
1401 connect( m_project, SIGNAL(projectCalculated(ScheduleManager*)), this, SLOT(slotProjectCalculated(ScheduleManager*)) );
1402
1403 foreach ( Resource *r, m_project->resourceList() ) {
1404 connect( r, SIGNAL(externalAppointmentToBeAdded(Resource*,int)), this, SLOT(slotAppointmentToBeInserted(Resource*,int)) );
1405 connect( r, SIGNAL(externalAppointmentAdded(Resource*,Appointment*)), this, SLOT(slotAppointmentInserted(Resource*,Appointment*)) );
1406 connect( r, SIGNAL(externalAppointmentToBeRemoved(Resource*,int)), this, SLOT(slotAppointmentToBeRemoved(Resource*,int)) );
1407 connect( r, SIGNAL(externalAppointmentRemoved()), this, SLOT(slotAppointmentRemoved()) );
1408 connect( r, SIGNAL(externalAppointmentChanged(Resource*,Appointment*)), this, SLOT(slotAppointmentChanged(Resource*,Appointment*)) );
1409 }
1410 }
1411 reset();
1412}
1413
1414void ResourceAppointmentsRowModel::setScheduleManager( ScheduleManager *sm )
1415{
1416 kDebug(planDbg())<<"ResourceAppointmentsRowModel::setScheduleManager:"<<sm;
1417 if ( sm == 0 || sm != m_manager || sm->expected() != m_schedule ) {
1418 m_manager = sm;
1419 m_schedule = sm ? sm->expected() : 0;
1420 qDeleteAll( m_datamap );
1421 m_datamap.clear();
1422 reset();
1423 }
1424}
1425
1426long ResourceAppointmentsRowModel::id() const
1427{
1428 return m_manager ? m_manager->scheduleId() : -1;
1429}
1430
1431const QMetaEnum ResourceAppointmentsRowModel::columnMap() const
1432{
1433 return metaObject()->enumerator( metaObject()->indexOfEnumerator("Properties") );
1434}
1435
1436int ResourceAppointmentsRowModel::columnCount( const QModelIndex & /*parent */) const
1437{
1438 return columnMap().keyCount();
1439}
1440
1441int ResourceAppointmentsRowModel::rowCount( const QModelIndex & parent ) const
1442{
1443 if ( m_project == 0 ) {
1444 return 0;
1445 }
1446 if ( ! parent.isValid() ) {
1447 return m_project->numResourceGroups();
1448 }
1449 if ( ResourceGroup *g = resourcegroup( parent ) ) {
1450 return g->numResources();
1451 }
1452 if ( m_manager == 0 ) {
1453 return 0;
1454 }
1455 if ( Resource *r = resource( parent ) ) {
1456 return r->numAppointments( id() ) + r->numExternalAppointments(); // number of tasks there are appointments with + external projects
1457 }
1458 if ( Appointment *a = appointment( parent ) ) {
1459 return a->count(); // number of appointment intervals
1460 }
1461 return 0;
1462}
1463
1464QVariant ResourceAppointmentsRowModel::data( const QModelIndex &index, int role ) const
1465{
1466 //kDebug(planDbg())<<index<<role;
1467 if ( ! index.isValid() ) {
1468 return QVariant();
1469 }
1470 if ( role == Qt::TextAlignmentRole ) {
1471 return headerData( index.column(), Qt::Horizontal, role );
1472 }
1473 return static_cast<Private*>(index.internalPointer() )->data( index.column(), id(), role );
1474}
1475
1476QVariant ResourceAppointmentsRowModel::headerData( int section, Qt::Orientation orientation, int role ) const
1477{
1478 if ( orientation == Qt::Vertical ) {
1479 return QVariant();
1480 }
1481 if ( role == Qt::DisplayRole ) {
1482 switch ( section ) {
1483 case Name: return i18n( "Name" );
1484 case Type: return i18n( "Type" );
1485 case StartTime: return i18n( "Start Time" );
1486 case EndTime: return i18n( "End Time" );
1487 case Load: return i18nc( "@title:column noun", "Load" );
1488 }
1489 }
1490 if ( role == Qt::TextAlignmentRole ) {
1491 switch ( section ) {
1492 case Name:
1493 case Type:
1494 case StartTime:
1495 case EndTime:
1496 return (int)(Qt::AlignLeft|Qt::AlignVCenter);;
1497 case Load:
1498 return (int)(Qt::AlignRight|Qt::AlignVCenter);
1499 }
1500 }
1501 return ItemModelBase::headerData( section, orientation, role );
1502}
1503
1504QModelIndex ResourceAppointmentsRowModel::parent( const QModelIndex &idx ) const
1505{
1506 if ( !idx.isValid() || m_project == 0 ) {
1507 kWarning(planDbg())<<"No data "<<idx;
1508 return QModelIndex();
1509 }
1510
1511 QModelIndex p;
1512 if ( resourcegroup( idx ) ) {
1513 // ResourceGroup, no parent
1514 return QModelIndex();
1515 }
1516 if ( ResourceGroup *pg = parentGroup( idx ) ) {
1517 // Resource, parent is ResourceGroup
1518 int row = m_project->indexOf( pg );
1519 p = const_cast<ResourceAppointmentsRowModel*>( this )->createGroupIndex( row, 0, m_project );
1520 //kDebug(planDbg())<<"Parent:"<<p<<r->parentGroup()->name();
1521 Q_ASSERT( p.isValid() );
1522 return p;
1523 }
1524 if ( Resource *pr = parentResource( idx ) ) {
1525 // Appointment, parent is Resource
1526 int row = pr->parentGroup()->indexOf( pr );
1527 p = const_cast<ResourceAppointmentsRowModel*>( this )->createResourceIndex( row, 0, pr->parentGroup() );
1528 //kDebug(planDbg())<<"Parent:"<<p<<r->parentGroup()->name();
1529 Q_ASSERT( p.isValid() );
1530 return p;
1531 }
1532 if ( Appointment *a = parentAppointment( idx ) ) {
1533 // AppointmentInterval, parent is Appointment
1534 Private *pi = static_cast<Private*>( idx.internalPointer() );
1535 if ( pi->parent->type == OT_Appointment ) {
1536 Q_ASSERT( a->resource()->id() == id() );
1537 if ( a->resource() && a->resource()->resource() ) {
1538 Resource *r = a->resource()->resource();
1539 int row = r->indexOf( a, id() );
1540 Q_ASSERT( row >= 0 );
1541 p = const_cast<ResourceAppointmentsRowModel*>( this )->createAppointmentIndex( row, 0, r );
1542 //kDebug(planDbg())<<"Parent:"<<p<<r->name();
1543 Q_ASSERT( p.isValid() );
1544 }
1545 } else if ( pi->parent->type == OT_External ) {
1546 Resource *r = static_cast<Resource*>( pi->parent->parent->ptr );
1547 int row = r->externalAppointmentList().indexOf( a );
1548 Q_ASSERT( row >= 0 );
1549 row += r->numAppointments( id() );
1550 p = const_cast<ResourceAppointmentsRowModel*>( this )->createAppointmentIndex( row, 0, r );
1551 }
1552 return p;
1553 }
1554 return QModelIndex();
1555}
1556
1557QModelIndex ResourceAppointmentsRowModel::index( ResourceGroup *g ) const
1558{
1559 if ( m_project == 0 || g == 0 ) {
1560 return QModelIndex();
1561 }
1562 return const_cast<ResourceAppointmentsRowModel*>( this )->createGroupIndex( m_project->indexOf( g ), 0, m_project );
1563}
1564
1565QModelIndex ResourceAppointmentsRowModel::index( Resource *r ) const
1566{
1567 if ( m_project == 0 || r == 0 ) {
1568 return QModelIndex();
1569 }
1570 return const_cast<ResourceAppointmentsRowModel*>( this )->createResourceIndex( r->parentGroup()->indexOf( r ), 0, r->parentGroup() );
1571}
1572
1573QModelIndex ResourceAppointmentsRowModel::index( Appointment *a ) const
1574{
1575 if ( m_project == 0 || m_manager == 0 || a == 0 || a->resource()->resource() ) {
1576 return QModelIndex();
1577 }
1578 Resource *r = a->resource()->resource();
1579 return const_cast<ResourceAppointmentsRowModel*>( this )->createAppointmentIndex( r->indexOf( a, id() ), 0, r );
1580}
1581
1582QModelIndex ResourceAppointmentsRowModel::index( int row, int column, const QModelIndex &parent ) const
1583{
1584 if ( m_project == 0 || row < 0 || column < 0 ) {
1585 return QModelIndex();
1586 }
1587 if ( ! parent.isValid() ) {
1588 if ( row < m_project->numResourceGroups() ) {
1589 //kDebug(planDbg())<<"Group: "<<m_project->resourceGroupAt( row );
1590 return const_cast<ResourceAppointmentsRowModel*>( this )->createGroupIndex( row, column, m_project );
1591 }
1592 return QModelIndex();
1593 }
1594 if ( ResourceGroup *g = resourcegroup( parent ) ) {
1595 if ( row < g->numResources() ) {
1596 //kDebug(planDbg())<<"Resource: "<<g->resourceAt( row )<<static_cast<Private*>( parent.internalPointer() );
1597 return const_cast<ResourceAppointmentsRowModel*>( this )->createResourceIndex( row, column, g );
1598 }
1599 return QModelIndex();
1600 }
1601 if ( m_manager == 0 ) {
1602 return QModelIndex();
1603 }
1604 if ( Resource *r = resource( parent ) ) {
1605 int num = r->numAppointments( id() ) + r->numExternalAppointments();
1606 if ( row < num ) {
1607 //kDebug(planDbg())<<"Appointment: "<<r->appointmentAt( row, m_manager->scheduleId() )<<static_cast<Private*>( parent.internalPointer() );
1608 return const_cast<ResourceAppointmentsRowModel*>( this )->createAppointmentIndex( row, column, r );
1609 }
1610 return QModelIndex();
1611 }
1612 if ( Appointment *a = appointment( parent ) ) {
1613 int num = a->count();
1614 if ( row < num ) {
1615 //kDebug(planDbg())<<"Appointment interval at: "<<row<<static_cast<Private*>( parent.internalPointer() );
1616 return const_cast<ResourceAppointmentsRowModel*>( this )->createIntervalIndex( row, column, a );
1617 }
1618 return QModelIndex();
1619 }
1620 return QModelIndex();
1621}
1622
1623QModelIndex ResourceAppointmentsRowModel::createGroupIndex( int row, int column, Project *project )
1624{
1625 ResourceGroup *group = project->resourceGroupAt( row );
1626 Private *p = m_datamap.value( (void*)group );
1627 if ( p == 0 ) {
1628 p = new Private( 0, group, OT_ResourceGroup );
1629 m_datamap.insert( group, p );
1630 }
1631 QModelIndex idx = createIndex( row, column, p );
1632 Q_ASSERT( idx.isValid() );
1633 return idx;
1634}
1635
1636QModelIndex ResourceAppointmentsRowModel::createResourceIndex( int row, int column, ResourceGroup *g )
1637{
1638 Resource *res = g->resourceAt( row );
1639 Private *p = m_datamap.value( (void*)res );
1640 if ( p == 0 ) {
1641 Private *pg = m_datamap.value( g );
1642 Q_ASSERT( pg );
1643 p = new Private( pg, res, OT_Resource );
1644 m_datamap.insert( res, p );
1645 }
1646 QModelIndex idx = createIndex( row, column, p );
1647 Q_ASSERT( idx.isValid() );
1648 return idx;
1649}
1650
1651QModelIndex ResourceAppointmentsRowModel::createAppointmentIndex( int row, int column, Resource *r )
1652{
1653 Private *p = 0;
1654 KPlato::ObjectType type;
1655 Appointment *a = 0;
1656 if ( row < r->numAppointments( id() ) ) {
1657 a = r->appointmentAt( row, id() );
1658 type = OT_Appointment;
1659 } else {
1660 a = r->externalAppointmentList().value( row - r->numAppointments( id() ) );
1661 type = OT_External;
1662 }
1663 Q_ASSERT( a );
1664 p = m_datamap.value( (void*)a );
1665 if ( p == 0 ) {
1666 Private *pr = m_datamap.value( r );
1667 Q_ASSERT( pr );
1668 p = new Private( pr, a, type );
1669 m_datamap.insert( a, p );
1670 }
1671 QModelIndex idx = createIndex( row, column, p );
1672 Q_ASSERT( idx.isValid() );
1673 return idx;
1674}
1675
1676QModelIndex ResourceAppointmentsRowModel::createIntervalIndex( int row, int column, Appointment *a )
1677{
1678 AppointmentInterval i = a->intervalAt( row );
1679 Private *pr = m_datamap.value( a );
1680 Q_ASSERT( pr );
1681 Private *p = pr->intervalAt( row );
1682 Q_ASSERT( p );
1683
1684 QModelIndex idx = createIndex( row, column, p );
1685 Q_ASSERT( idx.isValid() );
1686 return idx;
1687}
1688
1689void ResourceAppointmentsRowModel::slotResourceToBeInserted( const ResourceGroup *group, int row )
1690{
1691 kDebug(planDbg())<<group->name()<<row;
1692 QModelIndex i = index( const_cast<ResourceGroup*>( group ) );
1693 beginInsertRows( i, row, row );
1694}
1695
1696void ResourceAppointmentsRowModel::slotResourceInserted( const Resource *r )
1697{
1698 kDebug(planDbg())<<r->name();
1699 endInsertRows();
1700
1701 connect( r, SIGNAL(externalAppointmentToBeAdded(Resource*,int)), this, SLOT(slotAppointmentToBeInserted(Resource*,int)) );
1702 connect( r, SIGNAL(externalAppointmentAdded(Resource*,Appointment*)), this, SLOT(slotAppointmentInserted(Resource*,Appointment*)) );
1703 connect( r, SIGNAL(externalAppointmentToBeRemoved(Resource*,int)), this, SLOT(slotAppointmentToBeRemoved(Resource*,int)) );
1704 connect( r, SIGNAL(externalAppointmentRemoved()), this, SLOT(slotAppointmentRemoved()) );
1705 connect( r, SIGNAL(externalAppointmentChanged(Resource*,Appointment*)), this, SLOT(slotAppointmentChanged(Resource*,Appointment*)) );
1706}
1707
1708void ResourceAppointmentsRowModel::slotResourceToBeRemoved( const Resource *r )
1709{
1710 kDebug(planDbg())<<r->name();
1711 int row = r->parentGroup()->indexOf( r );
1712
1713 beginRemoveRows( index( r->parentGroup() ), row, row );
1714 disconnect( r, SIGNAL(externalAppointmentToBeAdded(Resource*,int)), this, SLOT(slotAppointmentToBeInserted(Resource*,int)) );
1715 disconnect( r, SIGNAL(externalAppointmentAdded(Resource*,Appointment*)), this, SLOT(slotAppointmentInserted(Resource*,Appointment*)) );
1716 disconnect( r, SIGNAL(externalAppointmentToBeRemoved(Resource*,int)), this, SLOT(slotAppointmentToBeRemoved(Resource*,int)) );
1717 disconnect( r, SIGNAL(externalAppointmentRemoved()), this, SLOT(slotAppointmentRemoved()) );
1718 disconnect( r, SIGNAL(externalAppointmentChanged(Resource*,Appointment*)), this, SLOT(slotAppointmentChanged(Resource*,Appointment*)) );
1719
1720 Private *p = 0;
1721 foreach ( Appointment *a, r->appointments( id() ) ) {
1722 // remove appointment
1723 p = m_datamap.value( a );
1724 if ( p ) {
1725 m_datamap.remove( a );
1726 delete p;
1727 }
1728 }
1729 foreach ( Appointment *a, r->externalAppointmentList() ) {
1730 // remove appointment
1731 p = m_datamap.value( a );
1732 if ( p ) {
1733 m_datamap.remove( a );
1734 delete p;
1735 }
1736 }
1737 // remove resource
1738 p = m_datamap.value( (void*)r );
1739 if ( p ) {
1740 m_datamap.remove( const_cast<Resource*>( r ) );
1741 delete p;
1742 }
1743}
1744
1745void ResourceAppointmentsRowModel::slotResourceRemoved( const Resource *resource )
1746{
1747 Q_UNUSED(resource);
1748 //kDebug(planDbg())<<resource->name();
1749 endRemoveRows();
1750}
1751
1752void ResourceAppointmentsRowModel::slotResourceGroupToBeInserted( const ResourceGroup *group, int row )
1753{
1754 Q_UNUSED(group);
1755 beginInsertRows( QModelIndex(), row, row );
1756}
1757
1758void ResourceAppointmentsRowModel::slotResourceGroupInserted( const ResourceGroup*/*group*/ )
1759{
1760 endInsertRows();
1761}
1762
1763void ResourceAppointmentsRowModel::slotResourceGroupToBeRemoved( const ResourceGroup *group )
1764{
1765 //kDebug(planDbg())<<group->name()<<endl;
1766 int row = m_project->indexOf( const_cast<ResourceGroup*>( group ) );
1767 beginRemoveRows( QModelIndex(), row, row );
1768
1769 Private *p = m_datamap.value( const_cast<ResourceGroup*>( group ) );
1770 if ( p ) {
1771 m_datamap.remove( const_cast<ResourceGroup*>( group ) );
1772 delete p;
1773 }
1774}
1775
1776void ResourceAppointmentsRowModel::slotResourceGroupRemoved( const ResourceGroup *group )
1777{
1778 Q_UNUSED(group);
1779 //kDebug(planDbg())<<group->name();
1780 endRemoveRows();
1781}
1782
1783void ResourceAppointmentsRowModel::slotAppointmentToBeInserted( Resource *r, int row )
1784{
1785 Q_UNUSED(r);
1786 Q_UNUSED(row);
1787 // external appointments only, (Internal handled in slotProjectCalculated)
1788}
1789
1790void ResourceAppointmentsRowModel::slotAppointmentInserted( Resource *r, Appointment *a )
1791{
1792 Q_UNUSED(a);
1793 // external appointments only, (Internal handled in slotProjectCalculated)
1794 Private *p = m_datamap.value( r );
1795 if ( p ) {
1796 p->externalCached = false;
1797 }
1798 reset();
1799}
1800
1801void ResourceAppointmentsRowModel::slotAppointmentToBeRemoved( Resource *r, int row )
1802{
1803 Q_UNUSED(row);
1804 // external appointments only, (Internal handled in slotProjectCalculated)
1805 Private *p = m_datamap.value( r );
1806 if ( p ) {
1807 p->externalCached = false;
1808 }
1809}
1810
1811void ResourceAppointmentsRowModel::slotAppointmentRemoved()
1812{
1813 // external appointments only, (Internal handled in slotProjectCalculated)
1814 reset();
1815}
1816
1817void ResourceAppointmentsRowModel::slotAppointmentChanged( Resource *r, Appointment *a )
1818{
1819 Q_UNUSED(r);
1820 Q_UNUSED(a);
1821 // external appointments only, (Internal handled in slotProjectCalculated)
1822 // will not happen atm
1823}
1824
1825void ResourceAppointmentsRowModel::slotProjectCalculated( ScheduleManager *sm )
1826{
1827 if ( sm == m_manager ) {
1828 setScheduleManager( sm );
1829 }
1830}
1831
1832ResourceGroup *ResourceAppointmentsRowModel::parentGroup( const QModelIndex &index ) const
1833{
1834 if ( m_project == 0 ) {
1835 return 0;
1836 }
1837 Private *ch = static_cast<Private*>( index.internalPointer() );
1838 if ( ch && ch->type == OT_Resource ) {
1839 return static_cast<ResourceGroup*>( ch->parent->ptr );
1840 }
1841 return 0;
1842}
1843
1844ResourceGroup *ResourceAppointmentsRowModel::resourcegroup( const QModelIndex &index ) const
1845{
1846 if ( m_project == 0 ) {
1847 return 0;
1848 }
1849 Private *p = static_cast<Private*>( index.internalPointer() );
1850 if ( p && p->type == OT_ResourceGroup ) {
1851 return static_cast<ResourceGroup*>( p->ptr );
1852 }
1853 return 0;
1854}
1855
1856Resource *ResourceAppointmentsRowModel::parentResource( const QModelIndex &index ) const
1857{
1858 if ( m_project == 0 ) {
1859 return 0;
1860 }
1861 Private *ch = static_cast<Private*>( index.internalPointer() );
1862 if ( ch && ( ch->type == OT_Appointment || ch->type == OT_External ) ) {
1863 return static_cast<Resource*>( ch->parent->ptr );
1864 }
1865 return 0;
1866}
1867
1868
1869Resource *ResourceAppointmentsRowModel::resource( const QModelIndex &index ) const
1870{
1871 if ( m_project == 0 ) {
1872 return 0;
1873 }
1874 Private *p = static_cast<Private*>( index.internalPointer() );
1875 if ( p && p->type == OT_Resource ) {
1876 return static_cast<Resource*>( p->ptr );
1877 }
1878 return 0;
1879}
1880
1881Appointment *ResourceAppointmentsRowModel::parentAppointment( const QModelIndex &index ) const
1882{
1883 if ( m_project == 0 || m_manager == 0 ) {
1884 return 0;
1885 }
1886 Private *ch = static_cast<Private*>( index.internalPointer() );
1887 if ( ch && ch->type == OT_Interval ) {
1888 return static_cast<Appointment*>( ch->parent->ptr );
1889 }
1890 return 0;
1891}
1892
1893Appointment *ResourceAppointmentsRowModel::appointment( const QModelIndex &index ) const
1894{
1895 if ( m_project == 0 || m_manager == 0 || ! index.isValid() ) {
1896 return 0;
1897 }
1898 Private *p = static_cast<Private*>( index.internalPointer() );
1899 if ( p && ( p->type == OT_Appointment || p->type == OT_External ) ) {
1900 return static_cast<Appointment*>( p->ptr );
1901 }
1902 return 0;
1903}
1904
1905AppointmentInterval *ResourceAppointmentsRowModel::interval( const QModelIndex &index ) const
1906{
1907 if ( m_project == 0 || m_manager == 0 ) {
1908 return 0;
1909 }
1910 Private *p = static_cast<Private*>( index.internalPointer() );
1911 if ( p && p->type == OT_Interval ) {
1912 return &( p->interval );
1913 }
1914 return 0;
1915}
1916
1917Node *ResourceAppointmentsRowModel::node( const QModelIndex &idx ) const
1918{
1919 Appointment *a = appointment( idx );
1920 return ( a && a->node() ? a->node()->node() : 0 );
1921}
1922
1923
1924//---------------------------------------------
1925ResourceAppointmentsGanttModel::ResourceAppointmentsGanttModel( QObject *parent )
1926 : ResourceAppointmentsRowModel( parent )
1927{
1928}
1929
1930ResourceAppointmentsGanttModel::~ResourceAppointmentsGanttModel()
1931{
1932}
1933
1934QVariant ResourceAppointmentsGanttModel::data( const ResourceGroup *g, int column, int role ) const
1935{
1936 Q_UNUSED(column);
1937 switch( role ) {
1938 case KDGantt::ItemTypeRole: return KDGantt::TypeSummary;
1939 case KDGantt::StartTimeRole: return g->startTime( id() );
1940 case KDGantt::EndTimeRole: return g->endTime( id() );
1941 }
1942 return QVariant();
1943}
1944
1945QVariant ResourceAppointmentsGanttModel::data( const Resource *r, int column, int role ) const
1946{
1947 Q_UNUSED(column);
1948 switch( role ) {
1949 case KDGantt::ItemTypeRole: return KDGantt::TypeSummary;
1950 case KDGantt::StartTimeRole: return r->startTime( id() );
1951 case KDGantt::EndTimeRole: return r->endTime( id() );
1952 }
1953 return QVariant();
1954}
1955
1956QVariant ResourceAppointmentsGanttModel::data( const Appointment *a, int column, int role ) const
1957{
1958 Q_UNUSED(column);
1959 switch( role ) {
1960 case KDGantt::ItemTypeRole: return KDGantt::TypeMulti;
1961 case KDGantt::StartTimeRole: return a->startTime();
1962 case KDGantt::EndTimeRole: return a->endTime();
1963 }
1964 return QVariant();
1965}
1966
1967QVariant ResourceAppointmentsGanttModel::data( const AppointmentInterval *a, int column, int role ) const
1968{
1969 Q_UNUSED(column);
1970 switch( role ) {
1971 case KDGantt::ItemTypeRole: return KDGantt::TypeTask;
1972 case KDGantt::StartTimeRole: return a->startTime();
1973 case KDGantt::EndTimeRole: return a->endTime();
1974 }
1975 return QVariant();
1976}
1977
1978QVariant ResourceAppointmentsGanttModel::data( const QModelIndex &index, int role ) const
1979{
1980 //kDebug(planDbg())<<index<<role;
1981 if ( m_project == 0 || ! index.isValid() ) {
1982 return QVariant();
1983 }
1984 if ( role == KDGantt::ItemTypeRole ||
1985 role == KDGantt::StartTimeRole ||
1986 role == KDGantt::EndTimeRole ||
1987 role == KDGantt::TaskCompletionRole )
1988 {
1989 if ( ResourceGroup *g = resourcegroup( index ) ) {
1990 return data( g, index.column(), role );
1991 }
1992 if ( Resource *r = resource( index ) ) {
1993 return data( r, index.column(), role );
1994 }
1995 if ( m_manager == 0 ) {
1996 return QVariant();
1997 }
1998 if ( Appointment *a = appointment( index ) ) {
1999 return data( a, index.column(), role );
2000 }
2001 if ( AppointmentInterval *i = interval( index ) ) {
2002 return data( i, index.column(), role );
2003 }
2004 return QVariant();
2005 }
2006 return ResourceAppointmentsRowModel::data( index, role );
2007}
2008
2009} // namespace KPlato
2010
2011#include "kptresourceappointmentsmodel.moc"
2012