00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kptnode.h"
00021
00022 #include "kptappointment.h"
00023 #include "kptaccount.h"
00024 #include "kptwbsdefinition.h"
00025 #include "kptresource.h"
00026 #include "kptschedule.h"
00027
00028 #include <qptrlist.h>
00029 #include <qdom.h>
00030
00031 #include <klocale.h>
00032 #include <kdebug.h>
00033
00034 namespace KPlato
00035 {
00036
00037 Node::Node(Node *parent) : m_nodes(), m_dependChildNodes(), m_dependParentNodes() {
00038
00039 m_parent = parent;
00040 init();
00041 m_id = QString();
00042 }
00043
00044 Node::Node(Node &node, Node *parent)
00045 : m_nodes(),
00046 m_dependChildNodes(),
00047 m_dependParentNodes() {
00048
00049 m_parent = parent;
00050 init();
00051 m_name = node.name();
00052 m_leader = node.leader();
00053 m_description = node.description();
00054 m_constraint = (ConstraintType) node.constraint();
00055 m_constraintStartTime = node.constraintStartTime();
00056 m_constraintEndTime = node.constraintEndTime();
00057
00058 m_dateOnlyStartDate = node.startDate();
00059 m_dateOnlyEndDate = node.endDate();
00060
00061 m_runningAccount = node.runningAccount();
00062 m_startupAccount = node.startupAccount();
00063 m_shutdownAccount = node.shutdownAccount();
00064
00065 m_startupCost = node.startupCost();
00066 m_shutdownCost = node.shutdownCost();
00067
00068 m_schedules.setAutoDelete(node.m_schedules.autoDelete());
00069 }
00070
00071 Node::~Node() {
00072 if (findNode() == this) {
00073 removeId();
00074 }
00075 Relation *rel = 0;
00076 while ((rel = m_dependParentNodes.getFirst())) {
00077 delete rel;
00078 }
00079 while ((rel = m_dependChildNodes.getFirst())) {
00080 delete rel;
00081 }
00082 if (m_runningAccount)
00083 m_runningAccount->removeRunning(*this);
00084 if (m_startupAccount)
00085 m_startupAccount->removeStartup(*this);
00086 if (m_shutdownAccount)
00087 m_shutdownAccount->removeShutdown(*this);
00088 }
00089
00090 void Node::init() {
00091 m_currentSchedule = 0;
00092 m_nodes.setAutoDelete(true);
00093 m_name="";
00094 m_constraint = Node::ASAP;
00095 m_effort = 0;
00096 m_visitedForward = false;
00097 m_visitedBackward = false;
00098
00099 m_dateOnlyStartDate = m_dateOnlyEndDate = QDate::currentDate();
00100 m_dateOnlyDuration.addDays(1);
00101
00102 m_runningAccount = 0;
00103 m_startupAccount = 0;
00104 m_shutdownAccount = 0;
00105 m_startupCost = 0.0;
00106 m_shutdownCost = 0.0;
00107 }
00108
00109 Node *Node::projectNode() {
00110 if ((type() == Type_Project) || (type() == Type_Subproject)) {
00111 return this;
00112 }
00113 if (m_parent)
00114 return m_parent->projectNode();
00115
00116 kdError()<<k_funcinfo<<"Ooops, no parent and no project found"<<endl;
00117 return 0;
00118 }
00119
00120
00121 void Node::delChildNode_NoId( Node *node, bool remove) {
00122
00123 if ( m_nodes.findRef(node) != -1 ) {
00124 if(remove)
00125 m_nodes.remove();
00126 else
00127 m_nodes.take();
00128 }
00129 }
00130
00131 void Node::delChildNode( Node *node, bool remove) {
00132
00133 if ( m_nodes.findRef(node) != -1 ) {
00134 removeId(node->id());
00135 if(remove)
00136 m_nodes.remove();
00137 else
00138 m_nodes.take();
00139 }
00140 }
00141
00142
00143 void Node::delChildNode_NoId( int number, bool remove) {
00144 if(remove)
00145 m_nodes.remove(number);
00146 else
00147 m_nodes.take(number);
00148 }
00149
00150 void Node::delChildNode( int number, bool remove) {
00151 Node *n = m_nodes.at(number);
00152 if (n)
00153 removeId(n->id());
00154 if(remove)
00155 m_nodes.remove(number);
00156 else
00157 m_nodes.take(number);
00158 }
00159
00160
00161 void Node::insertChildNode_NoId( unsigned int index, Node *node) {
00162 m_nodes.insert(index,node);
00163 node->setParent(this);
00164 }
00165
00166 void Node::insertChildNode( unsigned int index, Node *node) {
00167 node->setParent(this);
00168 if (!node->setId(node->id())) {
00169 kdError()<<k_funcinfo<<node->name()<<" Not unique id: "<<m_id<<endl;
00170 }
00171 m_nodes.insert(index,node);
00172 }
00173
00174 void Node::addChildNode( Node *node, Node *after) {
00175 int index = m_nodes.findRef(after);
00176 node->setParent(this);
00177 if (!node->setId(node->id())) {
00178 kdError()<<k_funcinfo<<node->name()<<" Not unique id: "<<m_id<<endl;
00179 }
00180 if (index == -1) {
00181 m_nodes.append(node);
00182
00183 return;
00184 }
00185 m_nodes.insert(index+1, node);
00186 }
00187
00188
00189 void Node::addChildNode_NoId( Node *node, Node *after) {
00190 int index = m_nodes.findRef(after);
00191 if (index == -1) {
00192 m_nodes.append(node);
00193 node->setParent(this);
00194 return;
00195 }
00196 m_nodes.insert(index+1, node);
00197 node->setParent(this);
00198 }
00199
00200 int Node::findChildNode( Node* node )
00201 {
00202 return m_nodes.findRef( node );
00203 }
00204
00205
00206 const Node* Node::getChildNode(int number) const {
00207
00208 const QPtrList<Node> &nodes = m_nodes;
00209 return (const_cast<QPtrList<Node> &>(nodes)).at(number);
00210 }
00211
00212 Duration *Node::getDelay() {
00213
00214
00215
00216 return 0L;
00217 }
00218
00219 void Node::addDependChildNode( Node *node, Relation::Type p) {
00220 addDependChildNode(node,p,Duration());
00221 }
00222
00223 void Node::addDependChildNode( Node *node, Relation::Type p, Duration lag) {
00224 Relation *relation = new Relation(this, node, p, lag);
00225 if (node->addDependParentNode(relation))
00226 m_dependChildNodes.append(relation);
00227 else
00228 delete relation;
00229 }
00230
00231 void Node::insertDependChildNode( unsigned int index, Node *node, Relation::Type p) {
00232 Relation *relation = new Relation(this, node, p, Duration());
00233 if (node->addDependParentNode(relation))
00234 m_dependChildNodes.insert(index, relation);
00235 else
00236 delete relation;
00237 }
00238
00239 bool Node::addDependChildNode( Relation *relation) {
00240 if(m_dependChildNodes.findRef(relation) != -1)
00241 return false;
00242 m_dependChildNodes.append(relation);
00243 return true;
00244 }
00245
00246
00247 void Node::delDependChildNode( Node *node, bool remove) {
00248 if ( m_nodes.findRef(node) != -1 ) {
00249 if(remove)
00250 m_dependChildNodes.remove();
00251 else
00252 m_dependChildNodes.take();
00253 }
00254 }
00255
00256 void Node::delDependChildNode( Relation *rel, bool remove) {
00257 if ( m_dependChildNodes.findRef(rel) != -1 ) {
00258 if(remove)
00259 m_dependChildNodes.remove();
00260 else
00261 m_dependChildNodes.take();
00262 }
00263 }
00264
00265 void Node::delDependChildNode( int number, bool remove) {
00266 if(remove)
00267 m_dependChildNodes.remove(number);
00268 else
00269 m_dependChildNodes.take(number);
00270 }
00271
00272 void Node::takeDependChildNode(Relation *rel) {
00273 if (m_dependChildNodes.findRef(rel) != -1) {
00274 m_dependChildNodes.take();
00275 }
00276 }
00277
00278 void Node::addDependParentNode( Node *node, Relation::Type p) {
00279 addDependParentNode(node,p,Duration());
00280 }
00281
00282 void Node::addDependParentNode( Node *node, Relation::Type p, Duration lag) {
00283 Relation *relation = new Relation(node, this, p, lag);
00284 if (node->addDependChildNode(relation))
00285 m_dependParentNodes.append(relation);
00286 else
00287 delete relation;
00288 }
00289
00290 void Node::insertDependParentNode( unsigned int index, Node *node, Relation::Type p) {
00291 Relation *relation = new Relation(this, node, p, Duration());
00292 if (node->addDependChildNode(relation))
00293 m_dependParentNodes.insert(index,relation);
00294 else
00295 delete relation;
00296 }
00297
00298 bool Node::addDependParentNode( Relation *relation) {
00299 if(m_dependParentNodes.findRef(relation) != -1)
00300 return false;
00301 m_dependParentNodes.append(relation);
00302 return true;
00303 }
00304
00305
00306 void Node::delDependParentNode( Node *node, bool remove) {
00307 if ( m_nodes.findRef(node) != -1 ) {
00308 if(remove)
00309 m_dependParentNodes.remove();
00310 else
00311 m_dependParentNodes.take();
00312 }
00313 }
00314
00315 void Node::delDependParentNode( Relation *rel, bool remove) {
00316 if ( m_dependParentNodes.findRef(rel) != -1 ) {
00317 if(remove)
00318 m_dependParentNodes.remove();
00319 else
00320 m_dependParentNodes.take();
00321 }
00322 }
00323
00324 void Node::delDependParentNode( int number, bool remove) {
00325 if(remove)
00326 m_dependParentNodes.remove(number);
00327 else
00328 m_dependParentNodes.take(number);
00329 }
00330
00331 void Node::takeDependParentNode(Relation *rel) {
00332 if (m_dependParentNodes.findRef(rel) != -1) {
00333 rel = m_dependParentNodes.take();
00334 }
00335 }
00336
00337 bool Node::isParentOf(Node *node) {
00338 if (m_nodes.findRef(node) != -1)
00339 return true;
00340
00341 QPtrListIterator<Node> nit(childNodeIterator());
00342 for ( ; nit.current(); ++nit ) {
00343 if (nit.current()->isParentOf(node))
00344 return true;
00345 }
00346 return false;
00347 }
00348
00349 Relation *Node::findParentRelation(Node *node) {
00350 for (int i=0; i<numDependParentNodes(); i++) {
00351 Relation *rel = getDependParentNode(i);
00352 if (rel->parent() == node)
00353 return rel;
00354 }
00355 return (Relation *)0;
00356 }
00357
00358 Relation *Node::findChildRelation(Node *node) {
00359 for (int i=0; i<numDependChildNodes(); i++) {
00360 Relation *rel = getDependChildNode(i);
00361 if (rel->child() == node)
00362 return rel;
00363 }
00364 return (Relation *)0;
00365 }
00366
00367 Relation *Node::findRelation(Node *node) {
00368 Relation *rel = findParentRelation(node);
00369 if (!rel)
00370 rel = findChildRelation(node);
00371 return rel;
00372 }
00373
00374 bool Node::isDependChildOf(Node *node) {
00375
00376 for (int i=0; i<numDependParentNodes(); i++) {
00377 Relation *rel = getDependParentNode(i);
00378 if (rel->parent() == node)
00379 return true;
00380 if (rel->parent()->isDependChildOf(node))
00381 return true;
00382 }
00383 return false;
00384 }
00385
00386 Duration Node::duration(const DateTime &time, int use, bool backward) {
00387
00388
00389 if (!time.isValid()) {
00390 kdError()<<k_funcinfo<<"Time is invalid"<<endl;
00391 return Duration::zeroDuration;
00392 }
00393 if (m_effort == 0) {
00394 kdError()<<k_funcinfo<<"m_effort == 0"<<endl;
00395 return Duration::zeroDuration;
00396 }
00397 if (m_currentSchedule == 0) {
00398 return Duration::zeroDuration;
00399 kdError()<<k_funcinfo<<"No current schedule"<<endl;
00400 }
00401 return calcDuration(time, m_effort->effort(use), backward);
00402 }
00403
00404 void Node::makeAppointments() {
00405 QPtrListIterator<Node> nit(m_nodes);
00406 for ( ; nit.current(); ++nit ) {
00407 nit.current()->makeAppointments();
00408 }
00409 }
00410
00411 void Node::calcResourceOverbooked() {
00412 QPtrListIterator<Node> nit(m_nodes);
00413 for ( ; nit.current(); ++nit ) {
00414 nit.current()->calcResourceOverbooked();
00415 }
00416 }
00417
00418 void Node::saveRelations(QDomElement &element) const {
00419 QPtrListIterator<Relation> it(m_dependChildNodes);
00420 for (; it.current(); ++it) {
00421 it.current()->save(element);
00422 }
00423 QPtrListIterator<Node> nodes(m_nodes);
00424 for ( ; nodes.current(); ++nodes ) {
00425 nodes.current()->saveRelations(element);
00426 }
00427 }
00428
00429 void Node::setConstraint(QString &type) {
00430
00431 if (type == "ASAP")
00432 setConstraint(ASAP);
00433 else if (type == "ALAP")
00434 setConstraint(ALAP);
00435 else if (type == "StartNotEarlier")
00436 setConstraint(StartNotEarlier);
00437 else if (type == "FinishNotLater")
00438 setConstraint(FinishNotLater);
00439 else if (type == "MustStartOn")
00440 setConstraint(MustStartOn);
00441 else if (type == "MustFinishOn")
00442 setConstraint(MustFinishOn);
00443 else if (type == "FixedInterval")
00444 setConstraint(FixedInterval);
00445 else
00446 setConstraint(ASAP);
00447 }
00448
00449 QString Node::constraintToString() const {
00450
00451 if (m_constraint == ASAP)
00452 return QString("ASAP");
00453 else if (m_constraint == ALAP)
00454 return QString("ALAP");
00455 else if (m_constraint == StartNotEarlier)
00456 return QString("StartNotEarlier");
00457 else if (m_constraint == FinishNotLater)
00458 return QString("FinishNotLater");
00459 else if (m_constraint == MustStartOn)
00460 return QString("MustStartOn");
00461 else if (m_constraint == MustFinishOn)
00462 return QString("MustFinishOn");
00463 else if (m_constraint == FixedInterval)
00464 return QString("FixedInterval");
00465
00466 return QString();
00467 }
00468
00469 void Node::propagateEarliestStart(DateTime &time) {
00470 if (m_currentSchedule == 0)
00471 return;
00472 m_currentSchedule->earliestStart = time;
00473
00474 QPtrListIterator<Node> it = m_nodes;
00475 for (; it.current(); ++it) {
00476 it.current()->propagateEarliestStart(time);
00477 }
00478 }
00479
00480 void Node::propagateLatestFinish(DateTime &time) {
00481 if (m_currentSchedule == 0)
00482 return;
00483 m_currentSchedule->latestFinish = time;
00484
00485 QPtrListIterator<Node> it = m_nodes;
00486 for (; it.current(); ++it) {
00487 it.current()->propagateLatestFinish(time);
00488 }
00489 }
00490
00491 void Node::moveEarliestStart(DateTime &time) {
00492 if (m_currentSchedule == 0)
00493 return;
00494 if (m_currentSchedule->earliestStart < time)
00495 m_currentSchedule->earliestStart = time;
00496 QPtrListIterator<Node> it = m_nodes;
00497 for (; it.current(); ++it) {
00498 it.current()->moveEarliestStart(time);
00499 }
00500 }
00501
00502 void Node::moveLatestFinish(DateTime &time) {
00503 if (m_currentSchedule == 0)
00504 return;
00505 if (m_currentSchedule->latestFinish > time)
00506 m_currentSchedule->latestFinish = time;
00507 QPtrListIterator<Node> it = m_nodes;
00508 for (; it.current(); ++it) {
00509 it.current()->moveLatestFinish(time);
00510 }
00511 }
00512
00513 void Node::initiateCalculation(Schedule &sch) {
00514 QPtrListIterator<Node> it = m_nodes;
00515 for (; it.current(); ++it) {
00516 it.current()->initiateCalculation(sch);
00517 }
00518 }
00519
00520 void Node::resetVisited() {
00521 m_visitedForward = false;
00522 m_visitedBackward = false;
00523 QPtrListIterator<Node> it = m_nodes;
00524 for (; it.current(); ++it) {
00525 it.current()->resetVisited();
00526 }
00527 }
00528
00529 Node *Node::siblingBefore() {
00530
00531 if (getParent())
00532 return getParent()->childBefore(this);
00533 return 0;
00534 }
00535
00536 Node *Node::childBefore(Node *node) {
00537
00538 int index = m_nodes.findRef(node);
00539 if (index > 0){
00540 return m_nodes.at(index-1);
00541 }
00542 return 0;
00543 }
00544
00545 Node *Node::siblingAfter() {
00546
00547 if (getParent())
00548 return getParent()->childAfter(this);
00549 return 0;
00550 }
00551
00552 Node *Node::childAfter(Node *node)
00553 {
00554
00555 uint index = m_nodes.findRef(node);
00556 if (index < m_nodes.count()-1) {
00557 return m_nodes.at(index+1); }
00558 return 0;
00559 }
00560
00561 bool Node::moveChildUp(Node* node)
00562 {
00563 if (findChildNode(node) == -1)
00564 return false;
00565 Node *sib = node->siblingBefore();
00566 if (!sib)
00567 return false;
00568 sib = sib->siblingBefore();
00569 delChildNode(node, false);
00570 if (sib) {
00571 addChildNode(node, sib);
00572 } else {
00573 insertChildNode(0, node);
00574 }
00575 return true;
00576 }
00577
00578 bool Node::moveChildDown(Node* node)
00579 {
00580 if (findChildNode(node) == -1)
00581 return false;
00582 Node *sib = node->siblingAfter();
00583 if (!sib)
00584 return false;
00585 delChildNode(node, false);
00586 addChildNode(node, sib);
00587 return true;
00588 }
00589
00590 bool Node::legalToLink(Node *node) {
00591 Node *p = projectNode();
00592 if (p)
00593 return p->legalToLink(this, node);
00594 return false;
00595 }
00596
00597 bool Node::isEndNode() const {
00598 return m_dependChildNodes.isEmpty();
00599 }
00600 bool Node::isStartNode() const {
00601 return m_dependParentNodes.isEmpty();
00602 }
00603
00604 bool Node::setId(QString id) {
00605
00606 if (id.isEmpty()) {
00607 kdError()<<k_funcinfo<<"id is empty"<<endl;
00608 m_id = id;
00609 return false;
00610 }
00611 if (!m_id.isEmpty()) {
00612 Node *n = findNode();
00613 if (n == this) {
00614
00615 removeId();
00616 } else if (n) {
00617
00618 kdError()<<k_funcinfo<<"My id '"<<m_id<<"' already used for different node: "<<n->name()<<endl;
00619 }
00620 }
00621 if (findNode(id)) {
00622 kdError()<<k_funcinfo<<"id '"<<id<<"' is already used for different node: "<<findNode(id)->name()<<endl;
00623 m_id = QString();
00624 return false;
00625 }
00626 m_id = id;
00627 insertId(id);
00628
00629 return true;
00630 }
00631
00632 void Node::setStartTime(DateTime startTime) {
00633 if (m_currentSchedule)
00634 m_currentSchedule->startTime = startTime;
00635 m_dateOnlyStartDate = startTime.date();
00636 }
00637
00638 void Node::setEndTime(DateTime endTime) {
00639 if (m_currentSchedule)
00640 m_currentSchedule->endTime = endTime;
00641
00642 m_dateOnlyEndDate = endTime.date();
00643 if (endTime.time().isNull() && m_dateOnlyEndDate > m_dateOnlyStartDate)
00644 m_dateOnlyEndDate = m_dateOnlyEndDate.addDays(-1);
00645 }
00646
00647 void Node::saveAppointments(QDomElement &element, long id) const {
00648
00649 QPtrListIterator<Node> it(m_nodes);
00650 for (; it.current(); ++it ) {
00651 it.current()->saveAppointments(element, id);
00652 }
00653 }
00654
00655 QPtrList<Appointment> Node::appointments() {
00656 QPtrList<Appointment> lst;
00657 if (m_currentSchedule)
00658 lst = m_currentSchedule->appointments();
00659 return lst;
00660 }
00661
00662
00663
00664
00665
00666
00667 bool Node::addAppointment(Appointment *appointment) {
00668 if (m_currentSchedule)
00669 return m_currentSchedule->add(appointment);
00670 return false;
00671 }
00672
00673 bool Node::addAppointment(Appointment *appointment, Schedule &main) {
00674
00675 Schedule *s = findSchedule(main.id());
00676 if (s == 0) {
00677 s = createSchedule(&main);
00678 }
00679 appointment->setNode(s);
00680 return s->add(appointment);
00681 }
00682
00683 void Node::addAppointment(ResourceSchedule *resource, DateTime &start, DateTime &end, double load) {
00684 Schedule *node = findSchedule(resource->id());
00685 if (node == 0) {
00686 node = createSchedule(resource->parent());
00687 }
00688 node->addAppointment(resource, start, end, load);
00689 }
00690
00691 void Node::takeSchedule(const Schedule *schedule) {
00692 if (schedule == 0)
00693 return;
00694 if (m_currentSchedule == schedule)
00695 m_currentSchedule = 0;
00696 m_schedules.take(schedule->id());
00697 }
00698
00699 void Node::addSchedule(Schedule *schedule) {
00700 if (schedule == 0)
00701 return;
00702 m_schedules.replace(schedule->id(), schedule);
00703 }
00704
00705 Schedule *Node::createSchedule(QString name, Schedule::Type type, long id) {
00706
00707 NodeSchedule *sch = new NodeSchedule(this, name, type, id);
00708 addSchedule(sch);
00709 return sch;
00710 }
00711
00712 Schedule *Node::createSchedule(Schedule *parent) {
00713
00714 NodeSchedule *sch = new NodeSchedule(parent, this);
00715 addSchedule(sch);
00716 return sch;
00717 }
00718
00719 Schedule *Node::findSchedule(const QString name, const Schedule::Type type) const {
00720 QIntDictIterator<Schedule> it = m_schedules;
00721 for (; it.current(); ++it) {
00722 if (!it.current()->isDeleted() &&
00723 it.current()->name() == name && it.current()->type() == type)
00724 return it.current();
00725 }
00726 return 0;
00727 }
00728
00729 Schedule *Node::findSchedule(const Schedule::Type type) const {
00730
00731 QIntDictIterator<Schedule> it = m_schedules;
00732 for (; it.current(); ++it) {
00733 if (!it.current()->isDeleted() && it.current()->type() == type) {
00734 return it.current();
00735 }
00736 }
00737 return 0;
00738 }
00739
00740 void Node::setScheduleDeleted(long id, bool on) {
00741 Schedule *ns = findSchedule(id);
00742 if (ns == 0) {
00743 kdError()<<k_funcinfo<<m_name<<" Could not find schedule with id="<<id<<endl;
00744 } else {
00745 ns->setDeleted(on);
00746 }
00747 }
00748
00749 void Node::setParentSchedule(Schedule *sch) {
00750 Schedule *s = findSchedule(sch->id());
00751 if (s) {
00752 s->setParent(sch);
00753 }
00754 QPtrListIterator<Node> it = m_nodes;
00755 for (; it.current(); ++it) {
00756 it.current()->setParentSchedule(sch);
00757 }
00758 }
00759
00760 bool Node::calcCriticalPath(bool fromEnd) {
00761 if (m_currentSchedule == 0)
00762 return false;
00763
00764 if (!isCritical()) {
00765 return false;
00766 }
00767 if (!fromEnd && isStartNode()) {
00768 m_currentSchedule->inCriticalPath = true;
00769 return true;
00770 }
00771 if (fromEnd && isEndNode()) {
00772 m_currentSchedule->inCriticalPath = true;
00773 return true;
00774 }
00775 QPtrListIterator<Relation> pit(m_dependParentNodes);
00776 for (; pit.current(); ++pit) {
00777 if (pit.current()->parent()->calcCriticalPath(fromEnd)) {
00778 m_currentSchedule->inCriticalPath = true;
00779 }
00780 }
00781 return m_currentSchedule->inCriticalPath;
00782 }
00783
00784 int Node::level() {
00785 Node *n = getParent();
00786 return n ? n->level() + 1 : 0;
00787 }
00788
00789 void Node::generateWBS(int count, WBSDefinition &def, QString wbs) {
00790 m_wbs = wbs + def.code(count, level());
00791
00792 QString w = wbs + def.wbs(count, level());
00793 QPtrListIterator<Node> it = m_nodes;
00794 for (int i=0; it.current(); ++it) {
00795 it.current()->generateWBS(++i, def, w);
00796 }
00797
00798 }
00799
00800 void Node::setCurrentSchedule(long id) {
00801 QPtrListIterator<Node> it = m_nodes;
00802 for (; it.current(); ++it) {
00803 it.current()->setCurrentSchedule(id);
00804 }
00805
00806 }
00808
00809 Effort::Effort( Duration e, Duration p, Duration o) {
00810 m_expectedEffort = e;
00811 m_pessimisticEffort = p;
00812 m_optimisticEffort = o;
00813 m_type = Type_Effort;
00814 }
00815
00816 Effort::Effort(const Effort &effort) {
00817 set(effort.expected(), effort.pessimistic(), effort.optimistic());
00818 setType(effort.type());
00819 }
00820
00821 Effort::~Effort() {
00822 }
00823
00824 const Effort Effort::zeroEffort( Duration::zeroDuration,
00825 Duration::zeroDuration,
00826 Duration::zeroDuration );
00827
00828 void Effort::set( Duration e, Duration p, Duration o ) {
00829 m_expectedEffort = e;
00830 m_pessimisticEffort = (p == Duration::zeroDuration) ? e : p;
00831 m_optimisticEffort = (o == Duration::zeroDuration) ? e : o;
00832
00833 }
00834
00835 void Effort::set( int e, int p, int o ) {
00836 m_expectedEffort = Duration(e);
00837 m_pessimisticEffort = (p < 0) ? Duration(e) : Duration(p);
00838 m_optimisticEffort = (o < 0) ? Duration(e) : Duration(o);
00839
00840
00841
00842
00843
00844 }
00845
00846
00847 void Effort::set(unsigned days, unsigned hours, unsigned minutes) {
00848 Duration dur(days, hours, minutes);
00849 set(dur);
00850
00851 }
00852
00853 void Effort::expectedEffort(unsigned *days, unsigned *hours, unsigned *minutes) {
00854 m_expectedEffort.get(days, hours, minutes);
00855 }
00856
00857 bool Effort::load(QDomElement &element) {
00858 m_expectedEffort = Duration::fromString(element.attribute("expected"));
00859 m_optimisticEffort = Duration::fromString(element.attribute("optimistic"));
00860 m_pessimisticEffort = Duration::fromString(element.attribute("pessimistic"));
00861 setType(element.attribute("type", "WorkBased"));
00862 return true;
00863 }
00864
00865 void Effort::save(QDomElement &element) const {
00866 QDomElement me = element.ownerDocument().createElement("effort");
00867 element.appendChild(me);
00868 me.setAttribute("expected", m_expectedEffort.toString());
00869 me.setAttribute("optimistic", m_optimisticEffort.toString());
00870 me.setAttribute("pessimistic", m_pessimisticEffort.toString());
00871 me.setAttribute("type", typeToString());
00872 }
00873
00874 QString Effort::typeToString() const {
00875 if (m_type == Type_Effort)
00876 return QString("Effort");
00877 if (m_type == Type_FixedDuration)
00878 return QString("Type_FixedDuration");
00879
00880 return QString();
00881 }
00882
00883 void Effort::setType(QString type) {
00884 if (type == "Effort")
00885 setType(Type_Effort);
00886 else if (type == "Type_FixedDuration")
00887 setType(Type_FixedDuration);
00888 else
00889 setType(Type_Effort);
00890 }
00891
00892 void Effort::setOptimisticRatio(int percent)
00893 {
00894 int p = percent>0 ? -percent : percent;
00895 m_optimisticEffort = m_expectedEffort*(100+p)/100;
00896 }
00897
00898 int Effort::optimisticRatio() const {
00899 if (m_expectedEffort == Duration::zeroDuration)
00900 return 0;
00901 return (m_optimisticEffort.milliseconds()*100/m_expectedEffort.milliseconds())-100;
00902 }
00903
00904 void Effort::setPessimisticRatio(int percent)
00905 {
00906 int p = percent<0 ? -percent : percent;
00907 m_pessimisticEffort = m_expectedEffort*(100+p)/100;
00908 }
00909 int Effort::pessimisticRatio() const {
00910 if (m_expectedEffort == Duration::zeroDuration)
00911 return 0;
00912 return m_pessimisticEffort.milliseconds()*100/m_expectedEffort.milliseconds()-100;
00913 }
00914
00915
00916 #ifndef NDEBUG
00917 void Node::printDebug(bool children, QCString indent) {
00918 kdDebug()<<indent<<" Unique node identity="<<m_id<<endl;
00919 if (m_effort) m_effort->printDebug(indent);
00920 QString s = " Constraint: " + constraintToString();
00921 if (m_constraint == MustStartOn || m_constraint == StartNotEarlier || m_constraint == FixedInterval)
00922 kdDebug()<<indent<<s<<" ("<<constraintStartTime().toString()<<")"<<endl;
00923 if (m_constraint == MustFinishOn || m_constraint == FinishNotLater || m_constraint == FixedInterval)
00924 kdDebug()<<indent<<s<<" ("<<constraintEndTime().toString()<<")"<<endl;
00925 Schedule *cs = m_currentSchedule;
00926 if (cs) {
00927 kdDebug()<<indent<<" Current schedule: "<<"id="<<cs->id()<<" '"<<cs->name()<<"' type: "<<cs->type()<<endl;
00928 } else {
00929 kdDebug()<<indent<<" Current schedule: None"<<endl;
00930 }
00931 QIntDictIterator<Schedule> it = m_schedules;
00932 for (; it.current(); ++it) {
00933 it.current()->printDebug(indent+" ");
00934 }
00935 kdDebug()<<indent<<" Parent: "<<(m_parent ? m_parent->name() : QString("None"))<<endl;
00936 kdDebug()<<indent<<" Level: "<<level()<<endl;
00937 kdDebug()<<indent<<" No of predecessors: "<<m_dependParentNodes.count()<<endl;
00938 QPtrListIterator<Relation> pit(m_dependParentNodes);
00939
00940 if (pit.count() > 0) {
00941 for ( ; pit.current(); ++pit ) {
00942 pit.current()->printDebug(indent);
00943 }
00944 }
00945 kdDebug()<<indent<<" No of successors: "<<m_dependChildNodes.count()<<endl;
00946 QPtrListIterator<Relation> cit(m_dependChildNodes);
00947
00948 if (cit.count() > 0) {
00949 for ( ; cit.current(); ++cit ) {
00950 cit.current()->printDebug(indent);
00951 }
00952 }
00953
00954
00955 indent += " ";
00956 if (children) {
00957 QPtrListIterator<Node> it(m_nodes);
00958 for ( ; it.current(); ++it ) {
00959 it.current()->printDebug(true,indent);
00960 }
00961 }
00962
00963 }
00964 #endif
00965
00966
00967 #ifndef NDEBUG
00968 void Effort::printDebug(QCString indent) {
00969 kdDebug()<<indent<<" Effort:"<<endl;
00970 indent += " ";
00971 kdDebug()<<indent<<" Expected: "<<m_expectedEffort.toString()<<endl;
00972 kdDebug()<<indent<<" Optimistic: "<<m_optimisticEffort.toString()<<endl;
00973 kdDebug()<<indent<<" Pessimistic: "<<m_pessimisticEffort.toString()<<endl;
00974 }
00975 #endif
00976
00977 }