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