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 addChildNode_NoId(Node *node, Node *after=0); //HACK
00107     virtual void insertChildNode(unsigned int index, Node *node);
00108     virtual void insertChildNode_NoId(unsigned int index, Node *node); //HACK
00109     void delChildNode(Node *node, bool remove=true);
00110     void delChildNode_NoId(Node *node, bool remove=true); //HACK
00111     void delChildNode(int number, bool remove=true);
00112     void delChildNode_NoId(int number, bool remove=true); //HACK
00113     Node* getChildNode(int number) { return m_nodes.at(number); }
00114     const Node* getChildNode(int number) const;
00115     int findChildNode( Node* node );
00116 
00117     // Time-dependent child-node-management.
00118     // list all nodes that are dependent upon this one.
00119     // Building a house requires the table to be finished, therefore the
00120     // house-building is time dependent on the table-building. So a child
00121     // of the table-building node is the house-building node.
00122 
00123     int numDependChildNodes() const { return m_dependChildNodes.count(); }
00125     virtual void addDependChildNode( Node *node, Relation::Type p=Relation::FinishStart);
00127     virtual void addDependChildNode( Node *node, Relation::Type p, Duration lag);
00129     virtual bool addDependChildNode( Relation *relation);
00131     virtual void insertDependChildNode( unsigned int index, Node *node, Relation::Type p=Relation::FinishStart);
00132     void delDependChildNode( Node *node, bool remove=false);
00133     void delDependChildNode( Relation *rel, bool remove=false);
00134     void delDependChildNode( int number, bool remove=false);
00135     Relation *getDependChildNode( int number) {
00136     return m_dependChildNodes.at(number);
00137     }
00138     QPtrList<Relation> &dependChildNodes() { return m_dependChildNodes; }
00139 
00144     void takeDependChildNode(Relation *rel);
00145     
00146     int numDependParentNodes() const { return m_dependParentNodes.count(); }
00148     virtual void addDependParentNode(Node *node, Relation::Type p=Relation::FinishStart);
00150     virtual void addDependParentNode( Node *node, Relation::Type p, Duration lag);
00152     virtual bool addDependParentNode( Relation *relation);
00154     virtual void insertDependParentNode( unsigned int index, Node *node, Relation::Type p=Relation::FinishStart);
00155     void delDependParentNode( Node *node, bool remove=false);
00156     void delDependParentNode( Relation *rel, bool remove=false);
00157     void delDependParentNode( int number, bool remove=false);
00158     Relation *getDependParentNode( int number) {
00159     return m_dependParentNodes.at(number);
00160     }
00161     QPtrList<Relation> &dependParentNodes() { return m_dependParentNodes; }
00162     
00167     void takeDependParentNode(Relation *rel);
00168 
00169     bool isParentOf(Node *node);
00170     bool isDependChildOf(Node *node);
00171 
00172     Relation *findParentRelation(Node *node);
00173     Relation *findChildRelation(Node *node);
00174     Relation *findRelation(Node *node);
00175 
00176     void setStartTime(DateTime startTime);
00178     virtual DateTime startTime() const
00179         { return m_currentSchedule ? m_currentSchedule->startTime : DateTime(); }
00180     const QDate &startDate() const { return m_dateOnlyStartDate; }
00181     void setEndTime(DateTime endTime);
00183     virtual DateTime endTime() const
00184         { return m_currentSchedule ? m_currentSchedule->endTime : DateTime(); }
00185     const QDate &endDate() const { return m_dateOnlyEndDate; }
00186 
00187     void setEffort(Effort* e) { m_effort = e; }
00188     Effort* effort() const { return m_effort; }
00189 
00193     virtual Duration *getExpectedDuration() = 0;
00194 
00200     virtual Duration *getRandomDuration() = 0;
00201 
00206     Duration *getDelay();
00207 
00213     DateTime getEarliestStart() const
00214         { return m_currentSchedule ? m_currentSchedule->earliestStart : DateTime(); }
00219     void setEarliestStart(const DateTime &dt) 
00220         { if (m_currentSchedule) m_currentSchedule->earliestStart = dt; }
00225     DateTime getLatestFinish() const 
00226         { return m_currentSchedule ? m_currentSchedule->latestFinish : DateTime(); }
00232     void setLatestFinish(const DateTime &dt) 
00233         { if (m_currentSchedule) m_currentSchedule->latestFinish = dt; }
00234 
00235     QString &name() { return m_name; }
00236     QString &leader() { return m_leader; }
00237     QString &description() { return m_description; }
00238     const QString &name() const { return m_name; }
00239     const QString &leader() const { return m_leader; }
00240     const QString &description() const { return m_description; }
00241     void setName(const QString &n) { m_name = n; }
00242     void setLeader(const QString &l) { m_leader = l; }
00243     void setDescription(const QString &d) { m_description = d; }
00244 
00245     virtual void setConstraint(Node::ConstraintType type) { m_constraint = type; }
00246     void setConstraint(QString &type);
00247     int constraint() const { return m_constraint; }
00248     QString constraintToString() const;
00249 
00250     virtual void setConstraintStartTime(QDateTime time) { m_constraintStartTime = time; }
00251     virtual void setConstraintEndTime(QDateTime time) { m_constraintEndTime = time; }
00252 
00253     virtual DateTime constraintStartTime() const { return m_constraintStartTime; }
00254     virtual DateTime constraintEndTime() const { return m_constraintEndTime; }
00255     virtual DateTime startNotEarlier() const { return m_constraintStartTime; }
00256     virtual DateTime finishNotLater() const { return m_constraintEndTime; }
00257     virtual DateTime mustStartOn() const { return m_constraintStartTime; }
00258     virtual DateTime mustFinishOn() const { return m_constraintEndTime; }
00259 
00260     virtual ResourceGroupRequest *resourceRequest(ResourceGroup */*group*/) const { return 0; }
00261     virtual void makeAppointments();
00262 
00264     bool resourceError() const 
00265         { return m_currentSchedule ? m_currentSchedule->resourceError : false; }
00267     virtual bool resourceOverbooked() const
00268         { return m_currentSchedule ? m_currentSchedule->resourceOverbooked : false; }
00271     virtual void calcResourceOverbooked();
00273     bool resourceNotAvailable() const
00274         { return m_currentSchedule ? m_currentSchedule->resourceNotAvailable : false; }
00276     virtual bool schedulingError() const
00277         { return m_currentSchedule ? m_currentSchedule->schedulingError : false; }
00279     bool notScheduled() const
00280         { return m_currentSchedule == 0 || m_currentSchedule->isDeleted() || m_currentSchedule->notScheduled; }
00281     
00282     virtual EffortCostMap plannedEffortCostPrDay(const QDate &start, const QDate &end) const=0;
00283         
00285     virtual Duration plannedEffort() { return Duration::zeroDuration; }
00287     virtual Duration plannedEffort(const QDate &) { return Duration::zeroDuration; }
00289     virtual Duration plannedEffortTo(const QDate &) { return Duration::zeroDuration; }
00290     
00292     virtual Duration actualEffort() { return Duration::zeroDuration; }
00294     virtual Duration actualEffort(const QDate &/*date*/) { return Duration::zeroDuration; }
00296     virtual Duration actualEffortTo(const QDate &/*date*/) { return Duration::zeroDuration; }
00297     
00302     virtual double plannedCost() { return 0; }
00303     
00305     virtual double plannedCost(const QDate &/*date*/) { return 0; }
00310     virtual double plannedCostTo(const QDate &/*date*/) { return 0; }
00315     virtual double actualCost() { return 0; }
00317     virtual double actualCost(const QDate &/*date*/) { return 0; }
00319     virtual double actualCostTo(const QDate &/*date*/) { return 0; }
00320     
00322     double effortPerformanceIndex(const QDate &/*date*/, bool */*error=0*/) { return 0.0; }
00324     double costPerformanceIndex(const QDate &/*date*/, bool */*error=0*/) { return 0.0; }
00325     
00326     virtual void initiateCalculationLists(QPtrList<Node> &startnodes, QPtrList<Node> &endnodes, QPtrList<Node> &summarytasks) = 0;
00327     virtual DateTime calculateForward(int /*use*/) = 0;
00328     virtual DateTime calculateBackward(int /*use*/) = 0;
00329     virtual DateTime scheduleForward(const DateTime &, int /*use*/) = 0;
00330     virtual DateTime scheduleBackward(const DateTime &, int /*use*/) = 0;
00331     virtual void adjustSummarytask() = 0;
00332 
00333     virtual void initiateCalculation(Schedule &sch);
00334     virtual void resetVisited();
00335     void propagateEarliestStart(DateTime &time);
00336     void propagateLatestFinish(DateTime &time);
00337     void moveEarliestStart(DateTime &time);
00338     void moveLatestFinish(DateTime &time);
00339     // Reimplement this
00340     virtual Duration summarytaskDurationForward(const DateTime &/*time*/) 
00341         { return Duration::zeroDuration; }
00342     // Reimplement this
00343     virtual DateTime summarytaskEarliestStart() 
00344         { return DateTime(); }
00345     // Reimplement this
00346     virtual Duration summarytaskDurationBackward(const DateTime &/*time*/) 
00347         { return Duration::zeroDuration; }
00348     // Reimplement this
00349     virtual DateTime summarytaskLatestFinish() 
00350         { return DateTime(); }
00351     // Returns the (previously) calculated duration
00352     const Duration &duration()
00353         { return m_currentSchedule ? m_currentSchedule->duration : Duration::zeroDuration; }
00362     Duration duration(const DateTime &time, int use, bool backward);
00363     // Reimplement this
00364     virtual Duration calcDuration(const DateTime &/*time*/, const Duration &/*effort*/, bool /*backward*/) { return Duration::zeroDuration;}
00365 
00366     Node *siblingBefore();
00367     Node *childBefore(Node *node);
00368     Node *siblingAfter();
00369     Node *childAfter(Node *node);
00370     bool moveChildUp(Node *node);
00371     bool moveChildDown(Node *node);
00372     
00374     bool legalToLink(Node *node);
00376     virtual bool legalToLink(Node *, Node *) { return false; }
00378     virtual bool isEndNode() const;
00380     virtual bool isStartNode() const;
00381     virtual void clearProxyRelations() {}
00382     virtual void addParentProxyRelations(QPtrList<Relation> &) {}
00383     virtual void addChildProxyRelations(QPtrList<Relation> &) {}
00384     virtual void addParentProxyRelation(Node *, const Relation *) {}
00385     virtual void addChildProxyRelation(Node *, const Relation *) {}
00386 
00388     virtual void saveAppointments(QDomElement &element, long id) const;
00390     QPtrList<Appointment> appointments();
00392 //    Appointment *findAppointment(Resource *resource);
00394     virtual bool addAppointment(Appointment *appointment);
00396     virtual bool addAppointment(Appointment *appointment, Schedule &main);
00398     virtual void addAppointment(ResourceSchedule *resource, DateTime &start, DateTime &end, double load=100);
00399     
00401     virtual Node *findNode() const { return findNode(m_id); }
00403     virtual Node *findNode(const QString &id) const
00404         { return (m_parent ? m_parent->findNode(id) : 0); }
00406     virtual bool removeId()  { return removeId(m_id); }
00408     virtual bool removeId(const QString &id)
00409         { return (m_parent ? m_parent->removeId(id) : false); }
00411     virtual void insertId(const QString &id) { insertId(id, this); }
00413     virtual void insertId(const QString &id, const Node *node)
00414         { if (m_parent) m_parent->insertId(id, node); }
00415     
00421     virtual DateTime workStartTime() const
00422         { return m_currentSchedule ? m_currentSchedule->workStartTime : DateTime(); }
00423     void setWorkStartTime(const DateTime &dt) 
00424         { if (m_currentSchedule) m_currentSchedule->workStartTime = dt; }
00425     
00431     virtual DateTime workEndTime() const 
00432         { return m_currentSchedule ? m_currentSchedule->workEndTime : DateTime(); }
00433     void setWorkEndTime(const DateTime &dt) 
00434         { if (m_currentSchedule) m_currentSchedule->workEndTime = dt; }
00435     
00436     virtual bool isCritical() const { return false; }
00437     virtual bool inCriticalPath() const
00438         { return m_currentSchedule ? m_currentSchedule->inCriticalPath : false; }
00439     virtual bool calcCriticalPath(bool fromEnd);
00440     
00442     virtual int level();
00444     virtual void generateWBS(int count, WBSDefinition &def, QString wbs=QString());
00445     QString wbs() const { return m_wbs; }
00446     
00447     double startupCost() const { return m_startupCost; }
00448     void setStartupCost(double cost) { m_startupCost = cost; }
00449     
00450     Account *startupAccount() const { return m_startupAccount; }
00451     void setStartupAccount(Account *acc) { m_startupAccount = acc; }
00452     
00453     double shutdownCost() const { return m_shutdownCost; }
00454     void  setShutdownCost(double cost) { m_shutdownCost = cost; }
00455     
00456     Account *shutdownAccount() const { return m_shutdownAccount; }
00457     void setShutdownAccount(Account *acc) { m_shutdownAccount = acc; }
00458     
00459     Account *runningAccount() const { return m_runningAccount; }
00460     void setRunningAccount(Account *acc) { m_runningAccount = acc; }
00461 
00462     Schedule *currentSchedule() const { return m_currentSchedule; }
00464     virtual void setCurrentSchedule(long id);
00465     // NOTE: Cannot use setCurrentSchedule() due to overload/casting problems
00466     void setCurrentSchedulePtr(Schedule *schedule) { m_currentSchedule = schedule; }
00467     
00468     QIntDict<Schedule> &schedules() { return m_schedules; }
00470     Schedule *findSchedule(const QString name, const Schedule::Type type) const;
00472     Schedule *findSchedule(const Schedule::Type type) const;
00474     Schedule *findSchedule(long id) const { return m_schedules[id]; }
00476     void takeSchedule(const Schedule *schedule);
00478     void addSchedule(Schedule *schedule);
00480     Schedule *createSchedule(QString name, Schedule::Type type, long id);
00482     Schedule *createSchedule(Schedule *parent);
00483     
00485     void setScheduleDeleted(long id, bool onoff);
00487     virtual void setParentSchedule(Schedule *sch);
00488     
00489     DateTime startTime()
00490         { return m_currentSchedule ? m_currentSchedule->startTime : DateTime(); }
00491     DateTime endTime()
00492         { return m_currentSchedule ? m_currentSchedule->endTime : DateTime(); }
00493 
00494 protected:
00495     QPtrList<Node> m_nodes;
00496     QPtrList<Relation> m_dependChildNodes;
00497     QPtrList<Relation> m_dependParentNodes;
00498     Node *m_parent;
00499 
00500     QString m_id; // unique id
00501     QString m_name;        // Name of this node
00502     QString m_leader;      // Person or group responsible for this node
00503     QString m_description; // Description of this node
00504 
00505     Effort* m_effort;
00506     
00507 
00508     ConstraintType m_constraint;
00509 
00514     DateTime m_constraintStartTime;
00519     DateTime m_constraintEndTime;
00520 
00521     bool m_visitedForward;
00522     bool m_visitedBackward;
00523     Duration m_durationForward;
00524     Duration m_durationBackward;
00525     
00526     QDate m_dateOnlyStartDate;
00527     QDate m_dateOnlyEndDate;
00528     Duration m_dateOnlyDuration;
00529  
00530     QIntDict<Schedule> m_schedules;
00531     Schedule *m_currentSchedule;
00532 
00533     QString m_wbs;
00534     
00535     double m_startupCost;
00536     Account *m_startupAccount;
00537     double m_shutdownCost;
00538     Account *m_shutdownAccount;
00539     Account *m_runningAccount;
00540     
00541 private:
00542     void init();
00543         
00544 #ifndef NDEBUG
00545 public:
00546     virtual void printDebug(bool children, QCString indent);
00547 #endif
00548 
00549 };
00550 
00552 
00558 class Effort {
00559 public:
00560     Effort ( Duration e = Duration::zeroDuration, Duration p = Duration::zeroDuration,
00561         Duration o = Duration::zeroDuration );
00562 
00563     Effort ( double e, double p = 0, double o = 0);
00564     
00565     Effort (const Effort &effort);
00566     ~Effort();
00567 
00568     enum Type { Type_Effort = 0,        // Changing amount of resources changes the task duration
00569                           Type_FixedDuration = 1     // Changing amount of resources will not change the tasks duration
00570      };
00571     Type type() const { return m_type; }
00572     void setType(Type type) { m_type = type; }
00573     void setType(QString type);
00574     QString typeToString() const;
00575 
00576     enum Use { Use_Expected=0, Use_Optimistic=1, Use_Pessimistic=2 };
00577     const Duration& effort(int use) {
00578         if (use == Effort::Use_Expected)
00579             return m_expectedEffort;
00580         else if (use == Effort::Use_Optimistic)
00581             return m_optimisticEffort;
00582         else if (use == Effort::Use_Pessimistic)
00583             return m_pessimisticEffort;
00584         
00585         return m_expectedEffort; // default
00586     }
00587     const Duration& optimistic() const {return m_optimisticEffort;}
00588     const Duration& pessimistic() const {return m_pessimisticEffort;}
00589     const Duration& expected() const {return m_expectedEffort;}
00590 
00591     void set( Duration e, Duration p = Duration::zeroDuration, Duration o = Duration::zeroDuration );
00592     void set( int e, int p = -1, int o = -1 );
00593     void set(unsigned days, unsigned hours, unsigned minutes);
00594     void expectedEffort(unsigned *days, unsigned *hours, unsigned *minutes);
00595 
00596     bool load(QDomElement &element);
00597     void save(QDomElement &element) const;
00598 
00603     void setOptimisticRatio(int percent);
00608     int optimisticRatio() const;
00613     void setPessimisticRatio(int percent);
00618     int pessimisticRatio() const;
00619 
00623     static const Effort zeroEffort;
00624 
00625 private:
00626     Duration m_optimisticEffort;
00627     Duration m_pessimisticEffort;
00628     Duration m_expectedEffort;
00629 
00630     Type m_type;
00631     
00632 #ifndef NDEBUG
00633 public:
00634     void printDebug(QCString indent);
00635 #endif
00636 
00637 };
00638 
00639 }  //KPlato namespace
00640 
00641 #endif
KDE Home | KDE Accessibility Home | Description of Access Keys