1 | /* This file is part of the KDE project |
2 | Copyright (C) 2005 - 2011 Dag Andersen <danders@get2net.dk> |
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 | #ifndef KPTSCHEDULE_H |
21 | #define KPTSCHEDULE_H |
22 | |
23 | #include "kplatokernel_export.h" |
24 | |
25 | #include "kptglobal.h" |
26 | #include "kptcalendar.h" |
27 | #include "kpteffortcostmap.h" |
28 | #include "kptresource.h" |
29 | |
30 | #include <QList> |
31 | #include <QMap> |
32 | #include <QString> |
33 | |
34 | //#include "KoXmlReaderForward.h" |
35 | class QDomElement; |
36 | class QStringList; |
37 | |
38 | |
39 | /// The main namespace |
40 | namespace KPlato |
41 | { |
42 | |
43 | class Appointment; |
44 | class DateTime; |
45 | class Duration; |
46 | class Node; |
47 | class Project; |
48 | class Task; |
49 | class ScheduleManager; |
50 | class XMLLoaderObject; |
51 | class SchedulerPlugin; |
52 | class KPlatoXmlLoaderBase; |
53 | |
54 | /// Caches effortcost data (bcws, bcwp, acwp) |
55 | class EffortCostCache { |
56 | public: |
57 | EffortCostCache() : cached( false ) {} |
58 | bool cached; |
59 | EffortCostMap effortcostmap; |
60 | }; |
61 | |
62 | /** |
63 | * The Schedule class holds data calculated during project |
64 | * calculation and scheduling, eg start- and end-times and |
65 | * appointments. |
66 | * There is one Schedule per node (tasks and project ) and one per resource. |
67 | * Schedule is subclassed into: |
68 | * MainSchedule Used by the main project. |
69 | * NodeSchedule Used by all other nodes (tasks). |
70 | * ResourceSchedule Used by resources. |
71 | */ |
72 | class KPLATOKERNEL_EXPORT Schedule |
73 | { |
74 | public: |
75 | //NOTE: Must match Effort::Use atm. |
76 | enum Type { Expected = 0 //Effort::Use_Expected |
77 | }; |
78 | |
79 | Schedule(); |
80 | explicit Schedule(Schedule *parent); |
81 | Schedule( const QString& name, Type type, long id ); |
82 | virtual ~Schedule(); |
83 | |
84 | QString name() const { return m_name; } |
85 | void setName( const QString& name ) { m_name = name; } |
86 | Type type() const { return m_type; } |
87 | void setType( Type type ) { m_type = type; } |
88 | void setType( const QString& type ); |
89 | QString typeToString( bool translate = false ) const; |
90 | long id() const { return m_id; } |
91 | void setId( long id ) { m_id = id; } |
92 | void setParent( Schedule *parent ); |
93 | Schedule *parent() const { return m_parent; } |
94 | virtual bool isDeleted() const; |
95 | virtual void setDeleted( bool on ); |
96 | virtual bool recalculate() const { return m_parent == 0 ? false : m_parent->recalculate(); } |
97 | virtual DateTime recalculateFrom() const { return m_parent == 0 ? DateTime() : m_parent->recalculateFrom(); } |
98 | |
99 | virtual long parentScheduleId() const { return m_parent == 0 ? NOTSCHEDULED : m_parent->parentScheduleId(); } |
100 | |
101 | virtual Resource *resource() const { return 0; } |
102 | virtual Node *node() const { return 0; } |
103 | |
104 | virtual bool isBaselined() const; |
105 | virtual bool usePert() const; |
106 | |
107 | enum OBState { OBS_Parent, OBS_Allow, OBS_Deny }; |
108 | /// Sets whether overbooking resources is allowed locally for this schedule |
109 | /// If @p state is OBS_Parent, the parent is checked when allowOverbooking() is called |
110 | virtual void setAllowOverbookingState( OBState state ); |
111 | OBState allowOverbookingState() const; |
112 | virtual bool allowOverbooking() const; |
113 | virtual bool checkExternalAppointments() const; |
114 | |
115 | bool isCritical() const { return positiveFloat == Duration::zeroDuration; } |
116 | |
117 | virtual bool loadXML( const KoXmlElement &element, XMLLoaderObject &status ); |
118 | virtual void saveXML( QDomElement &element ) const; |
119 | void saveCommonXML( QDomElement &element ) const; |
120 | void saveAppointments( QDomElement &element ) const; |
121 | |
122 | /// Return the effort available in the @p interval |
123 | virtual Duration effort( const DateTimeInterval &interval ) const; |
124 | virtual DateTimeInterval available( const DateTimeInterval &interval ) const; |
125 | |
126 | enum CalculationMode { Scheduling, CalculateForward, CalculateBackward }; |
127 | /// Set calculation mode |
128 | void setCalculationMode( int mode ) { m_calculationMode = mode; } |
129 | /// Return calculation mode |
130 | int calculationMode() const { return m_calculationMode; } |
131 | /// Return the list of appointments |
132 | QList<Appointment*> appointments() const { return m_appointments; } |
133 | /// Return true if the @p which list is not empty |
134 | bool hasAppointments( int which ) const; |
135 | /// Return the list of appointments |
136 | /// @param which specifies which list is returned |
137 | QList<Appointment*> appointments(int which) const; |
138 | /// Adds appointment to this schedule only |
139 | virtual bool add( Appointment *appointment ); |
140 | /// Adds appointment to both this resource schedule and node schedule |
141 | virtual void addAppointment( Schedule * /*other*/, const DateTime & /*start*/, const DateTime & /*end*/, double /*load*/ = 100 ) {} |
142 | /// Removes appointment without deleting it. |
143 | virtual void takeAppointment( Appointment *appointment, int type = Scheduling ); |
144 | Appointment *findAppointment( Schedule *resource, Schedule *node, int type = Scheduling ); |
145 | /// Attach the appointment to appropriate list (appointment->calculationMode() specifies list) |
146 | bool attatch( Appointment *appointment ); |
147 | |
148 | DateTime appointmentStartTime() const; |
149 | DateTime appointmentEndTime() const; |
150 | |
151 | virtual Appointment appointmentIntervals( int which = Scheduling, const DateTimeInterval &interval = DateTimeInterval() ) const; |
152 | void copyAppointments( CalculationMode from, CalculationMode to ); |
153 | |
154 | virtual bool isOverbooked() const { return false; } |
155 | virtual bool isOverbooked( const DateTime & /*start*/, const DateTime & /*end*/ ) const { return false; } |
156 | virtual QStringList overbookedResources() const; |
157 | /// Returns the first booked interval to @p node that intersects @p interval (limited to @p interval) |
158 | virtual DateTimeInterval firstBookedInterval( const DateTimeInterval &interval, const Schedule *node ) const; |
159 | |
160 | /// Return the resources that has appointments to this schedule |
161 | virtual QList<Resource*> resources() const; |
162 | /// Return the resource names that has appointments to this schedule |
163 | virtual QStringList resourceNameList() const; |
164 | |
165 | virtual EffortCostMap bcwsPrDay( EffortCostCalculationType type = ECCT_All ); |
166 | virtual EffortCostMap bcwsPrDay( EffortCostCalculationType type = ECCT_All ) const; |
167 | virtual EffortCostMap plannedEffortCostPrDay( const QDate &start, const QDate &end, EffortCostCalculationType type = ECCT_All ) const; |
168 | virtual EffortCostMap plannedEffortCostPrDay( const Resource *resource, const QDate &start, const QDate &end, EffortCostCalculationType type = ECCT_All ) const; |
169 | |
170 | /// Returns the total planned effort for @p resource this schedule |
171 | virtual Duration plannedEffort( const Resource *resource, EffortCostCalculationType type = ECCT_All) const; |
172 | /// Returns the total planned effort for this schedule |
173 | virtual Duration plannedEffort( EffortCostCalculationType type = ECCT_All) const; |
174 | /// Returns the total planned effort for this schedule on date |
175 | virtual Duration plannedEffort( const QDate &date, EffortCostCalculationType type = ECCT_All ) const; |
176 | /// Returns the planned effort for @p resource on the @p date date |
177 | virtual Duration plannedEffort( const Resource *resource, const QDate &date, EffortCostCalculationType type = ECCT_All ) const; |
178 | /// Returns the planned effort up to and including date |
179 | virtual Duration plannedEffortTo( const QDate &date, EffortCostCalculationType type = ECCT_All ) const; |
180 | /// Returns the planned effort for @p resource up to and including date |
181 | virtual Duration plannedEffortTo( const Resource *resource, const QDate &date, EffortCostCalculationType type = ECCT_All ) const; |
182 | |
183 | /** |
184 | * Planned cost is the sum total of all resources and other costs |
185 | * planned for this node. |
186 | */ |
187 | virtual EffortCost plannedCost( EffortCostCalculationType type = ECCT_All ) const; |
188 | |
189 | /// Planned cost on date |
190 | virtual double plannedCost( const QDate &date, EffortCostCalculationType type = ECCT_All ) const; |
191 | /** |
192 | * Planned cost from start of activity up to and including date |
193 | * is the sum of all resource costs and other costs planned for this schedule. |
194 | */ |
195 | virtual double plannedCostTo( const QDate &date, EffortCostCalculationType type = ECCT_All ) const; |
196 | |
197 | virtual double normalRatePrHour() const { return 0.0; } |
198 | |
199 | void setEarliestStart( DateTime &dt ) { earlyStart = dt; } |
200 | void setLatestFinish( DateTime &dt ) { lateFinish = dt; } |
201 | |
202 | virtual void initiateCalculation(); |
203 | virtual void calcResourceOverbooked(); |
204 | |
205 | virtual void insertHardConstraint( Node * ) {} |
206 | virtual void insertSoftConstraint( Node * ) {} |
207 | virtual void insertForwardNode( Node *node ); |
208 | virtual void insertBackwardNode( Node *node ); |
209 | virtual void insertStartNode( Node * ) {} |
210 | virtual void insertEndNode( Node * ) {} |
211 | virtual void insertSummaryTask( Node * ) {} |
212 | |
213 | void setScheduled( bool on ); |
214 | bool isScheduled() const { return !notScheduled; } |
215 | |
216 | DateTime start() const { return startTime; } |
217 | DateTime end() const { return endTime; } |
218 | |
219 | QStringList state() const; |
220 | |
221 | void setResourceError( bool on ) { resourceError = on; } |
222 | void setResourceOverbooked( bool on ) { resourceOverbooked = on; } |
223 | void setResourceNotAvailable( bool on ) { resourceNotAvailable = on; } |
224 | void setConstraintError( bool on ) { constraintError = on; } |
225 | void setNotScheduled( bool on ) { notScheduled = on; } |
226 | void setSchedulingError( bool on ) { schedulingError = on; } |
227 | |
228 | void setPositiveFloat( const Duration &f ) { positiveFloat = f; } |
229 | void setNegativeFloat( const Duration &f ) { negativeFloat = f; } |
230 | void setFreeFloat( const Duration &f ) { freeFloat = f; } |
231 | |
232 | void setInCriticalPath( bool on = true ) { inCriticalPath = on; } |
233 | |
234 | virtual ScheduleManager *manager() const { return 0; } |
235 | |
236 | class KPLATOKERNEL_EXPORT Log { |
237 | public: |
238 | enum Type { Type_Debug = 0, Type_Info, Type_Warning, Type_Error }; |
239 | Log() |
240 | : node( 0 ), resource( 0 ), severity( 0 ), phase( -1 ) |
241 | {} |
242 | Log( const Node *n, int sev, const QString &msg, int ph = -1 ); |
243 | Log( const Node *n, const Resource *r, int sev, const QString &msg, int ph = -1 ); |
244 | Log( const Log &other ); |
245 | |
246 | Log &operator=( const Log &other ); |
247 | |
248 | const Node *node; |
249 | const Resource *resource; |
250 | QString message; |
251 | int severity; |
252 | int phase; |
253 | |
254 | QString formatMsg() const; |
255 | }; |
256 | virtual void addLog( Log &log ); |
257 | virtual void clearLogs() {}; |
258 | virtual void logError( const QString &, int = -1 ) {} |
259 | virtual void logWarning( const QString &, int = -1 ) {} |
260 | virtual void logInfo( const QString &, int = -1 ) {} |
261 | virtual void logDebug( const QString &, int = -1 ) {} |
262 | |
263 | virtual void incProgress() { if ( m_parent ) m_parent->incProgress(); } |
264 | |
265 | void clearPerformanceCache(); |
266 | |
267 | protected: |
268 | virtual void changed( Schedule * /*sch*/ ) {} |
269 | |
270 | protected: |
271 | QString m_name; |
272 | Type m_type; |
273 | long m_id; |
274 | bool m_deleted; |
275 | Schedule *m_parent; |
276 | OBState m_obstate; |
277 | |
278 | int m_calculationMode; |
279 | QList<Appointment*> m_appointments; |
280 | QList<Appointment*> m_forward; |
281 | QList<Appointment*> m_backward; |
282 | |
283 | friend class Node; |
284 | friend class Task; |
285 | friend class Project; |
286 | friend class Resource; |
287 | friend class RecalculateProjectCmd; |
288 | friend class ScheduleManager; |
289 | friend class KPlatoXmlLoaderBase; |
290 | /** |
291 | * earlyStart is calculated by PERT/CPM. |
292 | * A task may be scheduled to start later because of constraints |
293 | * or resource availability etc. |
294 | */ |
295 | DateTime earlyStart; |
296 | /** |
297 | * lateStart is calculated by PERT/CPM. |
298 | * A task may not be scheduled to start later. |
299 | */ |
300 | DateTime lateStart; |
301 | /** |
302 | * earlyFinish is calculated by PERT/CPM. |
303 | * A task may not be scheduled to finish earlier. |
304 | */ |
305 | DateTime earlyFinish; |
306 | /** |
307 | * lateFinish is calculated by PERT/CPM. |
308 | * A task may be scheduled to finish earlier because of constraints |
309 | * or resource availability etc. |
310 | */ |
311 | DateTime lateFinish; |
312 | /** startTime is the scheduled start time. |
313 | * It depends on constraints (i.e. ASAP/ALAP) and resource availability. |
314 | * It will always be later or equal to earliestStart |
315 | */ |
316 | DateTime startTime; |
317 | /** |
318 | * m_endTime is the scheduled finish time. |
319 | * It depends on constraints (i.e. ASAP/ALAP) and resource availability. |
320 | * It will always be earlier or equal to latestFinish |
321 | */ |
322 | DateTime endTime; |
323 | /** |
324 | * duration is the scheduled duration which depends on |
325 | * e.g. estimated effort, allocated resources and risk |
326 | */ |
327 | Duration duration; |
328 | |
329 | /// Set if EffortType == Effort, but no resource is requested |
330 | bool resourceError; |
331 | /// Set if the assigned resource is overbooked |
332 | bool resourceOverbooked; |
333 | /// Set if the requested resource is not available |
334 | bool resourceNotAvailable; |
335 | /// Set if the task cannot be scheduled to fullfil all the constraints |
336 | bool constraintError; |
337 | /// Set if the node has not been scheduled |
338 | bool notScheduled; |
339 | /// Set if the assigned resource cannot deliver the requered estimated effort |
340 | bool effortNotMet; |
341 | /// Set if some other scheduling error occurs |
342 | bool schedulingError; |
343 | |
344 | DateTime workStartTime; |
345 | DateTime workEndTime; |
346 | bool inCriticalPath; |
347 | |
348 | Duration positiveFloat; |
349 | Duration negativeFloat; |
350 | Duration freeFloat; |
351 | |
352 | EffortCostCache &bcwsPrDayCache( int type ) { |
353 | return m_bcwsPrDay[ type ]; |
354 | } |
355 | EffortCostCache &bcwpPrDayCache( int type ) { |
356 | return m_bcwpPrDay[ type ]; |
357 | } |
358 | EffortCostCache &acwpCache( int type ) { |
359 | return m_acwp[ type ]; |
360 | } |
361 | QMap<int, EffortCostCache> m_bcwsPrDay; |
362 | QMap<int, EffortCostCache> m_bcwpPrDay; |
363 | QMap<int, EffortCostCache> m_acwp; |
364 | }; |
365 | |
366 | /** |
367 | * NodeSchedule holds scheduling information for a node (task). |
368 | * |
369 | */ |
370 | class KPLATOKERNEL_EXPORT NodeSchedule : public Schedule |
371 | { |
372 | public: |
373 | NodeSchedule(); |
374 | NodeSchedule( Node *node, const QString& name, Schedule::Type type, long id ); |
375 | NodeSchedule( Schedule *parent, Node *node ); |
376 | virtual ~NodeSchedule(); |
377 | |
378 | virtual bool isDeleted() const |
379 | { return m_parent == 0 ? true : m_parent->isDeleted(); } |
380 | void setDeleted( bool on ); |
381 | |
382 | virtual bool loadXML( const KoXmlElement &element, XMLLoaderObject &status ); |
383 | virtual void saveXML( QDomElement &element ) const; |
384 | |
385 | // tasks------------> |
386 | virtual void addAppointment( Schedule *resource, const DateTime &start, const DateTime &end, double load = 100 ); |
387 | virtual void takeAppointment( Appointment *appointment, int type = Schedule::Scheduling ); |
388 | |
389 | virtual Node *node() const { return m_node; } |
390 | virtual void setNode( Node *n ) { m_node = n; } |
391 | |
392 | /// Return the resources that has appointments to this schedule |
393 | virtual QList<Resource*> resources() const; |
394 | /// Return the resource names that has appointments to this schedule |
395 | virtual QStringList resourceNameList() const; |
396 | |
397 | virtual void logError( const QString &msg, int phase = -1 ); |
398 | virtual void logWarning( const QString &msg, int phase = -1 ); |
399 | virtual void logInfo( const QString &msg, int phase = -1 ); |
400 | virtual void logDebug( const QString &, int = -1 ); |
401 | |
402 | protected: |
403 | void init(); |
404 | |
405 | private: |
406 | Node *m_node; |
407 | }; |
408 | |
409 | /** |
410 | * ResourceSchedule holds scheduling information for a resource. |
411 | * |
412 | */ |
413 | class KPLATOKERNEL_EXPORT ResourceSchedule : public Schedule |
414 | { |
415 | public: |
416 | ResourceSchedule(); |
417 | ResourceSchedule( Resource *Resource, const QString& name, Schedule::Type type, long id ); |
418 | ResourceSchedule( Schedule *parent, Resource *Resource ); |
419 | virtual ~ResourceSchedule(); |
420 | |
421 | virtual bool isDeleted() const |
422 | { return m_parent == 0 ? true : m_parent->isDeleted(); } |
423 | virtual void addAppointment( Schedule *node, const DateTime &start, const DateTime &end, double load = 100 ); |
424 | virtual void takeAppointment( Appointment *appointment, int type = Scheduling ); |
425 | |
426 | virtual bool isOverbooked() const; |
427 | virtual bool isOverbooked( const DateTime &start, const DateTime &end ) const; |
428 | |
429 | virtual Resource *resource() const { return m_resource; } |
430 | virtual double normalRatePrHour() const; |
431 | |
432 | /// Return the effort available in the @p interval |
433 | virtual Duration effort( const DateTimeInterval &interval ) const; |
434 | virtual DateTimeInterval available( const DateTimeInterval &interval ) const; |
435 | |
436 | virtual void logError( const QString &msg, int phase = -1 ); |
437 | virtual void logWarning( const QString &msg, int phase = -1 ); |
438 | virtual void logInfo( const QString &msg, int phase = -1 ); |
439 | virtual void logDebug( const QString &, int = -1 ); |
440 | |
441 | void setNodeSchedule( const Schedule *sch ) { m_nodeSchedule = sch; } |
442 | |
443 | private: |
444 | Resource *m_resource; |
445 | Schedule *m_parent; |
446 | const Schedule *m_nodeSchedule; // used during scheduling |
447 | }; |
448 | |
449 | /** |
450 | * MainSchedule holds scheduling information for the main project node. |
451 | * |
452 | */ |
453 | class KPLATOKERNEL_EXPORT MainSchedule : public NodeSchedule |
454 | { |
455 | public: |
456 | MainSchedule(); |
457 | MainSchedule( Node *node, const QString& name, Schedule::Type type, long id ); |
458 | ~MainSchedule(); |
459 | virtual bool isDeleted() const { return m_deleted; } |
460 | |
461 | virtual bool isBaselined() const; |
462 | virtual bool allowOverbooking() const; |
463 | virtual bool checkExternalAppointments() const; |
464 | virtual bool usePert() const; |
465 | |
466 | virtual bool loadXML( const KoXmlElement &element, XMLLoaderObject &status ); |
467 | virtual void saveXML( QDomElement &element ) const; |
468 | |
469 | void setManager( ScheduleManager *sm ) { m_manager = sm; } |
470 | ScheduleManager *manager() const { return m_manager; } |
471 | virtual bool recalculate() const; |
472 | virtual DateTime recalculateFrom() const; |
473 | virtual long parentScheduleId() const; |
474 | |
475 | DateTime calculateForward( int use ); |
476 | DateTime calculateBackward( int use ); |
477 | DateTime scheduleForward( const DateTime &earliest, int use ); |
478 | DateTime scheduleBackward( const DateTime &latest, int use ); |
479 | |
480 | void clearNodes() { |
481 | m_hardconstraints.clear(); |
482 | m_softconstraints.clear(); |
483 | m_forwardnodes.clear(); |
484 | m_backwardnodes.clear(); |
485 | m_startNodes.clear(); |
486 | m_endNodes.clear(); |
487 | m_summarytasks.clear(); |
488 | } |
489 | virtual void insertHardConstraint( Node *node ) { m_hardconstraints.append( node ); } |
490 | QList<Node*> hardConstraints() const { return m_hardconstraints; } |
491 | virtual void insertSoftConstraint( Node *node ) { m_softconstraints.append( node ); } |
492 | QList<Node*> softConstraints() const { return m_softconstraints; } |
493 | QList<Node*> forwardNodes() const { return m_forwardnodes; } |
494 | virtual void insertForwardNode( Node *node ) { m_forwardnodes.append( node ); } |
495 | QList<Node*> backwardNodes() const { return m_backwardnodes; } |
496 | virtual void insertBackwardNode( Node *node ) { m_backwardnodes.append( node ); } |
497 | virtual void insertStartNode( Node *node ) { m_startNodes.append( node ); } |
498 | QList<Node*> startNodes() const { return m_startNodes; } |
499 | virtual void insertEndNode( Node *node ) { m_endNodes.append( node ); } |
500 | QList<Node*> endNodes() const { return m_endNodes; } |
501 | virtual void insertSummaryTask( Node *node ) { m_summarytasks.append( node ); } |
502 | QList<Node*> summaryTasks() const { return m_summarytasks; } |
503 | |
504 | void clearCriticalPathList(); |
505 | QList<Node*> *currentCriticalPath() const; |
506 | void addCriticalPath( QList<Node*> *lst = 0 ); |
507 | const QList< QList<Node*> > *criticalPathList() const { return &(m_pathlists); } |
508 | QList<Node*> criticalPath( int index = 0 ) { |
509 | QList<Node*> lst; |
510 | return m_pathlists.count() <= index ? lst : m_pathlists[ index ]; |
511 | } |
512 | void addCriticalPathNode( Node *node ); |
513 | |
514 | QList<Schedule::Log> logs() const; |
515 | void setLog( const QList<Schedule::Log> &log ) { m_log = log; } |
516 | virtual void addLog( Schedule::Log &log ); |
517 | virtual void clearLogs() { m_log.clear(); m_logPhase.clear(); } |
518 | |
519 | void setPhaseName( int phase, const QString &name ) { m_logPhase[ phase ] = name; } |
520 | QString logPhase( int phase ) const { return m_logPhase.value( phase ); } |
521 | static QString logSeverity( int severity ); |
522 | QMap<int, QString> phaseNames() const { return m_logPhase; } |
523 | void setPhaseNames( const QMap<int, QString> &pn ) { m_logPhase = pn; } |
524 | |
525 | virtual void incProgress(); |
526 | |
527 | QStringList logMessages() const; |
528 | |
529 | QList< QList<Node*> > m_pathlists; |
530 | bool criticalPathListCached; |
531 | |
532 | protected: |
533 | virtual void changed( Schedule *sch ); |
534 | |
535 | private: |
536 | friend class Project; |
537 | |
538 | ScheduleManager *m_manager; |
539 | QList<Node*> m_hardconstraints; |
540 | QList<Node*> m_softconstraints; |
541 | QList<Node*> m_forwardnodes; |
542 | QList<Node*> m_backwardnodes; |
543 | QList<Node*> m_startNodes; |
544 | QList<Node*> m_endNodes; |
545 | QList<Node*> m_summarytasks; |
546 | |
547 | QList<Node*> *m_currentCriticalPath; |
548 | |
549 | |
550 | QList<Schedule::Log> m_log; |
551 | QMap<int, QString> m_logPhase; |
552 | }; |
553 | |
554 | /** |
555 | * ScheduleManager is used by the Project class to manage the schedules. |
556 | * The ScheduleManager is the bases for the user interface to scheduling. |
557 | * A ScheduleManager can have child manager(s). |
558 | */ |
559 | class KPLATOKERNEL_EXPORT ScheduleManager : public QObject |
560 | { |
561 | Q_OBJECT |
562 | public: |
563 | enum CalculationResult { CalculationRunning = 0, CalculationDone, CalculationStopped, CalculationCanceled, CalculationError }; |
564 | |
565 | explicit ScheduleManager( Project &project, const QString name = QString() ); |
566 | ~ScheduleManager(); |
567 | |
568 | void setName( const QString& name ); |
569 | QString name() const { return m_name; } |
570 | |
571 | void setManagerId( const QString &id ) { m_id = id; } |
572 | QString managerId() const { return m_id; } |
573 | |
574 | Project &project() const { return m_project; } |
575 | |
576 | void setParentManager( ScheduleManager *sm, int index = -1 ); |
577 | ScheduleManager *parentManager() const { return m_parent; } |
578 | |
579 | long scheduleId() const { return m_expected == 0 ? NOTSCHEDULED : m_expected->id(); } |
580 | |
581 | int removeChild( const ScheduleManager *sm ); |
582 | void insertChild( ScheduleManager *sm, int index = -1 ); |
583 | QList<ScheduleManager*> children() const { return m_children; } |
584 | int childCount() const { return m_children.count(); } |
585 | ScheduleManager *childAt( int index ) const { return m_children.value( index ); } |
586 | /// Return list of all child managers (also childrens children) |
587 | QList<ScheduleManager*> allChildren() const; |
588 | int indexOf( const ScheduleManager* child ) const; |
589 | bool isParentOf( const ScheduleManager *sm ) const; |
590 | ScheduleManager *findManager( const QString &name ) const; |
591 | |
592 | /// This sub-schedule will be re-calculated based on the parents completion data |
593 | bool recalculate() const { return m_recalculate; } |
594 | /// Set re-calculate to @p on. |
595 | void setRecalculate( bool on ) { m_recalculate = on; } |
596 | /// The datetime this schedule will be calculated from |
597 | DateTime recalculateFrom() const { return m_recalculateFrom; } |
598 | /// Set the datetime this schedule will be calculated from to @p dt |
599 | void setRecalculateFrom( const DateTime &dt ) { m_recalculateFrom = dt; } |
600 | long parentScheduleId() const { return m_parent == 0 ? NOTSCHEDULED : m_parent->scheduleId(); } |
601 | void createSchedules(); |
602 | |
603 | void setDeleted( bool on ); |
604 | |
605 | bool isScheduled() const { return m_expected == 0 ? false : m_expected->isScheduled(); } |
606 | |
607 | void setExpected( MainSchedule *sch ); |
608 | MainSchedule *expected() const { return m_expected; } |
609 | |
610 | QStringList state() const; |
611 | |
612 | void setBaselined( bool on ); |
613 | bool isBaselined() const { return m_baselined; } |
614 | bool isChildBaselined() const; |
615 | void setAllowOverbooking( bool on ); |
616 | bool allowOverbooking() const; |
617 | |
618 | void setCheckExternalAppointments( bool on ); |
619 | bool checkExternalAppointments() const; |
620 | |
621 | void setUsePert( bool on ); |
622 | bool usePert() const { return m_usePert; } |
623 | |
624 | void setSchedulingDirection( bool on ); |
625 | bool schedulingDirection() const { return m_schedulingDirection; } |
626 | |
627 | void setScheduling( bool on ); |
628 | bool scheduling() const { return m_scheduling; } |
629 | |
630 | bool loadXML( KoXmlElement &element, XMLLoaderObject &status ); |
631 | void saveXML( QDomElement &element ) const; |
632 | |
633 | /// Save a workpackage document |
634 | void saveWorkPackageXML( QDomElement &element, const Node &node ) const; |
635 | |
636 | void scheduleChanged( MainSchedule *sch ); |
637 | |
638 | const QList<SchedulerPlugin*> schedulerPlugins() const; |
639 | QString schedulerPluginId() const; |
640 | void setSchedulerPluginId( const QString &id ); |
641 | SchedulerPlugin *schedulerPlugin() const; |
642 | QStringList schedulerPluginNames() const; |
643 | int schedulerPluginIndex() const; |
644 | void setSchedulerPlugin( int index ); |
645 | |
646 | /// Stop calculation. Use result if possible. |
647 | void stopCalculation(); |
648 | /// Terminate calculation. Forget any results. |
649 | void haltCalculation(); |
650 | void calculateSchedule(); |
651 | int calculationResult() const { return m_calculationresult; } |
652 | void setCalculationResult( int r ) { m_calculationresult = r; } |
653 | |
654 | /// Increments progress in the project |
655 | void incProgress(); |
656 | /// Returns current progress |
657 | int progress() const { return m_progress; } |
658 | /// Returns maximum progress value |
659 | int maxProgress() const { return m_maxprogress; } |
660 | |
661 | /// Log added by MainSchedule |
662 | /// Emits sigLogAdded() to enable synchronization between schedules |
663 | void logAdded( Schedule::Log &log ); |
664 | |
665 | /// Create and load a MainSchedule |
666 | MainSchedule *loadMainSchedule( KoXmlElement &element, XMLLoaderObject &status ); |
667 | |
668 | /// Load an existing MainSchedule |
669 | bool loadMainSchedule( MainSchedule *schedule, KoXmlElement &element, XMLLoaderObject &status ); |
670 | |
671 | QMap< int, QString > phaseNames() const; |
672 | |
673 | /// Return a list of the supported granularities of the current scheduler |
674 | QList<long unsigned int> supportedGranularities() const; |
675 | /// Return current index of supported granularities of the selected scheduler |
676 | int granularity() const; |
677 | /// Set current index of supported granularities of the selected scheduler |
678 | void setGranularity( int duration ); |
679 | |
680 | public slots: |
681 | /// Set maximum progress. Emits signal maxProgressChanged |
682 | void setMaxProgress( int value ); |
683 | /// Set progress. Emits signal progressChanged |
684 | void setProgress( int value ); |
685 | |
686 | /// Add the lis of logs @p log to expected() |
687 | void slotAddLog( const QList<KPlato::Schedule::Log> &log ); |
688 | |
689 | void setPhaseNames( const QMap<int, QString> &phasenames ); |
690 | |
691 | signals: |
692 | void maxProgressChanged( int ); |
693 | void progressChanged( int ); |
694 | |
695 | /// Emitted by logAdded() when new log entries are added |
696 | void logInserted( MainSchedule*, int firstrow, int lastrow ); |
697 | |
698 | /// Emitted by logAdded() |
699 | /// Used by scheduling thread |
700 | void sigLogAdded( Schedule::Log log ); |
701 | |
702 | protected: |
703 | Project &m_project; |
704 | ScheduleManager *m_parent; |
705 | QString m_name; |
706 | QString m_id; |
707 | bool m_baselined; |
708 | bool m_allowOverbooking; |
709 | bool m_checkExternalAppointments; |
710 | bool m_usePert; |
711 | bool m_recalculate; |
712 | DateTime m_recalculateFrom; |
713 | bool m_schedulingDirection; |
714 | bool m_scheduling; |
715 | int m_progress; |
716 | int m_maxprogress; |
717 | MainSchedule *m_expected; |
718 | QList<ScheduleManager*> m_children; |
719 | |
720 | QString m_schedulerPluginId; |
721 | |
722 | int m_calculationresult; |
723 | }; |
724 | |
725 | |
726 | } //namespace KPlato |
727 | |
728 | KPLATOKERNEL_EXPORT QDebug operator<<( QDebug dbg, const KPlato::Schedule *s ); |
729 | KPLATOKERNEL_EXPORT QDebug operator<<( QDebug dbg, const KPlato::Schedule &s ); |
730 | |
731 | KPLATOKERNEL_EXPORT QDebug operator<<( QDebug dbg, const KPlato::Schedule::Log &log ); |
732 | |
733 | #endif |
734 | |