|
|
|
/* This file is part of the KDE project
|
|
|
|
Copyright (C) 2001 Thomas Zander zander@kde.org
|
|
|
|
Copyright (C) 2004, 2005 Dag Andersen <danders@get2net.dk>
|
|
|
|
|
|
|
|
This library is free software; you can redistribute it and/or
|
|
|
|
modify it under the terms of the GNU Library General Public
|
|
|
|
License as published by the Free Software Foundation; either
|
|
|
|
version 2 of the License, or (at your option) any later version.
|
|
|
|
|
|
|
|
This library is distributed in the hope that it will be useful,
|
|
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
Library General Public License for more details.
|
|
|
|
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
|
|
along with this library; see the file COPYING.LIB. If not, write to
|
|
|
|
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
|
|
* Boston, MA 02110-1301, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#ifndef KPTNODE_H
|
|
|
|
#define KPTNODE_H
|
|
|
|
|
|
|
|
#include "kptrelation.h"
|
|
|
|
#include "kptduration.h"
|
|
|
|
#include "kptdatetime.h"
|
|
|
|
#include "kptschedule.h"
|
|
|
|
|
|
|
|
#include <tqintdict.h>
|
|
|
|
#include <tqrect.h>
|
|
|
|
#include <tqptrlist.h>
|
|
|
|
#include <tqstring.h>
|
|
|
|
#include <tqcanvas.h>
|
|
|
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
class TQDomElement;
|
|
|
|
|
|
|
|
namespace KPlato
|
|
|
|
{
|
|
|
|
|
|
|
|
class Account;
|
|
|
|
class Project;
|
|
|
|
class Appointment;
|
|
|
|
class ResourceGroup;
|
|
|
|
class Resource;
|
|
|
|
class ResourceGroupRequest;
|
|
|
|
class Effort;
|
|
|
|
class WBSDefinition;
|
|
|
|
class EffortCostMap;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This class represents any node in the project, a node can be a project or
|
|
|
|
* a subproject or any task.
|
|
|
|
* This class is basically an abstract interface to make the design more OO.
|
|
|
|
*/
|
|
|
|
class Node {
|
|
|
|
|
|
|
|
public:
|
|
|
|
enum ConstraintType { ASAP, ALAP, MustStartOn, MustFinishOn, StartNotEarlier, FinishNotLater, FixedInterval };
|
|
|
|
|
|
|
|
Node(Node *tqparent = 0);
|
|
|
|
Node(Node &node, Node *tqparent = 0);
|
|
|
|
|
|
|
|
|
|
|
|
// Declare the class abstract
|
|
|
|
virtual ~Node() = 0;
|
|
|
|
|
|
|
|
bool setId(TQString id);
|
|
|
|
TQString id() const { return m_id; } // unique identity
|
|
|
|
|
|
|
|
enum NodeTypes {
|
|
|
|
Type_Node = 0,
|
|
|
|
Type_Project = 1,
|
|
|
|
Type_Subproject = 2,
|
|
|
|
Type_Task = 3,
|
|
|
|
Type_Milestone = 4,
|
|
|
|
Type_Periodic = 5,
|
|
|
|
Type_Summarytask = 6
|
|
|
|
};
|
|
|
|
|
|
|
|
virtual int type() const = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns a pointer to the project node (main- or sub-project)
|
|
|
|
* Returns 0 if no project exists.
|
|
|
|
*/
|
|
|
|
virtual Node *projectNode();
|
|
|
|
|
|
|
|
// The load and save methods
|
|
|
|
virtual bool load(TQDomElement &) { return true; }
|
|
|
|
virtual bool load(TQDomElement &, Project &) { return true; }
|
|
|
|
virtual void save(TQDomElement &element) const = 0;
|
|
|
|
/// Save my and my tqchildrens relations.
|
|
|
|
virtual void saveRelations(TQDomElement &element) const;
|
|
|
|
|
|
|
|
// simple child node management
|
|
|
|
// Child nodes are things like subtasks, basically a task can exists of
|
|
|
|
// several sub-tasks. Creating a table has 4 subtasks, 1) measuring
|
|
|
|
// 2) cutting 3) building 4) painting.
|
|
|
|
Node *getParent() const { return m_parent; }
|
|
|
|
void setParent( Node* newParent ) { m_parent = newParent;}
|
|
|
|
const TQPtrList<Node> &childNodeIterator() const { return m_nodes; }
|
|
|
|
int numChildren() const { return m_nodes.count(); }
|
|
|
|
virtual void addChildNode(Node *node, Node *after=0);
|
|
|
|
virtual void insertChildNode(unsigned int index, Node *node);
|
|
|
|
void delChildNode(Node *node, bool remove=true);
|
|
|
|
void delChildNode(int number, bool remove=true);
|
|
|
|
Node* getChildNode(int number) { return m_nodes.at(number); }
|
|
|
|
const Node* getChildNode(int number) const;
|
|
|
|
int findChildNode( Node* node );
|
|
|
|
|
|
|
|
// Time-dependent child-node-management.
|
|
|
|
// list all nodes that are dependent upon this one.
|
|
|
|
// Building a house requires the table to be finished, therefore the
|
|
|
|
// house-building is time dependent on the table-building. So a child
|
|
|
|
// of the table-building node is the house-building node.
|
|
|
|
|
|
|
|
int numDependChildNodes() const { return m_dependChildNodes.count(); }
|
|
|
|
/// Adds relation to both this node and address node
|
|
|
|
virtual void addDependChildNode( Node *node, Relation::Type p=Relation::FinishStart);
|
|
|
|
/// Adds relation to both this node and address node
|
|
|
|
virtual void addDependChildNode( Node *node, Relation::Type p, Duration lag);
|
|
|
|
/// Adds relation only to this node
|
|
|
|
virtual bool addDependChildNode( Relation *relation);
|
|
|
|
/// Inserts relation to this node at index address index and appends relation to address node
|
|
|
|
virtual void insertDependChildNode( unsigned int index, Node *node, Relation::Type p=Relation::FinishStart);
|
|
|
|
void delDependChildNode( Node *node, bool remove=false);
|
|
|
|
void delDependChildNode( Relation *rel, bool remove=false);
|
|
|
|
void delDependChildNode( int number, bool remove=false);
|
|
|
|
Relation *getDependChildNode( int number) {
|
|
|
|
return m_dependChildNodes.at(number);
|
|
|
|
}
|
|
|
|
TQPtrList<Relation> &dependChildNodes() { return m_dependChildNodes; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Takes the relation rel from this node only.
|
|
|
|
* Never deletes even when autoDelete = true.
|
|
|
|
*/
|
|
|
|
void takeDependChildNode(Relation *rel);
|
|
|
|
|
|
|
|
int numDependParentNodes() const { return m_dependParentNodes.count(); }
|
|
|
|
/// Adds relation to both this node and node
|
|
|
|
virtual void addDependParentNode(Node *node, Relation::Type p=Relation::FinishStart);
|
|
|
|
/// Adds relation to both this node and node
|
|
|
|
virtual void addDependParentNode( Node *node, Relation::Type p, Duration lag);
|
|
|
|
/// Adds relation only to this node
|
|
|
|
virtual bool addDependParentNode( Relation *relation);
|
|
|
|
/// Inserts relation to this node at index and appends relation to node
|
|
|
|
virtual void insertDependParentNode( unsigned int index, Node *node, Relation::Type p=Relation::FinishStart);
|
|
|
|
void delDependParentNode( Node *node, bool remove=false);
|
|
|
|
void delDependParentNode( Relation *rel, bool remove=false);
|
|
|
|
void delDependParentNode( int number, bool remove=false);
|
|
|
|
Relation *getDependParentNode( int number) {
|
|
|
|
return m_dependParentNodes.at(number);
|
|
|
|
}
|
|
|
|
TQPtrList<Relation> &dependParentNodes() { return m_dependParentNodes; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Takes the relation rel from this node only.
|
|
|
|
* Never deletes even when autoDelete = true.
|
|
|
|
*/
|
|
|
|
void takeDependParentNode(Relation *rel);
|
|
|
|
|
|
|
|
bool isParentOf(Node *node);
|
|
|
|
bool isDependChildOf(Node *node);
|
|
|
|
|
|
|
|
Relation *findParentRelation(Node *node);
|
|
|
|
Relation *findChildRelation(Node *node);
|
|
|
|
Relation *findRelation(Node *node);
|
|
|
|
|
|
|
|
void setStartTime(DateTime startTime);
|
|
|
|
/// Return the scheduled start time
|
|
|
|
virtual DateTime startTime() const
|
|
|
|
{ return m_currentSchedule ? m_currentSchedule->startTime : DateTime(); }
|
|
|
|
const TQDate &startDate() const { return m_dateOnlyStartDate; }
|
|
|
|
void setEndTime(DateTime endTime);
|
|
|
|
/// Return the scheduled end time
|
|
|
|
virtual DateTime endTime() const
|
|
|
|
{ return m_currentSchedule ? m_currentSchedule->endTime : DateTime(); }
|
|
|
|
const TQDate &endDate() const { return m_dateOnlyEndDate; }
|
|
|
|
|
|
|
|
void setEffort(Effort* e) { m_effort = e; }
|
|
|
|
Effort* effort() const { return m_effort; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns the (previously) calculated duration.
|
|
|
|
*/
|
|
|
|
virtual Duration *getExpectedDuration() = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Instead of using the expected duration, generate a random value using
|
|
|
|
* the Distribution of each Task. This can be used for Monte-Carlo
|
|
|
|
* estimation of Project duration.
|
|
|
|
*/
|
|
|
|
virtual Duration *getRandomDuration() = 0;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Calculate the delay of this node.
|
|
|
|
* It is the difference between the actual startTime and scheduled startTime.
|
|
|
|
*/
|
|
|
|
Duration *getDelay();
|
|
|
|
|
|
|
|
/**
|
|
|
|
* getEarliestStart() returns earliest time this node can start
|
|
|
|
* given the constraints of the network.
|
|
|
|
* @see earliestStart
|
|
|
|
*/
|
|
|
|
DateTime getEarliestStart() const
|
|
|
|
{ return m_currentSchedule ? m_currentSchedule->earliestStart : DateTime(); }
|
|
|
|
/**
|
|
|
|
* setEarliestStart() sets earliest time this node can start
|
|
|
|
* @see earliestStart
|
|
|
|
*/
|
|
|
|
void setEarliestStart(const DateTime &dt)
|
|
|
|
{ if (m_currentSchedule) m_currentSchedule->earliestStart = dt; }
|
|
|
|
/**
|
|
|
|
* getLatestFinish() returns latest time this node can finish
|
|
|
|
* @see latestFinish
|
|
|
|
*/
|
|
|
|
DateTime getLatestFinish() const
|
|
|
|
{ return m_currentSchedule ? m_currentSchedule->latestFinish : DateTime(); }
|
|
|
|
/**
|
|
|
|
* setLatestFinish() sets latest time this node can finish
|
|
|
|
* given the constraints of the network.
|
|
|
|
* @see latestFinish
|
|
|
|
*/
|
|
|
|
void setLatestFinish(const DateTime &dt)
|
|
|
|
{ if (m_currentSchedule) m_currentSchedule->latestFinish = dt; }
|
|
|
|
|
|
|
|
TQString &name() { return m_name; }
|
|
|
|
TQString &leader() { return m_leader; }
|
|
|
|
TQString &description() { return m_description; }
|
|
|
|
const TQString &name() const { return m_name; }
|
|
|
|
const TQString &leader() const { return m_leader; }
|
|
|
|
const TQString &description() const { return m_description; }
|
|
|
|
void setName(const TQString &n) { m_name = n; }
|
|
|
|
void setLeader(const TQString &l) { m_leader = l; }
|
|
|
|
void setDescription(const TQString &d) { m_description = d; }
|
|
|
|
|
|
|
|
virtual void setConstraint(Node::ConstraintType type) { m_constraint = type; }
|
|
|
|
void setConstraint(TQString &type);
|
|
|
|
int constraint() const { return m_constraint; }
|
|
|
|
TQString constraintToString() const;
|
|
|
|
|
|
|
|
virtual void setConstraintStartTime(TQDateTime time) { m_constraintStartTime = time; }
|
|
|
|
virtual void setConstraintEndTime(TQDateTime time) { m_constraintEndTime = time; }
|
|
|
|
|
|
|
|
virtual DateTime constraintStartTime() const { return m_constraintStartTime; }
|
|
|
|
virtual DateTime constraintEndTime() const { return m_constraintEndTime; }
|
|
|
|
virtual DateTime startNotEarlier() const { return m_constraintStartTime; }
|
|
|
|
virtual DateTime finishNotLater() const { return m_constraintEndTime; }
|
|
|
|
virtual DateTime mustStartOn() const { return m_constraintStartTime; }
|
|
|
|
virtual DateTime mustFinishOn() const { return m_constraintEndTime; }
|
|
|
|
|
|
|
|
virtual ResourceGroupRequest *resourceRequest(ResourceGroup */*group*/) const { return 0; }
|
|
|
|
virtual void makeAppointments();
|
|
|
|
|
|
|
|
/// EffortType == Effort, but no resource is requested
|
|
|
|
bool resourceError() const
|
|
|
|
{ return m_currentSchedule ? m_currentSchedule->resourceError : false; }
|
|
|
|
/// The assigned resource is overbooked
|
|
|
|
virtual bool resourceOverbooked() const
|
|
|
|
{ return m_currentSchedule ? m_currentSchedule->resourceOverbooked : false; }
|
|
|
|
/// Return a list of overbooked resources
|
|
|
|
virtual TQStringList overbookedResources() const;
|
|
|
|
/// Calculates if the assigned resource is overbooked
|
|
|
|
/// within the duration of this node
|
|
|
|
virtual void calcResourceOverbooked();
|
|
|
|
/// The requested resource is not available
|
|
|
|
bool resourceNotAvailable() const
|
|
|
|
{ return m_currentSchedule ? m_currentSchedule->resourceNotAvailable : false; }
|
|
|
|
/// The task cannot be scheduled to fullfill all the constraints
|
|
|
|
virtual bool schedulingError() const
|
|
|
|
{ return m_currentSchedule ? m_currentSchedule->schedulingError : false; }
|
|
|
|
/// The node has not been scheduled
|
|
|
|
bool notScheduled() const
|
|
|
|
{ return m_currentSchedule == 0 || m_currentSchedule->isDeleted() || m_currentSchedule->notScheduled; }
|
|
|
|
|
|
|
|
virtual EffortCostMap plannedEffortCostPrDay(const TQDate &start, const TQDate &end) const=0;
|
|
|
|
|
|
|
|
/// Returns the total planned effort for this task (or subtasks)
|
|
|
|
virtual Duration plannedEffort() { return Duration::zeroDuration; }
|
|
|
|
/// Returns the total planned effort for this task (or subtasks) on date
|
|
|
|
virtual Duration plannedEffort(const TQDate &) { return Duration::zeroDuration; }
|
|
|
|
/// Returns the planned effort up to and including date
|
|
|
|
virtual Duration plannedEffortTo(const TQDate &) { return Duration::zeroDuration; }
|
|
|
|
|
|
|
|
/// Returns the total actual effort for this task (or subtasks)
|
|
|
|
virtual Duration actualEffort() { return Duration::zeroDuration; }
|
|
|
|
/// Returns the total actual effort for this task (or subtasks) on date
|
|
|
|
virtual Duration actualEffort(const TQDate &/*date*/) { return Duration::zeroDuration; }
|
|
|
|
/// Returns the total actual effort for this task (or subtasks) up to and including date
|
|
|
|
virtual Duration actualEffortTo(const TQDate &/*date*/) { return Duration::zeroDuration; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Planned cost is the sum total of all resources and other costs
|
|
|
|
* planned for this node.
|
|
|
|
*/
|
|
|
|
virtual double plannedCost() { return 0; }
|
|
|
|
|
|
|
|
/// Planned cost on date
|
|
|
|
virtual double plannedCost(const TQDate &/*date*/) { return 0; }
|
|
|
|
/**
|
|
|
|
* Planned cost from start of activity up to and including date
|
|
|
|
* is the sum of all resource costs and other costs planned for this node.
|
|
|
|
*/
|
|
|
|
virtual double plannedCostTo(const TQDate &/*date*/) { return 0; }
|
|
|
|
/**
|
|
|
|
* Actual cost is the sum total of the reported costs actually used
|
|
|
|
* for this node.
|
|
|
|
*/
|
|
|
|
virtual double actualCost() { return 0; }
|
|
|
|
/// Actual cost on date
|
|
|
|
virtual double actualCost(const TQDate &/*date*/) { return 0; }
|
|
|
|
/// Actual cost up to and including date
|
|
|
|
virtual double actualCostTo(const TQDate &/*date*/) { return 0; }
|
|
|
|
|
|
|
|
/// Effort based performance index
|
|
|
|
double effortPerformanceIndex(const TQDate &/*date*/, bool */*error=0*/) { return 0.0; }
|
|
|
|
/// Cost performance index
|
|
|
|
double costPerformanceIndex(const TQDate &/*date*/, bool */*error=0*/) { return 0.0; }
|
|
|
|
|
|
|
|
virtual void initiateCalculationLists(TQPtrList<Node> &startnodes, TQPtrList<Node> &endnodes, TQPtrList<Node> &summarytasks) = 0;
|
|
|
|
virtual DateTime calculateForward(int /*use*/) = 0;
|
|
|
|
virtual DateTime calculateBackward(int /*use*/) = 0;
|
|
|
|
virtual DateTime scheduleForward(const DateTime &, int /*use*/) = 0;
|
|
|
|
virtual DateTime scheduleBackward(const DateTime &, int /*use*/) = 0;
|
|
|
|
virtual void adjustSummarytask() = 0;
|
|
|
|
|
|
|
|
virtual void initiateCalculation(Schedule &sch);
|
|
|
|
virtual void resetVisited();
|
|
|
|
void propagateEarliestStart(DateTime &time);
|
|
|
|
void propagateLatestFinish(DateTime &time);
|
|
|
|
void moveEarliestStart(DateTime &time);
|
|
|
|
void moveLatestFinish(DateTime &time);
|
|
|
|
// Reimplement this
|
|
|
|
virtual Duration summarytaskDurationForward(const DateTime &/*time*/)
|
|
|
|
{ return Duration::zeroDuration; }
|
|
|
|
// Reimplement this
|
|
|
|
virtual DateTime summarytaskEarliestStart()
|
|
|
|
{ return DateTime(); }
|
|
|
|
// Reimplement this
|
|
|
|
virtual Duration summarytaskDurationBackward(const DateTime &/*time*/)
|
|
|
|
{ return Duration::zeroDuration; }
|
|
|
|
// Reimplement this
|
|
|
|
virtual DateTime summarytaskLatestFinish()
|
|
|
|
{ return DateTime(); }
|
|
|
|
// Returns the (previously) calculated duration
|
|
|
|
const Duration &duration()
|
|
|
|
{ return m_currentSchedule ? m_currentSchedule->duration : Duration::zeroDuration; }
|
|
|
|
/**
|
|
|
|
* Calculates and returns the duration of the node.
|
|
|
|
* Uses the correct expected-, optimistic- or pessimistic effort
|
|
|
|
* dependent on use.
|
|
|
|
* @param time Where to start calculation.
|
|
|
|
* @param use Calculate using expected-, optimistic- or pessimistic estimate.
|
|
|
|
* @param backward If true, time specifies when the task should end.
|
|
|
|
*/
|
|
|
|
Duration duration(const DateTime &time, int use, bool backward);
|
|
|
|
// Reimplement this
|
|
|
|
virtual Duration calcDuration(const DateTime &/*time*/, const Duration &/*effort*/, bool /*backward*/) { return Duration::zeroDuration;}
|
|
|
|
|
|
|
|
Node *siblingBefore();
|
|
|
|
Node *childBefore(Node *node);
|
|
|
|
Node *siblingAfter();
|
|
|
|
Node *childAfter(Node *node);
|
|
|
|
bool moveChildUp(Node *node);
|
|
|
|
bool moveChildDown(Node *node);
|
|
|
|
|
|
|
|
/// Check if this node can be linked to node
|
|
|
|
bool legalToLink(Node *node);
|
|
|
|
/// Check if node par can be linked to node child. (Reimplement)
|
|
|
|
virtual bool legalToLink(Node *, Node *) { return false; }
|
|
|
|
/// Check if this node has any dependent child nodes
|
|
|
|
virtual bool isEndNode() const;
|
|
|
|
/// Check if this node has any dependent tqparent nodes
|
|
|
|
virtual bool isStartNode() const;
|
|
|
|
virtual void clearProxyRelations() {}
|
|
|
|
virtual void addParentProxyRelations(TQPtrList<Relation> &) {}
|
|
|
|
virtual void addChildProxyRelations(TQPtrList<Relation> &) {}
|
|
|
|
virtual void addParentProxyRelation(Node *, const Relation *) {}
|
|
|
|
virtual void addChildProxyRelation(Node *, const Relation *) {}
|
|
|
|
|
|
|
|
/// Save appointments for schedule with id
|
|
|
|
virtual void saveAppointments(TQDomElement &element, long id) const;
|
|
|
|
///Return the list of appointments for current schedule.
|
|
|
|
TQPtrList<Appointment> appointments();
|
|
|
|
/// Return appointment this node have with resource
|
|
|
|
// Appointment *findAppointment(Resource *resource);
|
|
|
|
/// Adds appointment to this node only (not to resource)
|
|
|
|
virtual bool addAppointment(Appointment *appointment);
|
|
|
|
/// Adds appointment to this node only (not to resource)
|
|
|
|
virtual bool addAppointment(Appointment *appointment, Schedule &main);
|
|
|
|
/// Adds appointment to both this node and resource
|
|
|
|
virtual void addAppointment(ResourceSchedule *resource, DateTime &start, DateTime &end, double load=100);
|
|
|
|
|
|
|
|
/// Find the node with my id
|
|
|
|
virtual Node *findNode() const { return findNode(m_id); }
|
|
|
|
/// Find the node with identity id
|
|
|
|
virtual Node *findNode(const TQString &id) const
|
|
|
|
{ return (m_parent ? m_parent->findNode(id) : 0); }
|
|
|
|
/// Remove myself from the id register
|
|
|
|
virtual bool removeId() { return removeId(m_id); }
|
|
|
|
/// Remove the registered identity id
|
|
|
|
virtual bool removeId(const TQString &id)
|
|
|
|
{ return (m_parent ? m_parent->removeId(id) : false); }
|
|
|
|
/// Insert myself into the id register
|
|
|
|
virtual void insertId(const TQString &id) { insertId(id, this); }
|
|
|
|
/// Insert node with identity id into the register
|
|
|
|
virtual void insertId(const TQString &id, const Node *node)
|
|
|
|
{ if (m_parent) m_parent->insertId(id, node); }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This is when work can start on this node in accordance with
|
|
|
|
* the calendar of allocated resources. Normally this is the same
|
|
|
|
* as @ref startTime(), but may differ if timing constraints are set.
|
|
|
|
*/
|
|
|
|
virtual DateTime workStartTime() const
|
|
|
|
{ return m_currentSchedule ? m_currentSchedule->workStartTime : DateTime(); }
|
|
|
|
void setWorkStartTime(const DateTime &dt)
|
|
|
|
{ if (m_currentSchedule) m_currentSchedule->workStartTime = dt; }
|
|
|
|
|
|
|
|
/**
|
|
|
|
* This is when work can finish on this node in accordance with
|
|
|
|
* the calendar of allocated resources. Normally this is the same
|
|
|
|
* as @ref endTime(), but may differ if timing constraints are set.
|
|
|
|
*/
|
|
|
|
virtual DateTime workEndTime() const
|
|
|
|
{ return m_currentSchedule ? m_currentSchedule->workEndTime : DateTime(); }
|
|
|
|
void setWorkEndTime(const DateTime &dt)
|
|
|
|
{ if (m_currentSchedule) m_currentSchedule->workEndTime = dt; }
|
|
|
|
|
|
|
|
virtual bool isCritical() const { return false; }
|
|
|
|
virtual bool inCriticalPath() const
|
|
|
|
{ return m_currentSchedule ? m_currentSchedule->inCriticalPath : false; }
|
|
|
|
virtual bool calcCriticalPath(bool fromEnd);
|
|
|
|
|
|
|
|
/// Returns the level this node is in the hierarchy. Top node is level 0.
|
|
|
|
virtual int level();
|
|
|
|
/// Generate WBS
|
|
|
|
virtual void generateWBS(int count, WBSDefinition &def, TQString wbs=TQString());
|
|
|
|
TQString wbs() const { return m_wbs; }
|
|
|
|
|
|
|
|
double startupCost() const { return m_startupCost; }
|
|
|
|
void setStartupCost(double cost) { m_startupCost = cost; }
|
|
|
|
|
|
|
|
Account *startupAccount() const { return m_startupAccount; }
|
|
|
|
void setStartupAccount(Account *acc) { m_startupAccount = acc; }
|
|
|
|
|
|
|
|
double shutdownCost() const { return m_shutdownCost; }
|
|
|
|
void setShutdownCost(double cost) { m_shutdownCost = cost; }
|
|
|
|
|
|
|
|
Account *shutdownAccount() const { return m_shutdownAccount; }
|
|
|
|
void setShutdownAccount(Account *acc) { m_shutdownAccount = acc; }
|
|
|
|
|
|
|
|
Account *runningAccount() const { return m_runningAccount; }
|
|
|
|
void setRunningAccount(Account *acc) { m_runningAccount = acc; }
|
|
|
|
|
|
|
|
Schedule *currentSchedule() const { return m_currentSchedule; }
|
|
|
|
/// Set current schedule to schedule with identity id, for me and my tqchildren
|
|
|
|
virtual void setCurrentSchedule(long id);
|
|
|
|
// NOTE: Cannot use setCurrentSchedule() due to overload/casting problems
|
|
|
|
void setCurrentSchedulePtr(Schedule *schedule) { m_currentSchedule = schedule; }
|
|
|
|
|
|
|
|
TQIntDict<Schedule> &schedules() { return m_schedules; }
|
|
|
|
/// Find schedule matching name and type. Does not return deleted schedule.
|
|
|
|
Schedule *findSchedule(const TQString name, const Schedule::Type type) const;
|
|
|
|
/// Find schedule matching type. Does not return deleted schedule.
|
|
|
|
Schedule *findSchedule(const Schedule::Type type) const;
|
|
|
|
/// Find schedule matching id. Also returns deleted schedule.
|
|
|
|
Schedule *findSchedule(long id) const { return m_schedules[id]; }
|
|
|
|
/// Take, don't delete (as in destruct).
|
|
|
|
void takeSchedule(const Schedule *schedule);
|
|
|
|
/// Add schedule to list, replace if schedule with same id allready exists.
|
|
|
|
void addSchedule(Schedule *schedule);
|
|
|
|
/// Create a new schedule.
|
|
|
|
Schedule *createSchedule(TQString name, Schedule::Type type, long id);
|
|
|
|
/// Create a new schedule.
|
|
|
|
Schedule *createSchedule(Schedule *tqparent);
|
|
|
|
|
|
|
|
/// Set deleted = onoff for schedule with id
|
|
|
|
void setScheduleDeleted(long id, bool onoff);
|
|
|
|
/// Set tqparent schedule recursivly
|
|
|
|
virtual void setParentSchedule(Schedule *sch);
|
|
|
|
|
|
|
|
DateTime startTime()
|
|
|
|
{ return m_currentSchedule ? m_currentSchedule->startTime : DateTime(); }
|
|
|
|
DateTime endTime()
|
|
|
|
{ return m_currentSchedule ? m_currentSchedule->endTime : DateTime(); }
|
|
|
|
|
|
|
|
protected:
|
|
|
|
TQPtrList<Node> m_nodes;
|
|
|
|
TQPtrList<Relation> m_dependChildNodes;
|
|
|
|
TQPtrList<Relation> m_dependParentNodes;
|
|
|
|
Node *m_parent;
|
|
|
|
|
|
|
|
TQString m_id; // unique id
|
|
|
|
TQString m_name; // Name of this node
|
|
|
|
TQString m_leader; // Person or group responsible for this node
|
|
|
|
TQString m_description; // Description of this node
|
|
|
|
|
|
|
|
Effort* m_effort;
|
|
|
|
|
|
|
|
|
|
|
|
ConstraintType m_constraint;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* m_constraintTime is used if any of the constraints
|
|
|
|
* FixedInterval, StartNotEarlier, MustStartOn or FixedInterval is selected
|
|
|
|
*/
|
|
|
|
DateTime m_constraintStartTime;
|
|
|
|
/**
|
|
|
|
* m_constraintEndTime is used if any of the constraints
|
|
|
|
* FixedInterval, FinishNotLater, MustFinishOn or FixedInterval is selected
|
|
|
|
*/
|
|
|
|
DateTime m_constraintEndTime;
|
|
|
|
|
|
|
|
bool m_visitedForward;
|
|
|
|
bool m_visitedBackward;
|
|
|
|
Duration m_durationForward;
|
|
|
|
Duration m_durationBackward;
|
|
|
|
|
|
|
|
TQDate m_dateOnlyStartDate;
|
|
|
|
TQDate m_dateOnlyEndDate;
|
|
|
|
Duration m_dateOnlyDuration;
|
|
|
|
|
|
|
|
TQIntDict<Schedule> m_schedules;
|
|
|
|
Schedule *m_currentSchedule;
|
|
|
|
|
|
|
|
TQString m_wbs;
|
|
|
|
|
|
|
|
double m_startupCost;
|
|
|
|
Account *m_startupAccount;
|
|
|
|
double m_shutdownCost;
|
|
|
|
Account *m_shutdownAccount;
|
|
|
|
Account *m_runningAccount;
|
|
|
|
|
|
|
|
private:
|
|
|
|
void init();
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
public:
|
|
|
|
virtual void printDebug(bool tqchildren, TQCString indent);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
//////////////////////////////// Effort ////////////////////////////////
|
|
|
|
/**
|
|
|
|
* Any @ref Node will store how much time it takes to complete the node
|
|
|
|
* (typically a @ref Task) in the traditional scheduling software the
|
|
|
|
* effort which is needed to complete the node is not simply a timespan but
|
|
|
|
* is stored as an optimistic, a pessimistic and an expected timespan.
|
|
|
|
*/
|
|
|
|
class Effort {
|
|
|
|
public:
|
|
|
|
Effort ( Duration e = Duration::zeroDuration, Duration p = Duration::zeroDuration,
|
|
|
|
Duration o = Duration::zeroDuration );
|
|
|
|
|
|
|
|
Effort ( double e, double p = 0, double o = 0);
|
|
|
|
|
|
|
|
Effort (const Effort &effort);
|
|
|
|
~Effort();
|
|
|
|
|
|
|
|
enum Type { Type_Effort = 0, // Changing amount of resources changes the task duration
|
|
|
|
Type_FixedDuration = 1 // Changing amount of resources will not change the tasks duration
|
|
|
|
};
|
|
|
|
Type type() const { return m_type; }
|
|
|
|
void setType(Type type) { m_type = type; }
|
|
|
|
void setType(TQString type);
|
|
|
|
TQString typeToString() const;
|
|
|
|
|
|
|
|
enum Risktype { Risk_None, Risk_Low, Risk_High };
|
|
|
|
Risktype risktype() const { return m_risktype; }
|
|
|
|
void setRisktype(Risktype type) { m_risktype = type; }
|
|
|
|
void setRisktype(TQString type);
|
|
|
|
TQString risktypeToString() const;
|
|
|
|
|
|
|
|
enum Use { Use_Expected=0, Use_Optimistic=1, Use_Pessimistic=2 };
|
|
|
|
Duration effort(int use) const;
|
|
|
|
const Duration& optimistic() const {return m_optimisticEffort;}
|
|
|
|
const Duration& pessimistic() const {return m_pessimisticEffort;}
|
|
|
|
const Duration& expected() const {return m_expectedEffort;}
|
|
|
|
|
|
|
|
void set( Duration e, Duration p = Duration::zeroDuration, Duration o = Duration::zeroDuration );
|
|
|
|
void set( int e, int p = -1, int o = -1 );
|
|
|
|
void set(unsigned days, unsigned hours, unsigned minutes);
|
|
|
|
void expectedEffort(unsigned *days, unsigned *hours, unsigned *minutes);
|
|
|
|
|
|
|
|
bool load(TQDomElement &element);
|
|
|
|
void save(TQDomElement &element) const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the optimistic duration
|
|
|
|
* @param percent should be a negativ value.
|
|
|
|
*/
|
|
|
|
void setOptimisticRatio(int percent);
|
|
|
|
/**
|
|
|
|
* Return the "optimistic" duration as deviation from "expected" in percent.
|
|
|
|
* This should be a negativ value.
|
|
|
|
*/
|
|
|
|
int optimisticRatio() const;
|
|
|
|
/**
|
|
|
|
* Set the pessimistic duration
|
|
|
|
* @param percent should be a positive value.
|
|
|
|
*/
|
|
|
|
void setPessimisticRatio(int percent);
|
|
|
|
/**
|
|
|
|
* Return the "pessimistic" duration as the deviation from "expected" in percent.
|
|
|
|
* This should be a positive value.
|
|
|
|
*/
|
|
|
|
int pessimisticRatio() const;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* No effort.
|
|
|
|
*/
|
|
|
|
static const Effort zeroEffort;
|
|
|
|
|
|
|
|
Duration variance() const;
|
|
|
|
Duration pertExpected() const;
|
|
|
|
Duration pertOptimistic() const;
|
|
|
|
Duration pertPessimistic() const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
Duration m_optimisticEffort;
|
|
|
|
Duration m_pessimisticEffort;
|
|
|
|
Duration m_expectedEffort;
|
|
|
|
|
|
|
|
Type m_type;
|
|
|
|
Risktype m_risktype;
|
|
|
|
|
|
|
|
#ifndef NDEBUG
|
|
|
|
public:
|
|
|
|
void printDebug(TQCString indent);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
} //KPlato namespace
|
|
|
|
|
|
|
|
#endif
|