00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kptappointment.h"
00021
00022 #include "kptproject.h"
00023 #include "kpttask.h"
00024 #include "kptdatetime.h"
00025 #include "kptcalendar.h"
00026 #include "kpteffortcostmap.h"
00027 #include "kptschedule.h"
00028
00029 #include <kdebug.h>
00030
00031 namespace KPlato
00032 {
00033
00034 class Resource;
00035
00036 AppointmentInterval::AppointmentInterval() {
00037 m_load = 100.0;
00038 }
00039 AppointmentInterval::AppointmentInterval(const AppointmentInterval &interval) {
00040
00041 m_start = interval.startTime();
00042 m_end = interval.endTime();
00043 m_load = interval.load();
00044 }
00045 AppointmentInterval::AppointmentInterval(const DateTime &start, const DateTime end, double load) {
00046
00047 m_start = start;
00048 m_end = end;
00049 m_load = load;
00050 }
00051 AppointmentInterval::~AppointmentInterval() {
00052
00053 }
00054
00055 Duration AppointmentInterval::effort(const DateTime &start, const DateTime end) const {
00056 if (start >= m_end || end <= m_start) {
00057 return Duration::zeroDuration;
00058 }
00059 DateTime s = (start > m_start ? start : m_start);
00060 DateTime e = (end < m_end ? end : m_end);
00061 return (e - s) * m_load / 100;
00062 }
00063
00064 Duration AppointmentInterval::effort(const DateTime &time, bool upto) const {
00065 if (upto) {
00066 if (time <= m_start) {
00067 return Duration::zeroDuration;
00068 }
00069 DateTime e = (time < m_end ? time : m_end);
00070 return (e - m_start) * m_load / 100;
00071 }
00072
00073 if (time >= m_end) {
00074 return Duration::zeroDuration;
00075 }
00076 DateTime s = (time > m_start ? time : m_start);
00077 return (m_end - s) * m_load / 100;
00078 }
00079
00080 bool AppointmentInterval::loadXML(QDomElement &element) {
00081
00082 bool ok;
00083 QString s = element.attribute("start");
00084 if (s != "")
00085 m_start = DateTime::fromString(s);
00086 s = element.attribute("end");
00087 if (s != "")
00088 m_end = DateTime::fromString(s);
00089 m_load = element.attribute("load", "100").toDouble(&ok);
00090 if (!ok) m_load = 100;
00091 return m_start.isValid() && m_end.isValid();
00092 }
00093
00094 void AppointmentInterval::saveXML(QDomElement &element) const {
00095 QDomElement me = element.ownerDocument().createElement("interval");
00096 element.appendChild(me);
00097
00098 me.setAttribute("start", m_start.toString(Qt::ISODate));
00099 me.setAttribute("end", m_end.toString(Qt::ISODate));
00100 me.setAttribute("load", m_load);
00101 }
00102
00103 bool AppointmentInterval::isValid() const {
00104 return m_start.isValid() && m_end.isValid();
00105 }
00106
00107 AppointmentInterval AppointmentInterval::firstInterval(const AppointmentInterval &interval, const DateTime &from) const {
00108
00109 DateTime f = from;
00110 DateTime s1 = m_start;
00111 DateTime e1 = m_end;
00112 DateTime s2 = interval.startTime();
00113 DateTime e2 = interval.endTime();
00114 AppointmentInterval a;
00115 if (f.isValid() && f >= e1 && f >= e2) {
00116 return a;
00117 }
00118 if (f.isValid()) {
00119 if (s1 < f && f < e1) {
00120 s1 = f;
00121 }
00122 if (s2 < f && f < e2) {
00123 s2 = f;
00124 }
00125 } else {
00126 f = s1 < s2 ? s1 : s2;
00127 }
00128 if (s1 < s2) {
00129 a.setStartTime(s1);
00130 if (e1 <= s2) {
00131 a.setEndTime(e1);
00132 } else {
00133 a.setEndTime(s2);
00134 }
00135 a.setLoad(m_load);
00136 } else if (s1 > s2) {
00137 a.setStartTime(s2);
00138 if (e2 <= s1) {
00139 a.setEndTime(e2);
00140 } else {
00141 a.setEndTime(s1);
00142 }
00143 a.setLoad(interval.load());
00144 } else {
00145 a.setStartTime(s1);
00146 if (e1 <= e2)
00147 a.setEndTime(e1);
00148 else
00149 a.setEndTime(e2);
00150 a.setLoad(m_load + interval.load());
00151 }
00152
00153 return a;
00154 }
00155
00157
00158 Appointment::UsedEffortItem::UsedEffortItem(QDate date, Duration effort, bool overtime) {
00159 m_date = date;
00160 m_effort = effort;
00161 m_overtime = overtime;
00162 }
00163 QDate Appointment::UsedEffortItem::date() {
00164 return m_date;
00165 }
00166 Duration Appointment::UsedEffortItem::effort() {
00167 return m_effort;
00168 }
00169 bool Appointment::UsedEffortItem::isOvertime() {
00170 return m_overtime;
00171 }
00172
00173 Appointment::UsedEffort::UsedEffort() {
00174 setAutoDelete(true);
00175 }
00176
00177 void Appointment::UsedEffort::inSort(QDate date, Duration effort, bool overtime) {
00178 UsedEffortItem *item = new UsedEffortItem(date, effort, overtime);
00179 QPtrList<UsedEffortItem>::inSort(item);
00180 }
00181
00182 Duration Appointment::UsedEffort::usedEffort(bool includeOvertime) const {
00183 Duration eff;
00184 QPtrListIterator<UsedEffortItem> it(*this);
00185 for (; it.current(); ++it) {
00186 if (includeOvertime || !it.current()->isOvertime()) {
00187 eff += it.current()->effort();
00188 }
00189 }
00190 return eff;
00191 }
00192
00193 Duration Appointment::UsedEffort::usedEffort(const QDate &date, bool includeOvertime) const {
00194 Duration eff;
00195 QPtrListIterator<UsedEffortItem> it(*this);
00196 for (; it.current(); ++it) {
00197 if ((includeOvertime || !it.current()->isOvertime()) &&
00198 it.current()->date() == date) {
00199 eff += it.current()->effort();
00200 }
00201 }
00202 return eff;
00203 }
00204
00205 Duration Appointment::UsedEffort::usedEffortTo(const QDate &date, bool includeOvertime) const {
00206 Duration eff;
00207 QPtrListIterator<UsedEffortItem> it(*this);
00208 for (; it.current(); ++it) {
00209 if ((includeOvertime || !it.current()->isOvertime()) &&
00210 it.current()->date() <= date) {
00211 eff += it.current()->effort();
00212 }
00213 }
00214 return eff;
00215 }
00216
00217 Duration Appointment::UsedEffort::usedOvertime() const {
00218 UsedEffortItem *item = getFirst();
00219 return item==0 ? Duration::zeroDuration : usedOvertime(item->date());
00220 }
00221
00222 Duration Appointment::UsedEffort::usedOvertime(const QDate &date) const {
00223 Duration eff;
00224 QPtrListIterator<UsedEffortItem> it(*this);
00225 for (; it.current(); ++it) {
00226 if (it.current()->isOvertime() && it.current()->date() == date) {
00227 eff += it.current()->effort();
00228 }
00229 }
00230 return eff;
00231 }
00232
00233 Duration Appointment::UsedEffort::usedOvertimeTo(const QDate &date) const {
00234 Duration eff;
00235 QPtrListIterator<UsedEffortItem> it(*this);
00236 for (; it.current(); ++it) {
00237 if (it.current()->isOvertime() && it.current()->date() <= date) {
00238 eff += it.current()->effort();
00239 }
00240 }
00241 return eff;
00242 }
00243
00244 bool Appointment::UsedEffort::load(QDomElement &element) {
00245 QString s;
00246 QDomNodeList list = element.childNodes();
00247 for (unsigned int i=0; i<list.count(); ++i) {
00248 if (list.item(i).isElement()) {
00249 QDomElement e = list.item(i).toElement();
00250 if (e.tagName() == "actual-effort") {
00251 QDate date;
00252 s = e.attribute("date");
00253 if (s != "")
00254 date = QDate::fromString(s, Qt::ISODate);
00255 Duration eff = Duration::fromString(e.attribute("effort"));
00256 bool ot = e.attribute("overtime", "0").toInt();
00257 if (date.isValid()) {
00258 inSort(date, eff, ot);
00259 } else {
00260 kdError()<<k_funcinfo<<"Load failed, illegal date: "<<e.attribute("date")<<endl;
00261 }
00262 }
00263 }
00264 }
00265 return true;
00266 }
00267
00268 void Appointment::UsedEffort::save(QDomElement &element) const {
00269 if (isEmpty()) return;
00270 QPtrListIterator<UsedEffortItem> it = *this;
00271 for (; it.current(); ++it) {
00272 QDomElement me = element.ownerDocument().createElement("actual-effort");
00273 element.appendChild(me);
00274 me.setAttribute("date",it.current()->date().toString(Qt::ISODate));
00275 me.setAttribute("effort",it.current()->effort().toString());
00276 me.setAttribute("overtime",it.current()->isOvertime());
00277 }
00278 }
00279
00280 int Appointment::UsedEffort::compareItems(QPtrCollection::Item item1, QPtrCollection::Item item2) {
00281 QDate d1 = static_cast<UsedEffortItem*>(item1)->date();
00282 QDate d2 = static_cast<UsedEffortItem*>(item2)->date();
00283 if (d1 > d2) return 1;
00284 if (d1 < d2) return -1;
00285 return 0;
00286 }
00287
00289 Appointment::Appointment()
00290 : m_extraRepeats(), m_skipRepeats() {
00291
00292 m_resource=0;
00293 m_node=0;
00294 m_repeatInterval=Duration();
00295 m_repeatCount=0;
00296
00297 m_intervals.setAutoDelete(true);
00298 }
00299
00300 Appointment::Appointment(Schedule *resource, Schedule *node, DateTime start, DateTime end, double load)
00301 : m_extraRepeats(),
00302 m_skipRepeats() {
00303
00304 m_node = node;
00305 m_resource = resource;
00306 m_repeatInterval = Duration();
00307 m_repeatCount = 0;
00308
00309 addInterval(start, end, load);
00310
00311 m_intervals.setAutoDelete(true);
00312 }
00313
00314 Appointment::Appointment(Schedule *resource, Schedule *node, DateTime start, Duration duration, double load)
00315 : m_extraRepeats(),
00316 m_skipRepeats() {
00317
00318 m_node = node;
00319 m_resource = resource;
00320 m_repeatInterval = Duration();
00321 m_repeatCount = 0;
00322
00323 addInterval(start, duration, load);
00324
00325 m_intervals.setAutoDelete(true);
00326 }
00327
00328 Appointment::~Appointment() {
00329
00330 detach();
00331 }
00332
00333 void Appointment::addInterval(AppointmentInterval *a) {
00334
00335 m_intervals.inSort(a);
00336 }
00337 void Appointment::addInterval(const DateTime &start, const DateTime &end, double load) {
00338 addInterval(new AppointmentInterval(start, end, load));
00339 }
00340 void Appointment::addInterval(const DateTime &start, const Duration &duration, double load) {
00341 DateTime e = start+duration;
00342 addInterval(start, e, load);
00343 }
00344
00345 double Appointment::maxLoad() const {
00346 double v = 0.0;
00347 QPtrListIterator<AppointmentInterval> it = m_intervals;
00348 for (; it.current(); ++it) {
00349 if (v < it.current()->load())
00350 v = it.current()->load();
00351 }
00352 return v;
00353 }
00354
00355 DateTime Appointment::startTime() const {
00356 DateTime t;
00357 QPtrListIterator<AppointmentInterval> it = m_intervals;
00358 for (; it.current(); ++it) {
00359 if (!t.isValid() || t > it.current()->startTime())
00360 t = it.current()->startTime();
00361 }
00362 return t;
00363 }
00364
00365 DateTime Appointment::endTime() const {
00366 DateTime t;
00367 QPtrListIterator<AppointmentInterval> it = m_intervals;
00368 for (; it.current(); ++it) {
00369 if (!t.isValid() || t < it.current()->endTime())
00370 t = it.current()->endTime();
00371 }
00372 return t;
00373 }
00374
00375 void Appointment::deleteAppointmentFromRepeatList(DateTime) {
00376 }
00377
00378 void Appointment::addAppointmentToRepeatList(DateTime) {
00379 }
00380
00381 bool Appointment::isBusy(const DateTime &, const DateTime &) {
00382 return false;
00383 }
00384
00385 bool Appointment::loadXML(QDomElement &element, Project &project, Schedule &sch) {
00386
00387 QDictIterator<Node> it = project.nodeDict();
00388
00389
00390
00391 Node *node = project.findNode(element.attribute("task-id"));
00392 if (node == 0) {
00393 kdError()<<k_funcinfo<<"The referenced task does not exists: "<<element.attribute("task-id")<<endl;
00394 return false;
00395 }
00396 Resource *res = project.resource(element.attribute("resource-id"));
00397 if (res == 0) {
00398 kdError()<<k_funcinfo<<"The referenced resource does not exists: resource id="<<element.attribute("resource-id")<<endl;
00399 return false;
00400 }
00401 if (!res->addAppointment(this, sch)) {
00402 kdError()<<k_funcinfo<<"Failed to add appointment to resource: "<<res->name()<<endl;
00403 return false;
00404 }
00405 if (!node->addAppointment(this, sch)) {
00406 kdError()<<k_funcinfo<<"Failed to add appointment to node: "<<node->name()<<endl;
00407 m_resource->takeAppointment(this);
00408 return false;
00409 }
00410
00411 QDomNodeList list = element.childNodes();
00412 for (unsigned int i=0; i<list.count(); ++i) {
00413 if (list.item(i).isElement()) {
00414 QDomElement e = list.item(i).toElement();
00415 if (e.tagName() == "interval") {
00416 AppointmentInterval *a = new AppointmentInterval();
00417 if (a->loadXML(e)) {
00418 addInterval(a);
00419 } else {
00420 kdError()<<k_funcinfo<<"Could not load interval"<<endl;
00421 delete a;
00422 }
00423 }
00424 }
00425 }
00426 if (m_intervals.isEmpty()) {
00427 return false;
00428 }
00429 m_actualEffort.load(element);
00430 return true;
00431 }
00432
00433 void Appointment::saveXML(QDomElement &element) const {
00434 if (m_intervals.isEmpty()) {
00435 kdError()<<k_funcinfo<<"Incomplete appointment data: No intervals"<<endl;
00436 }
00437 if (m_resource == 0 || m_resource->resource() == 0) {
00438 kdError()<<k_funcinfo<<"Incomplete appointment data: No resource"<<endl;
00439 return;
00440 }
00441 if (m_node == 0 || m_node->node() == 0) {
00442 kdError()<<k_funcinfo<<"Incomplete appointment data: No node"<<endl;
00443 return;
00444 }
00445
00446 QDomElement me = element.ownerDocument().createElement("appointment");
00447 element.appendChild(me);
00448
00449 me.setAttribute("resource-id", m_resource->resource()->id());
00450 me.setAttribute("task-id", m_node->node()->id());
00451 QPtrListIterator<AppointmentInterval> it = m_intervals;
00452 for (; it.current(); ++it) {
00453 it.current()->saveXML(me);
00454 }
00455 m_actualEffort.save(me);
00456 }
00457
00458
00459 Duration Appointment::plannedEffort() const {
00460 Duration d;
00461 QPtrListIterator<AppointmentInterval> it = m_intervals;
00462 for (; it.current(); ++it) {
00463 d += it.current()->effort();
00464 }
00465 return d;
00466 }
00467
00468
00469 Duration Appointment::plannedEffort(const QDate &date) const {
00470 Duration d;
00471 DateTime s(date);
00472 DateTime e(date.addDays(1));
00473 QPtrListIterator<AppointmentInterval> it = m_intervals;
00474 for (; it.current(); ++it) {
00475 d += it.current()->effort(s, e);
00476 }
00477 return d;
00478 }
00479
00480
00481 Duration Appointment::plannedEffortTo(const QDate& date) const {
00482 Duration d;
00483 DateTime e(date.addDays(1));
00484 QPtrListIterator<AppointmentInterval> it = m_intervals;
00485 for (; it.current(); ++it) {
00486 d += it.current()->effort(e, true);
00487 }
00488 return d;
00489 }
00490
00491
00492
00493 EffortCostMap Appointment::plannedPrDay(const QDate& start, const QDate& end) const {
00494
00495 EffortCostMap ec;
00496 Duration eff;
00497 DateTime dt(start);
00498 DateTime ndt(dt.addDays(1));
00499 double rate = m_resource->normalRatePrHour();
00500 AppointmentIntervalListIterator it = m_intervals;
00501 for (; it.current(); ++it) {
00502 DateTime st = it.current()->startTime();
00503 DateTime e = it.current()->endTime();
00504 if (end < st.date())
00505 break;
00506 if (dt.date() < st.date()) {
00507 dt.setDate(st.date());
00508 }
00509 ndt = dt.addDays(1);
00510 while (dt.date() <= e.date()) {
00511 eff = it.current()->effort(dt, ndt);
00512 ec.add(dt.date(), eff, eff.toDouble(Duration::Unit_h) * rate);
00513 if (dt.date() < e.date() ) {
00514
00515 dt = ndt;
00516 ndt = ndt.addDays(1);
00517 } else {
00518 break;
00519 }
00520 }
00521 }
00522 return ec;
00523 }
00524
00525
00526
00527 Duration Appointment::actualEffort() const {
00528 return m_actualEffort.usedEffort();
00529 }
00530
00531
00532 Duration Appointment::actualEffort(const QDate &date) const {
00533 return m_actualEffort.usedEffort(date);
00534 }
00535
00536
00537 Duration Appointment::actualEffortTo(const QDate &date) const {
00538 return m_actualEffort.usedEffortTo(date);
00539 }
00540
00541 double Appointment::plannedCost() {
00542 if (m_resource && m_resource->resource()) {
00543 return plannedEffort().toDouble(Duration::Unit_h) * m_resource->resource()->normalRate();
00544 }
00545 return 0.0;
00546 }
00547
00548
00549 double Appointment::plannedCost(const QDate &date) {
00550 if (m_resource && m_resource->resource()) {
00551 return plannedEffort(date).toDouble(Duration::Unit_h) * m_resource->resource()->normalRate();
00552 }
00553 return 0.0;
00554 }
00555
00556
00557 double Appointment::plannedCostTo(const QDate &date) {
00558 if (m_resource && m_resource->resource()) {
00559 return plannedEffortTo(date).toDouble(Duration::Unit_h) * m_resource->resource()->normalRate();
00560 }
00561 return 0.0;
00562 }
00563
00564
00565 double Appointment::actualCost() {
00566
00567 if (m_resource && m_resource->resource()) {
00568 return (m_actualEffort.usedEffort(false ).toDouble(Duration::Unit_h)*m_resource->resource()->normalRate()) + (m_actualEffort.usedOvertime().toDouble(Duration::Unit_h)*m_resource->resource()->overtimeRate());
00569 }
00570 return 0.0;
00571 }
00572
00573
00574 double Appointment::actualCost(const QDate &date) {
00575 if (m_resource && m_resource->resource()) {
00576 return (m_actualEffort.usedEffort(date, false ).toDouble(Duration::Unit_h)*m_resource->resource()->normalRate()) + (m_actualEffort.usedOvertime(date).toDouble(Duration::Unit_h)*m_resource->resource()->overtimeRate());
00577 }
00578 return 0.0;
00579 }
00580
00581
00582 double Appointment::actualCostTo(const QDate &date) {
00583 if (m_resource && m_resource->resource()) {
00584 return (m_actualEffort.usedEffortTo(date, false ).toDouble(Duration::Unit_h)*m_resource->resource()->normalRate()) + (m_actualEffort.usedOvertimeTo(date).toDouble(Duration::Unit_h)*m_resource->resource()->overtimeRate());
00585 }
00586 return 0.0;
00587 }
00588
00589 void Appointment::addActualEffort(QDate date, Duration effort, bool overtime) {
00590 m_actualEffort.inSort(date, effort, overtime);
00591 }
00592
00593 bool Appointment::attach() {
00594
00595 if (m_resource && m_node) {
00596 m_resource->add(this);
00597 m_node->add(this);
00598 return true;
00599 }
00600 kdWarning()<<k_funcinfo<<"Failed: "<<(m_resource ? "" : "resource=0 ")
00601 <<(m_node ? "" : "node=0")<<endl;
00602 return false;
00603 }
00604
00605 void Appointment::detach() {
00606
00607 if (m_resource) {
00608 m_resource->takeAppointment(this);
00609 }
00610 if (m_node) {
00611 m_node->takeAppointment(this);
00612 }
00613 }
00614
00615
00616 Duration Appointment::effort(const DateTime &start, const DateTime &end) const {
00617 Duration d;
00618 QPtrListIterator<AppointmentInterval> it = m_intervals;
00619 for (; it.current(); ++it) {
00620 d += it.current()->effort(start, end);
00621 }
00622 return d;
00623 }
00624
00625 Duration Appointment::effort(const DateTime &start, const Duration &duration) const {
00626 Duration d;
00627 QPtrListIterator<AppointmentInterval> it = m_intervals;
00628 for (; it.current(); ++it) {
00629 d += it.current()->effort(start, start+duration);
00630 }
00631 return d;
00632 }
00633
00634 Duration Appointment::effortFrom(const DateTime &time) const {
00635 Duration d;
00636 QPtrListIterator<AppointmentInterval> it = m_intervals;
00637 for (; it.current(); ++it) {
00638 d += it.current()->effort(time, false);
00639 }
00640 return d;
00641 }
00642
00643 Appointment &Appointment::operator=(const Appointment &app) {
00644 m_resource = app.resource();
00645 m_node = app.node();
00646 m_repeatInterval = app.repeatInterval();
00647 m_repeatCount = app.repeatCount();
00648
00649 m_intervals.clear();
00650 QPtrListIterator<AppointmentInterval> it = app.intervals();
00651 for (; it.current(); ++it) {
00652 addInterval(new AppointmentInterval(*(it.current())));
00653 }
00654 return *this;
00655 }
00656
00657 Appointment &Appointment::operator+=(const Appointment &app) {
00658 *this = *this + app;
00659 return *this;
00660 }
00661
00662 Appointment Appointment::operator+(const Appointment &app) {
00663 Appointment a;
00664 AppointmentIntervalList ai = app.intervals();
00665 AppointmentInterval i;
00666 AppointmentInterval *i1 = m_intervals.first();
00667 AppointmentInterval *i2 = ai.first();
00668 DateTime from;
00669 while (i1 || i2) {
00670 if (!i1) {
00671 if (!from.isValid() || from < i2->startTime())
00672 from = i2->startTime();
00673 a.addInterval(from, i2->endTime(), i2->load());
00674
00675 from = i2->endTime();
00676 i2 = ai.next();
00677 continue;
00678 }
00679 if (!i2) {
00680 if (!from.isValid() || from < i1->startTime())
00681 from = i1->startTime();
00682 a.addInterval(from, i1->endTime(), i1->load());
00683
00684 from = i1->endTime();
00685 i1 = m_intervals.next();
00686 continue;
00687 }
00688 i = i1->firstInterval(*i2, from);
00689 if (!i.isValid()) {
00690 break;
00691 }
00692 a.addInterval(i);
00693 from = i.endTime();
00694
00695 if (i1 && a.endTime() >= i1->endTime()) {
00696 i1 = m_intervals.next();
00697 }
00698 if (i2 && a.endTime() >= i2->endTime()) {
00699 i2 = ai.next();
00700 }
00701 }
00702 return a;
00703 }
00704
00705 #ifndef NDEBUG
00706 void Appointment::printDebug(QString indent)
00707 {
00708 bool err = false;
00709 if (m_node == 0) {
00710 kdDebug()<<indent<<" No node schedule"<<endl;
00711 err = true;
00712 } else if (m_node->node() == 0) {
00713 kdDebug()<<indent<<" No node"<<endl;
00714 err = true;
00715 }
00716 if (m_resource == 0) {
00717 kdDebug()<<indent<<" No resource schedule"<<endl;
00718 err = true;
00719 } else if (m_resource->resource() == 0) {
00720 kdDebug()<<indent<<" No resource"<<endl;
00721 err = true;
00722 }
00723 if (err)
00724 return;
00725 kdDebug()<<indent<<" + Appointment to schedule: "<<m_node->name()<<" ("<<m_node->type()<<")"<<" resource: "<<m_resource->resource()->name()<<endl;
00726 indent += " ! ";
00727 QPtrListIterator<AppointmentInterval> it = intervals();
00728 for (; it.current(); ++it) {
00729 kdDebug()<<indent<<it.current()->startTime().toString()<<" - "<<it.current()->endTime().toString()<<" load="<<it.current()->load()<<endl;
00730 }
00731 }
00732 #endif
00733
00734 }