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