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