/* This file is part of the KDE project Copyright (C) 2001 Thomas zander Copyright (C) 2004, 2005 Dag Andersen 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. */ #include "kptnode.h" #include "kptappointment.h" #include "kptaccount.h" #include "kptwbsdefinition.h" #include "kptresource.h" #include "kptschedule.h" #include #include #include #include namespace KPlato { Node::Node(Node *parent) : m_nodes(), m_dependChildNodes(), m_dependParentNodes() { //kdDebug()<removeRunning(*this); if (m_startupAccount) m_startupAccount->removeStartup(*this); if (m_shutdownAccount) m_shutdownAccount->removeShutdown(*this); } void Node::init() { m_currentSchedule = 0; m_nodes.setAutoDelete(true); m_name=""; m_constraint = Node::ASAP; m_effort = 0; m_visitedForward = false; m_visitedBackward = false; m_dateOnlyStartDate = m_dateOnlyEndDate = TQDate::currentDate(); m_dateOnlyDuration.addDays(1); m_runningAccount = 0; m_startupAccount = 0; m_shutdownAccount = 0; m_startupCost = 0.0; m_shutdownCost = 0.0; } Node *Node::projectNode() { if ((type() == Type_Project) || (type() == Type_Subproject)) { return this; } if (m_parent) return m_parent->projectNode(); kdError()<name():"")<setParent(0); } } void Node::insertChildNode( unsigned int index, Node *node) { //kdDebug()<name()<setParent(this); } void Node::addChildNode( Node *node, Node *after) { //kdDebug()<name()<setParent(this); return; } //kdDebug()<name()<setParent(this); } int Node::findChildNode( Node* node ) { return m_nodes.findRef( node ); } const Node* Node::getChildNode(int number) const { // Work around missing const at() method in TQPtrList const TQPtrList &nodes = m_nodes; return (const_cast &>(nodes)).at(number); } Duration *Node::getDelay() { /* TODO Calculate the delay of this node. Use the calculated startTime and the setted startTime. */ return 0L; } void Node::addDependChildNode( Node *node, Relation::Type p) { addDependChildNode(node,p,Duration()); } void Node::addDependChildNode( Node *node, Relation::Type p, Duration lag) { Relation *relation = new Relation(this, node, p, lag); if (node->addDependParentNode(relation)) m_dependChildNodes.append(relation); else delete relation; } void Node::insertDependChildNode( unsigned int index, Node *node, Relation::Type p) { Relation *relation = new Relation(this, node, p, Duration()); if (node->addDependParentNode(relation)) m_dependChildNodes.insert(index, relation); else delete relation; } bool Node::addDependChildNode( Relation *relation) { if(m_dependChildNodes.findRef(relation) != -1) return false; m_dependChildNodes.append(relation); return true; } // These delDepend... methods look suspicious to me, can someone review? void Node::delDependChildNode( Node *node, bool remove) { if ( m_nodes.findRef(node) != -1 ) { if(remove) m_dependChildNodes.remove(); else m_dependChildNodes.take(); } } void Node::delDependChildNode( Relation *rel, bool remove) { if ( m_dependChildNodes.findRef(rel) != -1 ) { if(remove) m_dependChildNodes.remove(); else m_dependChildNodes.take(); } } void Node::delDependChildNode( int number, bool remove) { if(remove) m_dependChildNodes.remove(number); else m_dependChildNodes.take(number); } void Node::takeDependChildNode(Relation *rel) { if (m_dependChildNodes.findRef(rel) != -1) { m_dependChildNodes.take(); } } void Node::addDependParentNode( Node *node, Relation::Type p) { addDependParentNode(node,p,Duration()); } void Node::addDependParentNode( Node *node, Relation::Type p, Duration lag) { Relation *relation = new Relation(node, this, p, lag); if (node->addDependChildNode(relation)) m_dependParentNodes.append(relation); else delete relation; } void Node::insertDependParentNode( unsigned int index, Node *node, Relation::Type p) { Relation *relation = new Relation(this, node, p, Duration()); if (node->addDependChildNode(relation)) m_dependParentNodes.insert(index,relation); else delete relation; } bool Node::addDependParentNode( Relation *relation) { if(m_dependParentNodes.findRef(relation) != -1) return false; m_dependParentNodes.append(relation); return true; } // These delDepend... methods look suspicious to me, can someone review? void Node::delDependParentNode( Node *node, bool remove) { if ( m_nodes.findRef(node) != -1 ) { if(remove) m_dependParentNodes.remove(); else m_dependParentNodes.take(); } } void Node::delDependParentNode( Relation *rel, bool remove) { if ( m_dependParentNodes.findRef(rel) != -1 ) { if(remove) m_dependParentNodes.remove(); else m_dependParentNodes.take(); } } void Node::delDependParentNode( int number, bool remove) { if(remove) m_dependParentNodes.remove(number); else m_dependParentNodes.take(number); } void Node::takeDependParentNode(Relation *rel) { if (m_dependParentNodes.findRef(rel) != -1) { rel = m_dependParentNodes.take(); } } bool Node::isParentOf(Node *node) { if (m_nodes.findRef(node) != -1) return true; TQPtrListIterator nit(childNodeIterator()); for ( ; nit.current(); ++nit ) { if (nit.current()->isParentOf(node)) return true; } return false; } Relation *Node::findParentRelation(Node *node) { for (int i=0; iparent() == node) return rel; } return (Relation *)0; } Relation *Node::findChildRelation(Node *node) { for (int i=0; ichild() == node) return rel; } return (Relation *)0; } Relation *Node::findRelation(Node *node) { Relation *rel = findParentRelation(node); if (!rel) rel = findChildRelation(node); return rel; } bool Node::isDependChildOf(Node *node) { //kdDebug()<name()<<"'"<parent() == node) return true; if (rel->parent()->isDependChildOf(node)) return true; } return false; } Duration Node::duration(const DateTime &time, int use, bool backward) { //kdDebug()<earliestStart = time; //kdDebug()<earliestStart.toString()< it = m_nodes; for (; it.current(); ++it) { it.current()->propagateEarliestStart(time); } } void Node::propagateLatestFinish(DateTime &time) { if (m_currentSchedule == 0) return; m_currentSchedule->latestFinish = time; //kdDebug()<latestFinish< it = m_nodes; for (; it.current(); ++it) { it.current()->propagateLatestFinish(time); } } void Node::moveEarliestStart(DateTime &time) { if (m_currentSchedule == 0) return; if (m_currentSchedule->earliestStart < time) m_currentSchedule->earliestStart = time; TQPtrListIterator it = m_nodes; for (; it.current(); ++it) { it.current()->moveEarliestStart(time); } } void Node::moveLatestFinish(DateTime &time) { if (m_currentSchedule == 0) return; if (m_currentSchedule->latestFinish > time) m_currentSchedule->latestFinish = time; TQPtrListIterator it = m_nodes; for (; it.current(); ++it) { it.current()->moveLatestFinish(time); } } void Node::initiateCalculation(Schedule &sch) { TQPtrListIterator it = m_nodes; for (; it.current(); ++it) { it.current()->initiateCalculation(sch); } } void Node::resetVisited() { m_visitedForward = false; m_visitedBackward = false; TQPtrListIterator it = m_nodes; for (; it.current(); ++it) { it.current()->resetVisited(); } } Node *Node::siblingBefore() { //kdDebug()<childBefore(this); return 0; } Node *Node::childBefore(Node *node) { //kdDebug()< 0){ return m_nodes.at(index-1); } return 0; } Node *Node::siblingAfter() { //kdDebug()<childAfter(this); return 0; } Node *Node::childAfter(Node *node) { //kdDebug()<siblingBefore(); if (!sib) return false; sib = sib->siblingBefore(); delChildNode(node, false); if (sib) { addChildNode(node, sib); } else { insertChildNode(0, node); } return true; } bool Node::moveChildDown(Node* node) { if (findChildNode(node) == -1) return false; // not my node! Node *sib = node->siblingAfter(); if (!sib) return false; delChildNode(node, false); addChildNode(node, sib); return true; } bool Node::legalToLink(Node *node) { Node *p = projectNode(); if (p) return p->legalToLink(this, node); return false; } bool Node::isEndNode() const { return m_dependChildNodes.isEmpty(); } bool Node::isStartNode() const { return m_dependParentNodes.isEmpty(); } bool Node::setId(TQString id) { //kdDebug()<name()<name()< it = m_nodes; for (int i=0; it.current(); ++it) { it.current()->generateWBS(++i, def, w); } } void Node::setCurrentSchedule(long id) { TQPtrListIterator it = m_nodes; for (; it.current(); ++it) { it.current()->setCurrentSchedule(id); } //kdDebug()<0 ? -percent : percent; m_optimisticEffort = m_expectedEffort*(100+p)/100; } int Effort::optimisticRatio() const { if (m_expectedEffort == Duration::zeroDuration) return 0; return (m_optimisticEffort.milliseconds()*100/m_expectedEffort.milliseconds())-100; } void Effort::setPessimisticRatio(int percent) { int p = percent<0 ? -percent : percent; m_pessimisticEffort = m_expectedEffort*(100+p)/100; } int Effort::pessimisticRatio() const { if (m_expectedEffort == Duration::zeroDuration) return 0; return m_pessimisticEffort.milliseconds()*100/m_expectedEffort.milliseconds()-100; } // Debugging #ifndef NDEBUG void Node::printDebug(bool children, TQCString indent) { kdDebug()<name()<<"' type: "<type()< it = m_schedules; for (; it.current(); ++it) { it.current()->printDebug(indent+" "); } kdDebug()<name() : TQString("None"))< pit(m_dependParentNodes); //kdDebug()< cit(m_dependChildNodes); //kdDebug()< it(m_nodes); for ( ; it.current(); ++it ) { it.current()->printDebug(true,indent); } } } #endif #ifndef NDEBUG void Effort::printDebug(TQCString indent) { kdDebug()<