kplato

kptnode.h

00001 /* This file is part of the KDE project
00002    Copyright (C) 2001 Thomas Zander zander@kde.org
00003    Copyright (C) 2004, 2005 Dag Andersen <danders@get2net.dk>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009 
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public License
00016    along with this library; see the file COPYING.LIB.  If not, write to
00017    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00018  * Boston, MA 02110-1301, USA.
00019 */
00020 
00021 #ifndef KPTNODE_H
00022 #define KPTNODE_H
00023 
00024 #include "kptrelation.h"
00025 #include "kptduration.h"
00026 #include "kptdatetime.h"
00027 #include "kptschedule.h"
00028 
00029 #include <qintdict.h>
00030 #include <qrect.h>
00031 #include <qptrlist.h>
00032 #include <qstring.h>
00033 #include <qcanvas.h>
00034 
00035 #include <vector>
00036 
00037 class QDomElement;
00038 
00039 namespace KPlato
00040 {
00041 
00042 class Account;
00043 class Project;
00044 class Appointment;
00045 class ResourceGroup;
00046 class Resource;
00047 class ResourceGroupRequest;
00048 class Effort;
00049 class WBSDefinition;
00050 class EffortCostMap;
00051 
00057 class Node {
00058 
00059 public:
00060     enum ConstraintType { ASAP, ALAP, MustStartOn, MustFinishOn, StartNotEarlier, FinishNotLater, FixedInterval };
00061 
00062     Node(Node *parent = 0);
00063     Node(Node &node, Node *parent = 0);
00064 
00065 
00066     // Declare the class abstract
00067     virtual ~Node() = 0;
00068 
00069     bool setId(QString id);
00070     QString id() const { return m_id; } // unique identity
00071     
00072     enum NodeTypes {
00073       Type_Node = 0,
00074       Type_Project = 1,
00075       Type_Subproject = 2,
00076       Type_Task = 3,
00077       Type_Milestone = 4,
00078       Type_Periodic = 5,
00079       Type_Summarytask = 6
00080     };
00081 
00082     virtual int type() const = 0;
00083 
00088     virtual Node *projectNode();
00089     
00090     // The load and save methods
00091     virtual bool load(QDomElement &) { return true; }
00092     virtual bool load(QDomElement &, Project &) { return true; }
00093     virtual void save(QDomElement &element) const  = 0;
00095     virtual void saveRelations(QDomElement &element) const;
00096 
00097     // simple child node management
00098     // Child nodes are things like subtasks, basically a task can exists of
00099     // several sub-tasks. Creating a table has 4 subtasks, 1) measuring
00100     // 2) cutting 3) building 4) painting.
00101     Node *getParent() const { return m_parent; }
00102     void setParent( Node* newParent ) { m_parent = newParent;}
00103     const QPtrList<Node> &childNodeIterator() const { return m_nodes; }
00104     int numChildren() const { return m_nodes.count(); }
00105     virtual void addChildNode(Node *node, Node *after=0);
00106     virtual void insertChildNode(unsigned int index, Node *node);
00107     void delChildNode(Node *node, bool remove=true);
00108     void delChildNode(int number, bool remove=true);
00109     Node* getChildNode(int number) { return m_nodes.at(number); }
00110     const Node* getChildNode(int number) const;
00111     int findChildNode( Node* node );
00112 
00113     // Time-dependent child-node-management.
00114     // list all nodes that are dependent upon this one.
00115     // Building a house requires the table to be finished, therefore the
00116     // house-building is time dependent on the table-building. So a child
00117     // of the table-building node is the house-building node.
00118 
00119     int numDependChildNodes() const { return m_dependChildNodes.count(); }
00121     virtual void addDependChildNode( Node *node, Relation::Type p=Relation::FinishStart);
00123     virtual void addDependChildNode( Node *node, Relation::Type p, Duration lag);
00125     virtual bool addDependChildNode( Relation *relation);
00127     virtual void insertDependChildNode( unsigned int index, Node *node, Relation::Type p=Relation::FinishStart);
00128     void delDependChildNode( Node *node, bool remove=false);
00129     void delDependChildNode( Relation *rel, bool remove=false);
00130     void delDependChildNode( int number, bool remove=false);
00131     Relation *getDependChildNode( int number) {
00132     return m_dependChildNodes.at(number);
00133     }
00134     QPtrList<Relation> &dependChildNodes() { return m_dependChildNodes; }
00135 
00140     void takeDependChildNode(Relation *rel);
00141     
00142     int numDependParentNodes() const { return m_dependParentNodes.count(); }
00144     virtual void addDependParentNode(Node *node, Relation::Type p=Relation::FinishStart);
00146     virtual void addDependParentNode( Node *node, Relation::Type p, Duration lag);
00148     virtual bool addDependParentNode( Relation *relation);
00150     virtual void insertDependParentNode( unsigned int index, Node *node, Relation::Type p=Relation::FinishStart);
00151     void delDependParentNode( Node *node, bool remove=false);
00152     void delDependParentNode( Relation *rel, bool remove=false);
00153     void delDependParentNode( int number, bool remove=false);
00154     Relation *getDependParentNode( int number) {
00155     return m_dependParentNodes.at(number);
00156     }
00157     QPtrList<Relation> &dependParentNodes() { return m_dependParentNodes; }
00158     
00163     void takeDependParentNode(Relation *rel);
00164 
00165     bool isParentOf(Node *node);
00166     bool isDependChildOf(Node *node);
00167 
00168     Relation *findParentRelation(Node *node);
00169     Relation *findChildRelation(Node *node);
00170     Relation *findRelation(Node *node);
00171 
00172     void setStartTime(DateTime startTime);
00174     virtual DateTime startTime() const
00175         { return m_currentSchedule ? m_currentSchedule->startTime : DateTime(); }
00176     const QDate &startDate() const { return m_dateOnlyStartDate; }
00177     void setEndTime(DateTime endTime);
00179     virtual DateTime endTime() const
00180         { return m_currentSchedule ? m_currentSchedule->endTime : DateTime(); }
00181     const QDate &endDate() const { return m_dateOnlyEndDate; }
00182 
00183     void setEffort(Effort* e) { m_effort = e; }
00184     Effort* effort() const { return m_effort; }
00185 
00189     virtual Duration *getExpectedDuration() = 0;
00190 
00196     virtual Duration *getRandomDuration() = 0;
00197 
00202     Duration *getDelay();
00203 
00209     DateTime getEarliestStart() const
00210         { return m_currentSchedule ? m_currentSchedule->earliestStart : DateTime(); }
00215     void setEarliestStart(const DateTime &dt) 
00216         { if (m_currentSchedule) m_currentSchedule->earliestStart = dt; }
00221     DateTime getLatestFinish() const 
00222         { return m_currentSchedule ? m_currentSchedule->latestFinish : DateTime(); }
00228     void setLatestFinish(const DateTime &dt) 
00229         { if (m_currentSchedule) m_currentSchedule->latestFinish = dt; }
00230 
00231     QString &name() { return m_name; }
00232     QString &leader() { return m_leader; }
00233     QString &description() { return m_description; }
00234     const QString &name() const { return m_name; }
00235     const QString &leader() const { return m_leader; }
00236     const QString &description() const { return m_description; }
00237     void setName(const QString &n) { m_name = n; }
00238     void setLeader(const QString &l) { m_leader = l; }
00239     void setDescription(const QString &d) { m_description = d; }
00240 
00241     virtual void setConstraint(Node::ConstraintType type) { m_constraint = type; }
00242     void setConstraint(QString &type);
00243     int constraint() const { return m_constraint; }
00244     QString constraintToString() const;
00245 
00246     virtual void setConstraintStartTime(QDateTime time) { m_constraintStartTime = time; }
00247     virtual void setConstraintEndTime(QDateTime time) { m_constraintEndTime = time; }
00248 
00249     virtual DateTime constraintStartTime() const { return m_constraintStartTime; }
00250     virtual DateTime constraintEndTime() const { return m_constraintEndTime; }
00251     virtual DateTime startNotEarlier() const { return m_constraintStartTime; }
00252     virtual DateTime finishNotLater() const { return m_constraintEndTime; }
00253     virtual DateTime mustStartOn() const { return m_constraintStartTime; }
00254     virtual DateTime mustFinishOn() const { return m_constraintEndTime; }
00255 
00256     virtual ResourceGroupRequest *resourceRequest(ResourceGroup */*group*/) const { return 0; }
00257     virtual void makeAppointments();
00258 
00260     bool resourceError() const 
00261         { return m_currentSchedule ? m_currentSchedule->resourceError : false; }
00263     virtual bool resourceOverbooked() const
00264         { return m_currentSchedule ? m_currentSchedule->resourceOverbooked : false; }
00267     virtual void calcResourceOverbooked();
00269     bool resourceNotAvailable() const
00270         { return m_currentSchedule ? m_currentSchedule->resourceNotAvailable : false; }
00272     virtual bool schedulingError() const
00273         { return m_currentSchedule ? m_currentSchedule->schedulingError : false; }
00275     bool notScheduled() const
00276         { return m_currentSchedule == 0 || m_currentSchedule->isDeleted() || m_currentSchedule->notScheduled; }
00277     
00278     virtual EffortCostMap plannedEffortCostPrDay(const QDate &start, const QDate &end) const=0;
00279         
00281     virtual Duration plannedEffort() { return Duration::zeroDuration; }
00283     virtual Duration plannedEffort(const QDate &) { return Duration::zeroDuration; }
00285     virtual Duration plannedEffortTo(const QDate &) { return Duration::zeroDuration; }
00286     
00288     virtual Duration actualEffort() { return Duration::zeroDuration; }
00290     virtual Duration actualEffort(const QDate &/*date*/) { return Duration::zeroDuration; }
00292     virtual Duration actualEffortTo(const QDate &/*date*/) { return Duration::zeroDuration; }
00293     
00298     virtual double plannedCost() { return 0; }
00299     
00301     virtual double plannedCost(const QDate &/*date*/) { return 0; }
00306     virtual double plannedCostTo(const QDate &/*date*/) { return 0; }
00311     virtual double actualCost() { return 0; }
00313     virtual double actualCost(const QDate &/*date*/) { return 0; }
00315     virtual double actualCostTo(const QDate &/*date*/) { return 0; }
00316     
00318     double effortPerformanceIndex(const QDate &/*date*/, bool */*error=0*/) { return 0.0; }
00320     double costPerformanceIndex(const QDate &/*date*/, bool */*error=0*/) { return 0.0; }
00321     
00322     virtual void initiateCalculationLists(QPtrList<Node> &startnodes, QPtrList<Node> &endnodes, QPtrList<Node> &summarytasks) = 0;
00323     virtual DateTime calculateForward(int /*use*/) = 0;
00324     virtual DateTime calculateBackward(int /*use*/) = 0;
00325     virtual DateTime scheduleForward(const DateTime &, int /*use*/) = 0;
00326     virtual DateTime scheduleBackward(const DateTime &, int /*use*/) = 0;
00327     virtual void adjustSummarytask() = 0;
00328 
00329     virtual void initiateCalculation(Schedule &sch);
00330     virtual void resetVisited();
00331     void propagateEarliestStart(DateTime &time);
00332     void propagateLatestFinish(DateTime &time);
00333     void moveEarliestStart(DateTime &time);
00334     void moveLatestFinish(DateTime &time);
00335     // Reimplement this
00336     virtual Duration summarytaskDurationForward(const DateTime &/*time*/) 
00337         { return Duration::zeroDuration; }
00338     // Reimplement this
00339     virtual DateTime summarytaskEarliestStart() 
00340         { return DateTime(); }
00341     // Reimplement this
00342     virtual Duration summarytaskDurationBackward(const DateTime &/*time*/) 
00343         { return Duration::zeroDuration; }
00344     // Reimplement this
00345     virtual DateTime summarytaskLatestFinish() 
00346         { return DateTime(); }
00347     // Returns the (previously) calculated duration
00348     const Duration &duration()
00349         { return m_currentSchedule ? m_currentSchedule->duration : Duration::zeroDuration; }
00358     Duration duration(const DateTime &time, int use, bool backward);
00359     // Reimplement this
00360     virtual Duration calcDuration(const DateTime &/*time*/, const Duration &/*effort*/, bool /*backward*/) { return Duration::zeroDuration;}
00361 
00362     Node *siblingBefore();
00363     Node *childBefore(Node *node);
00364     Node *siblingAfter();
00365     Node *childAfter(Node *node);
00366     bool moveChildUp(Node *node);
00367     bool moveChildDown(Node *node);
00368     
00370     bool legalToLink(Node *node);
00372     virtual bool legalToLink(Node *, Node *) { return false; }
00374     virtual bool isEndNode() const;
00376     virtual bool isStartNode() const;
00377     virtual void clearProxyRelations() {}
00378     virtual void addParentProxyRelations(QPtrList<Relation> &) {}
00379     virtual void addChildProxyRelations(QPtrList<Relation> &) {}
00380     virtual void addParentProxyRelation(Node *, const Relation *) {}
00381     virtual void addChildProxyRelation(Node *, const Relation *) {}
00382 
00384     virtual void saveAppointments(QDomElement &element, long id) const;
00386     QPtrList<Appointment> appointments();
00388 //    Appointment *findAppointment(Resource *resource);
00390     virtual bool addAppointment(Appointment *appointment);
00392     virtual bool addAppointment(Appointment *appointment, Schedule &main);
00394     virtual void addAppointment(ResourceSchedule *resource, DateTime &start, DateTime &end, double load=100);
00395     
00397     virtual Node *findNode() const { return findNode(m_id); }
00399     virtual Node *findNode(const QString &id) const
00400         { return (m_parent ? m_parent->findNode(id) : 0); }
00402     virtual bool removeId()  { return removeId(m_id); }
00404     virtual bool removeId(const QString &id)
00405         { return (m_parent ? m_parent->removeId(id) : false); }
00407     virtual void insertId(const QString &id) { insertId(id, this); }
00409     virtual void insertId(const QString &id, const Node *node)
00410         { if (m_parent) m_parent->insertId(id, node); }
00411     
00417     virtual DateTime workStartTime() const
00418         { return m_currentSchedule ? m_currentSchedule->workStartTime : DateTime(); }
00419     void setWorkStartTime(const DateTime &dt) 
00420         { if (m_currentSchedule) m_currentSchedule->workStartTime = dt; }
00421     
00427     virtual DateTime workEndTime() const 
00428         { return m_currentSchedule ? m_currentSchedule->workEndTime : DateTime(); }
00429     void setWorkEndTime(const DateTime &dt) 
00430         { if (m_currentSchedule) m_currentSchedule->workEndTime = dt; }
00431     
00432     virtual bool isCritical() const { return false; }
00433     virtual bool inCriticalPath() const
00434         { return m_currentSchedule ? m_currentSchedule->inCriticalPath : false; }
00435     virtual bool calcCriticalPath(bool fromEnd);
00436     
00438     virtual int level();
00440     virtual void generateWBS(int count, WBSDefinition &def, QString wbs=QString());
00441     QString wbs() const { return m_wbs; }
00442     
00443     double startupCost() const { return m_startupCost; }
00444     void setStartupCost(double cost) { m_startupCost = cost; }
00445     
00446     Account *startupAccount() const { return m_startupAccount; }
00447     void setStartupAccount(Account *acc) { m_startupAccount = acc; }
00448     
00449     double shutdownCost() const { return m_shutdownCost; }
00450     void  setShutdownCost(double cost) { m_shutdownCost = cost; }
00451     
00452     Account *shutdownAccount() const { return m_shutdownAccount; }
00453     void setShutdownAccount(Account *acc) { m_shutdownAccount = acc; }
00454     
00455     Account *runningAccount() const { return m_runningAccount; }
00456     void setRunningAccount(Account *acc) { m_runningAccount = acc; }
00457 
00458     Schedule *currentSchedule() const { return m_currentSchedule; }
00460     virtual void setCurrentSchedule(long id);
00461     // NOTE: Cannot use setCurrentSchedule() due to overload/casting problems
00462     void setCurrentSchedulePtr(Schedule *schedule) { m_currentSchedule = schedule; }
00463     
00464     QIntDict<Schedule> &schedules() { return m_schedules; }
00466     Schedule *findSchedule(const QString name, const Schedule::Type type) const;
00468     Schedule *findSchedule(const Schedule::Type type) const;
00470     Schedule *findSchedule(long id) const { return m_schedules[id]; }
00472     void takeSchedule(const Schedule *schedule);
00474     void addSchedule(Schedule *schedule);
00476     Schedule *createSchedule(QString name, Schedule::Type type, long id);
00478     Schedule *createSchedule(Schedule *parent);
00479     
00481     void setScheduleDeleted(long id, bool onoff);
00483     virtual void setParentSchedule(Schedule *sch);
00484     
00485     DateTime startTime()
00486         { return m_currentSchedule ? m_currentSchedule->startTime : DateTime(); }
00487     DateTime endTime()
00488         { return m_currentSchedule ? m_currentSchedule->endTime : DateTime(); }
00489 
00490 protected:
00491     QPtrList<Node> m_nodes;
00492     QPtrList<Relation> m_dependChildNodes;
00493     QPtrList<Relation> m_dependParentNodes;
00494     Node *m_parent;
00495 
00496     QString m_id; // unique id
00497     QString m_name;        // Name of this node
00498     QString m_leader;      // Person or group responsible for this node
00499     QString m_description; // Description of this node
00500 
00501     Effort* m_effort;
00502     
00503 
00504     ConstraintType m_constraint;
00505 
00510     DateTime m_constraintStartTime;
00515     DateTime m_constraintEndTime;
00516 
00517     bool m_visitedForward;
00518     bool m_visitedBackward;
00519     Duration m_durationForward;
00520     Duration m_durationBackward;
00521     
00522     QDate m_dateOnlyStartDate;
00523     QDate m_dateOnlyEndDate;
00524     Duration m_dateOnlyDuration;
00525  
00526     QIntDict<Schedule> m_schedules;
00527     Schedule *m_currentSchedule;
00528 
00529     QString m_wbs;
00530     
00531     double m_startupCost;
00532     Account *m_startupAccount;
00533     double m_shutdownCost;
00534     Account *m_shutdownAccount;
00535     Account *m_runningAccount;
00536     
00537 private:
00538     void init();
00539         
00540 #ifndef NDEBUG
00541 public:
00542     virtual void printDebug(bool children, QCString indent);
00543 #endif
00544 
00545 };
00546 
00548 
00554 class Effort {
00555 public:
00556     Effort ( Duration e = Duration::zeroDuration, Duration p = Duration::zeroDuration,
00557         Duration o = Duration::zeroDuration );
00558 
00559     Effort ( double e, double p = 0, double o = 0);
00560     
00561     Effort (const Effort &effort);
00562     ~Effort();
00563 
00564     enum Type { Type_Effort = 0,        // Changing amount of resources changes the task duration
00565                           Type_FixedDuration = 1     // Changing amount of resources will not change the tasks duration
00566      };
00567     Type type() const { return m_type; }
00568     void setType(Type type) { m_type = type; }
00569     void setType(QString type);
00570     QString typeToString() const;
00571 
00572     enum Use { Use_Expected=0, Use_Optimistic=1, Use_Pessimistic=2 };
00573     const Duration& effort(int use) {
00574         if (use == Effort::Use_Expected)
00575             return m_expectedEffort;
00576         else if (use == Effort::Use_Optimistic)
00577             return m_optimisticEffort;
00578         else if (use == Effort::Use_Pessimistic)
00579             return m_pessimisticEffort;
00580         
00581         return m_expectedEffort; // default
00582     }
00583     const Duration& optimistic() const {return m_optimisticEffort;}
00584     const Duration& pessimistic() const {return m_pessimisticEffort;}
00585     const Duration& expected() const {return m_expectedEffort;}
00586 
00587     void set( Duration e, Duration p = Duration::zeroDuration, Duration o = Duration::zeroDuration );
00588     void set( int e, int p = -1, int o = -1 );
00589     void set(unsigned days, unsigned hours, unsigned minutes);
00590     void expectedEffort(unsigned *days, unsigned *hours, unsigned *minutes);
00591 
00592     bool load(QDomElement &element);
00593     void save(QDomElement &element) const;
00594 
00599     void setOptimisticRatio(int percent);
00604     int optimisticRatio() const;
00609     void setPessimisticRatio(int percent);
00614     int pessimisticRatio() const;
00615 
00619     static const Effort zeroEffort;
00620 
00621 private:
00622     Duration m_optimisticEffort;
00623     Duration m_pessimisticEffort;
00624     Duration m_expectedEffort;
00625 
00626     Type m_type;
00627     
00628 #ifndef NDEBUG
00629 public:
00630     void printDebug(QCString indent);
00631 #endif
00632 
00633 };
00634 
00635 }  //KPlato namespace
00636 
00637 #endif
KDE Home | KDE Accessibility Home | Description of Access Keys