2 * XMLFile.cpp - TaskJuggler
4 * Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006
5 * by Chris Schlaeger <cs@kde.org>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
19 #include <q3textstream.h>
23 #include "tjlib-internal.h"
24 #include "ParserNode.h"
25 #include "ParserTreeContext.h"
27 #include "Allocation.h"
29 #include "CustomAttributeDefinition.h"
30 #include "ReferenceAttribute.h"
31 #include "TextAttribute.h"
33 ParserNode* XMLFile::parserRootNode = 0;
35 XMLFile::XMLFile(Project* p) :
50 XMLFile::createParseTree()
52 /* Build the tree that describes how we expect the DOM tree to look like.
53 * Each node of the tree can have an arbitrary number of elements. Each
54 * element may then again have a node, when it has sub-elements. The
55 * structure of the tree built here very closely resembles the
57 parserRootNode = new ParserNode();
59 new ParserElement("taskjuggler", &XMLFile::doTaskJuggler,
61 ParserNode* taskjugglerNode = new ParserNode(pe);
64 pe = new ParserElement("project", &XMLFile::doProject, taskjugglerNode);
65 ParserNode* projectNode = new ParserNode(pe);
67 new ParserElement("start", &XMLFile::doProjectStart, projectNode);
68 new ParserElement("end", &XMLFile::doProjectEnd, projectNode);
69 new ParserElement("now", &XMLFile::doProjectNow, projectNode);
70 pe = new ParserElement("extend", &XMLFile::doExtend, projectNode);
71 ParserNode* extendNode = new ParserNode(pe);
73 new ParserElement("extendAttributeDefinition",
74 &XMLFile::doExtendAttribute,
77 new ParserElement("currencyFormat", &XMLFile::doCurrencyFormat,
79 pe = new ParserElement("workingHours", 0, projectNode);
80 createSubTreeWorkingHours
81 (&XMLFile::doProjectWeekdayWorkingHours, pe,
82 &XMLFile::doProjectWeekdayWorkingHoursPost);
83 pe = new ParserElement("scenario", &XMLFile::doScenario,
85 ParserNode* scenarioNode = new ParserNode(pe);
87 scenarioNode->add(pe, "scenario");
91 // vacationlist element
92 createSubTreeVacationList(&XMLFile::doProjectVacation,
96 pe = new ParserElement("shiftList", &XMLFile::doShiftList,
98 ParserNode* shiftListNode = new ParserNode(pe);
100 pe = new ParserElement("shift", &XMLFile::doShift,
102 ParserNode* shiftNode = new ParserNode(pe);
104 shiftNode->add(pe, "shift"); // recursive link
105 pe = new ParserElement("workingHours", 0, shiftNode);
106 createSubTreeWorkingHours
107 (&XMLFile::doShiftWeekdayWorkingHours, pe,
108 &XMLFile::doShiftWeekdayWorkingHoursPost);
112 // resourceList element
113 pe = new ParserElement("resourceList", &XMLFile::doResourceList,
115 ParserNode* resourceListNode = new ParserNode(pe);
117 pe = new ParserElement("resource", &XMLFile::doResource,
119 ParserNode* resourceNode = new ParserNode(pe);
121 resourceNode->add(pe, "resource"); // recursive link
122 new ParserElement("flag", &XMLFile::doFlag, resourceNode);
123 pe = new ParserElement("workingHours", 0, resourceNode);
124 createSubTreeWorkingHours
125 (&XMLFile::doResourceWeekdayWorkingHours, pe,
126 &XMLFile::doResourceWeekdayWorkingHoursPost);
127 createSubTreeVacationList(&XMLFile::doResourceVacation,
129 createSubTreeTimeInterval("shiftSelection",
130 &XMLFile::doShiftSelection,
132 createSubTreeCustomAttribute(resourceNode);
136 // accountList element
137 pe = new ParserElement("accountList", &XMLFile::doAccountList,
139 ParserNode* accountListNode = new ParserNode(pe);
141 pe = new ParserElement("account", &XMLFile::doAccount,
143 ParserNode* accountNode = new ParserNode(pe);
145 accountNode->add(pe, "account"); // recursive link
146 new ParserElement("flag", &XMLFile::doFlag, accountNode);
147 createSubTreeCustomAttribute(accountNode);
152 pe = new ParserElement("taskList", &XMLFile::doTaskList,
154 ParserNode* taskListNode = new ParserNode(pe);
156 pe = new ParserElement("task", &XMLFile::doTask, taskListNode);
157 ParserNode* taskNode = new ParserNode(pe);
159 taskNode->add(pe, "task"); // recursive link
160 pe = new ParserElement("taskScenario", &XMLFile::doTaskScenario,
162 ParserNode* taskScenarioNode = new ParserNode(pe);
164 new ParserElement("customScenario", 0, taskScenarioNode);
165 new ParserElement("start", &XMLFile::doTaskScenarioStart,
167 new ParserElement("end", &XMLFile::doTaskScenarioEnd,
169 new ParserElement("maxEnd", &XMLFile::doTaskScenarioMaxEnd,
171 new ParserElement("maxStart", &XMLFile::doTaskScenarioMaxStart,
173 new ParserElement("minEnd", &XMLFile::doTaskScenarioMinEnd,
175 new ParserElement("minStart", &XMLFile::doTaskScenarioMinStart,
179 pe = new ParserElement("allocate", &XMLFile::doAllocate,
181 ParserNode* allocateNode = new ParserNode(pe);
183 new ParserElement("candidate", &XMLFile::doCandidate,
186 new ParserElement("flag", &XMLFile::doFlag, taskNode);
187 pe = new ParserElement("depends", &XMLFile::doDepends, taskNode);
188 ParserNode* dependencyGapScenarioNode = new ParserNode(pe);
190 new ParserElement("dependencyGapScenario",
191 &XMLFile::doDependencyGapScenario,
192 dependencyGapScenarioNode);
194 pe = new ParserElement("precedes", &XMLFile::doPrecedes, taskNode);
195 dependencyGapScenarioNode = new ParserNode(pe);
197 new ParserElement("dependencyGapScenario",
198 &XMLFile::doDependencyGapScenario,
199 dependencyGapScenarioNode);
201 new ParserElement("note", &XMLFile::doNote, taskNode);
202 createSubTreeCustomAttribute(taskNode);
205 // bookingList element
206 pe = new ParserElement("bookingList", 0, taskjugglerNode);
207 ParserNode* bookingListNode = new ParserNode(pe);
209 pe = new ParserElement("resourceBooking",
210 &XMLFile::doResourceBooking,
212 ParserNode* resourceBookingNode = new ParserNode(pe);
214 createSubTreeTimeInterval("booking", &XMLFile::doBooking,
216 &XMLFile::doBookingPost);
223 XMLFile::createSubTreeTimeInterval(const QString& id,
224 ParserFunctionPtr preFunc,
225 ParserNode* parentNode,
226 ParserFunctionPtr postFunc)
228 ParserElement* pe = new ParserElement(id, preFunc, parentNode, postFunc);
229 ParserNode* timeIntervalNode = new ParserNode(pe);
231 new ParserElement("start", &XMLFile::doTimeIntervalStart,
233 new ParserElement("end", &XMLFile::doTimeIntervalEnd,
239 XMLFile::createSubTreeWorkingHours(ParserFunctionPtr func,
240 ParserElement* parentEl,
241 ParserFunctionPtr postFunc)
243 ParserNode* workingHoursNode = new ParserNode(parentEl);
246 new ParserElement("weekdayWorkingHours", func, workingHoursNode,
248 ParserNode* weekdayWorkingHoursNode = new ParserNode(pe);
250 createSubTreeTimeInterval("timeInterval",
251 &XMLFile::doTimeInterval,
252 weekdayWorkingHoursNode);
258 XMLFile::createSubTreeVacationList(ParserFunctionPtr func,
259 ParserNode* parentNode)
261 ParserElement* pe = new ParserElement("vacationList", 0, parentNode);
262 ParserNode* vacationListNode = new ParserNode(pe);
264 createSubTreeTimeInterval("vacation", func, vacationListNode);
269 XMLFile::createSubTreeCustomAttribute(ParserNode* parentNode)
272 new ParserElement("customAttribute", &XMLFile::doCustomAttribute,
274 ParserNode* customAttributeNode = new ParserNode(pe);
276 new ParserElement("textAttribute", &XMLFile::doTextAttribute,
277 customAttributeNode);
278 new ParserElement("referenceAttribute",
279 &XMLFile::doReferenceAttribute,
280 customAttributeNode);
285 XMLFile::readDOM(const QString& file, const QString&, const QString&,
290 project->setProgressBar(0, 100);
297 if ((zf = gzdopen(dup(STDIN_FILENO), "rb")) == NULL)
299 tjWarning(i18n("Cannot open compressed STDIN for reading."));
305 if ((zf = gzopen(file, "rb")) == NULL)
307 tjWarning(i18n("Cannot open compressed file %1 for "
308 "reading.").arg(file));
314 tjWarning(i18n("Processing file \'%1\'").arg(file));
320 gzgets(zf, cbuf, 1024);
324 if ((zError = gzclose(zf)) != 0)
326 tjWarning(i18n("Cannot close compressed file %1: %2")
327 .arg(file).arg(gzerror(zf, &zError)));
331 doc = new QDomDocument(file);
332 if (!doc->setContent(buf))
334 tjWarning(i18n("Syntax error in XML file '%1'.").arg(file));
344 QDomNode n = doc->firstChild();
346 ParserTreeContext ptc;
349 return parseNode(parserRootNode, n, ptc);
353 XMLFile::parseNode(const ParserNode* pn, QDomNode n, ParserTreeContext ptc)
359 QDomElement el = n.toElement();
362 const ParserElement* pEl = pn->getElement(el.tagName());
365 tjWarning(i18n("Unsupported XML element %1").arg(el.tagName()));
370 /* Create a copy of the current ptc. The node function may
371 * modify this copy to pass contextual information to the
372 * elements of this node. */
373 ParserTreeContext ptcCopy = ptc;
374 /* If a node pre function has been specified, call this function
375 * and pass it the ptc. */
376 if (pEl->getPreFunc())
377 if (!((*this).*(pEl->getPreFunc()))(n, ptcCopy))
379 /* If sub-elements of this node have been defined in the
380 * parse tree, call this function again to process the
383 if (!parseNode(pEl->getNode(), n.firstChild(), ptcCopy))
385 /* If a node post function has been specified, call this
386 * function and pass it the ptc. */
387 if (pEl->getPostFunc())
388 if (!((*this).*(pEl->getPostFunc()))(n, ptcCopy))
399 XMLFile::doTaskJuggler(QDomNode&, ParserTreeContext&)
405 XMLFile::doProject(QDomNode& n, ParserTreeContext& ptc)
407 QDomElement el = n.toElement();
408 // mandatory attributes
409 project->addId(el.attribute("id"));
410 project->setName(el.attribute("name"));
411 project->setVersion(el.attribute("version"));
412 if (el.hasAttribute("timezone") && !el.attribute("timezone").isEmpty())
413 project->setTimeZone(el.attribute("timezone"));
415 // optional attributes
416 project->setScheduleGranularity
417 (el.attribute("timingResolution", "3600").toInt());
418 project->setDailyWorkingHours
419 (el.attribute("dailyWorkingHours", "8").toDouble());
420 project->setYearlyWorkingDays
421 (el.attribute("yearlyWorkingDays", "260.714").toDouble());
422 project->setWeekStartsMonday
423 (el.attribute("weekStartMonday", "1").toInt());
424 project->setTimeFormat(el.attribute("timeFormat", "%Y-%m-%d %H:%M"));
425 project->setShortTimeFormat(el.attribute("shortTimeFormat", "%H:%M"));
427 /* Delete all default working hours since not all days have to be present
428 * in the working hour specificiation. A missing day is a day off. */
429 Q3PtrList<Interval> iv;
430 for (int i = 0; i < 7; ++i)
431 project->setWorkingHours(i, iv);
439 XMLFile::doProjectStart(QDomNode& n, ParserTreeContext&)
441 project->setStart(n.toElement().text().toLong());
446 XMLFile::doProjectEnd(QDomNode& n, ParserTreeContext&)
448 project->setEnd(n.toElement().text().toLong() - 1);
453 XMLFile::doProjectNow(QDomNode& n, ParserTreeContext&)
455 project->setNow(n.toElement().text().toLong());
460 XMLFile::doScenario(QDomNode& n, ParserTreeContext& ptc)
462 QDomElement el = n.toElement();
464 /* The project has a default scenario called plan. The XML always brings
465 * it's own scenario definition. So we have to clear the default. */
466 if (!ptc.getScenario())
467 delete project->getScenario(0);
468 Scenario* scenario = new Scenario(project, el.attribute("id"),
469 el.attribute("name"), ptc.getScenario());
470 ptc.setScenario(scenario);
476 XMLFile::doCurrencyFormat(QDomNode& n, ParserTreeContext&)
478 QDomElement el = n.toElement();
480 project->setCurrencyFormat
481 (RealFormat(el.attribute("signPrefix"), el.attribute("signSuffix"),
482 el.attribute("thousandSep"), el.attribute("fractionSep"),
483 el.attribute("fracDigits").toInt()));
488 XMLFile::doExtend(QDomNode& n, ParserTreeContext& ptc)
490 ptc.setExtendProperty(n.toElement().attribute("property"));
495 XMLFile::doExtendAttribute(QDomNode& n, ParserTreeContext& ptc)
497 QDomElement el = n.toElement();
498 QString type = el.attribute("type");
499 CustomAttributeType cat = CAT_Undefined;
502 else if (type == "reference")
504 CustomAttributeDefinition* ca =
505 new CustomAttributeDefinition(el.attribute("name"), cat);
508 tjWarning(i18n("Unknown custom attribute %1")
509 .arg(el.attribute("name")));
512 ca->setInherit(el.attribute("inherit").toInt());
513 if (ptc.getExtendProperty() == "task")
514 project->addTaskAttribute(el.attribute("id"), ca);
515 else if (ptc.getExtendProperty() == "resource")
516 project->addResourceAttribute(el.attribute("id"), ca);
517 else if (ptc.getExtendProperty() == "account")
518 project->addAccountAttribute(el.attribute("id"), ca);
524 XMLFile::doProjectWeekdayWorkingHours(QDomNode& n, ParserTreeContext& ptc)
526 QDomElement el = n.toElement();
528 Q3PtrList<Interval>* wi = new Q3PtrList<Interval>;
529 wi->setAutoDelete(true);
530 ptc.setWorkingHours(wi);
531 ptc.setWeekday(el.attribute("weekday").toInt());
537 XMLFile::doProjectWeekdayWorkingHoursPost(QDomNode&, ParserTreeContext& ptc)
539 project->setWorkingHours(ptc.getWeekday(), *ptc.getWorkingHours());
540 delete ptc.getWorkingHours();
545 XMLFile::doShiftWeekdayWorkingHours(QDomNode& n, ParserTreeContext& ptc)
547 QDomElement el = n.toElement();
549 Q3PtrList<Interval>* wi = new Q3PtrList<Interval>;
550 wi->setAutoDelete(true);
551 ptc.setWorkingHours(wi);
552 ptc.setWeekday(el.attribute("weekday").toInt());
558 XMLFile::doShiftWeekdayWorkingHoursPost(QDomNode&, ParserTreeContext& ptc)
560 ptc.getShift()->setWorkingHours(ptc.getWeekday(), *ptc.getWorkingHours());
561 delete ptc.getWorkingHours();
566 XMLFile::doResourceWeekdayWorkingHours(QDomNode& n, ParserTreeContext& ptc)
568 QDomElement el = n.toElement();
570 Q3PtrList<Interval>* wi = new Q3PtrList<Interval>;
571 wi->setAutoDelete(true);
572 ptc.setWorkingHours(wi);
573 ptc.setWeekday(el.attribute("weekday").toInt());
579 XMLFile::doResourceWeekdayWorkingHoursPost(QDomNode&, ParserTreeContext& ptc)
581 ptc.getResource()->setWorkingHours
582 (ptc.getWeekday(), *ptc.getWorkingHours());
583 delete ptc.getWorkingHours();
588 XMLFile::doTimeInterval(QDomNode&, ParserTreeContext& ptc)
590 Interval* iv = new Interval();
591 ptc.getWorkingHours()->append(iv);
598 XMLFile::doTimeIntervalStart(QDomNode& n, ParserTreeContext& ptc)
600 ptc.getInterval()->setStart(n.toElement().text().toLong());
605 XMLFile::doTimeIntervalEnd(QDomNode& n, ParserTreeContext& ptc)
607 ptc.getInterval()->setEnd(n.toElement().text().toLong() - 1);
612 XMLFile::doProjectVacation(QDomNode& n, ParserTreeContext& ptc)
614 QDomElement el = n.toElement();
615 VacationInterval* vi = new VacationInterval();
616 vi->setName(el.attribute("name"));
617 ptc.setVacationInterval(vi);
618 project->addVacation(vi);
623 XMLFile::doResourceVacation(QDomNode& n, ParserTreeContext& ptc)
625 QDomElement el = n.toElement();
626 Interval* vi = new Interval();
628 ptc.getResource()->addVacation(vi);
633 XMLFile::doCustomAttribute(QDomNode& n, ParserTreeContext& ptc)
635 ptc.setExtendProperty(n.toElement().attribute("id"));
640 XMLFile::doTextAttribute(QDomNode& n, ParserTreeContext& ptc)
642 QDomElement el = n.toElement();
644 new TextAttribute(el.attribute("text"));
645 ptc.getCoreAttributes()->addCustomAttribute(ptc.getExtendProperty(), ta);
650 XMLFile::doReferenceAttribute(QDomNode& n, ParserTreeContext& ptc)
652 QDomElement el = n.toElement();
653 ReferenceAttribute* ra =
654 new ReferenceAttribute(el.attribute("url"), el.attribute("label"));
655 ptc.getCoreAttributes()->addCustomAttribute(ptc.getExtendProperty(), ra);
660 XMLFile::doShiftList(QDomNode&, ParserTreeContext& ptc)
667 XMLFile::doShift(QDomNode& n, ParserTreeContext& ptc)
669 QDomElement el = n.toElement();
670 Shift* shift = new Shift(project, el.attribute("id"),
671 el.attribute("name"), ptc.getShift());
674 /* Delete all default working hours since not all days have to be present
675 * in the working hour specificiation. A missing day is a day off. */
676 Q3PtrList<Interval> iv;
677 for (int i = 0; i < 7; ++i)
678 shift->setWorkingHours(i, iv);
684 XMLFile::doResourceList(QDomNode&, ParserTreeContext& ptc)
691 XMLFile::doResource(QDomNode& n, ParserTreeContext& ptc)
693 QDomElement el = n.toElement();
694 Resource* r = new Resource(project, el.attribute("id"),
695 el.attribute("name"), ptc.getResource());
697 /* Delete all default working hours since not all days have to be present
698 * in the working hour specificiation. A missing day is a day off. */
699 Q3PtrList<Interval> iv;
700 for (int i = 0; i < 7; ++i)
701 r->setWorkingHours(i, iv);
709 XMLFile::doShiftSelection(QDomNode& n, ParserTreeContext& ptc)
711 Interval* iv = new Interval();
715 (iv, project->getShift(n.toElement().attribute("shiftId")));
716 ptc.getResource()->addShift(ss);
722 XMLFile::doAccountList(QDomNode&, ParserTreeContext& ptc)
729 XMLFile::doAccount(QDomNode& n, ParserTreeContext& ptc)
731 QDomElement el = n.toElement();
732 Account* a = new Account(project, el.attribute("id"),
733 el.attribute("name"), ptc.getAccount(),
735 ptc.getAccount()->getAcctType() :
736 el.attribute("type") == "cost" ?
744 XMLFile::doTaskList(QDomNode&, ParserTreeContext& ptc)
751 XMLFile::doTask(QDomNode& n, ParserTreeContext& ptc)
753 QDomElement el = n.toElement();
754 Task* t = new Task(project, el.attribute("id"), el.attribute("name"),
755 ptc.getTask(), "", 0);
757 t->setProjectId(el.attribute("projectId"));
758 t->setMilestone(el.attribute("milestone").toInt());
759 t->setScheduling(el.attribute("asapScheduling").toInt() ?
760 Task::ASAP : Task::ALAP);
761 t->setPriority(el.attribute("priority").toInt());
763 // Optional attributes
764 if (!el.attribute("responsible").isEmpty())
765 t->setResponsible(project->getResource(el.attribute("responsible")));
766 if (!el.attribute("account").isEmpty())
767 t->setAccount(project->getAccount(el.attribute("account")));
773 XMLFile::doTaskScenario(QDomNode& n, ParserTreeContext& ptc)
775 QDomElement el = n.toElement();
776 int sc = project->getScenarioIndex(el.attribute("scenarioId")) - 1;
777 ptc.setScenarioIndex(sc);
778 Task* t = ptc.getTask();
779 t->setEffort(sc, el.attribute("effort", "0.0").toDouble());
780 t->setDuration(sc, el.attribute("duration", "0.0").toDouble());
781 t->setLength(sc, el.attribute("length", "0.0").toDouble());
782 t->setScheduled(sc, el.attribute("scheduled", "0").toInt());
783 t->setComplete(sc, el.attribute("complete", "-1").toDouble());
784 /* The scenario status will be ignored as it is computed after the file is
786 t->setStatusNote(sc, el.attribute("statusNote", ""));
792 XMLFile::doTaskScenarioStart(QDomNode& n, ParserTreeContext& ptc)
794 ptc.getTask()->setSpecifiedStart(ptc.getScenarioIndex(),
795 n.toElement().text().toLong());
800 XMLFile::doTaskScenarioEnd(QDomNode& n, ParserTreeContext& ptc)
802 ptc.getTask()->setSpecifiedEnd(ptc.getScenarioIndex(),
803 n.toElement().text().toLong() - 1);
808 XMLFile::doTaskScenarioMaxEnd(QDomNode& n, ParserTreeContext& ptc)
810 ptc.getTask()->setMaxEnd(ptc.getScenarioIndex(),
811 n.toElement().text().toLong() - 1);
816 XMLFile::doTaskScenarioMinEnd(QDomNode& n, ParserTreeContext& ptc)
818 ptc.getTask()->setMinEnd(ptc.getScenarioIndex(),
819 n.toElement().text().toLong() - 1);
824 XMLFile::doTaskScenarioMaxStart(QDomNode& n, ParserTreeContext& ptc)
826 ptc.getTask()->setMaxStart(ptc.getScenarioIndex(),
827 n.toElement().text().toLong());
832 XMLFile::doTaskScenarioMinStart(QDomNode& n, ParserTreeContext& ptc)
834 ptc.getTask()->setMinStart(ptc.getScenarioIndex(),
835 n.toElement().text().toLong());
840 XMLFile::doAllocate(QDomNode&, ParserTreeContext& ptc)
842 Allocation* a = new Allocation();
843 ptc.getTask()->addAllocation(a);
844 ptc.setAllocation(a);
850 XMLFile::doCandidate(QDomNode& n, ParserTreeContext& ptc)
852 QDomElement el = n.toElement();
853 ptc.getAllocation()->addCandidate
854 (project->getResource(el.attribute("resourceId")));
860 XMLFile::doFlag(QDomNode& n, ParserTreeContext& ptc)
862 QDomElement el = n.toElement();
864 ptc.getCoreAttributes()->addFlag(el.text());
870 XMLFile::doDepends(QDomNode& n, ParserTreeContext& ptc)
872 ptc.setTaskDependency
873 (ptc.getTask()->addDepends(n.toElement().text()));
878 XMLFile::doPrecedes(QDomNode& n, ParserTreeContext& ptc)
880 ptc.setTaskDependency
881 (ptc.getTask()->addPrecedes(n.toElement().text()));
886 XMLFile::doDependencyGapScenario(QDomNode& n, ParserTreeContext& ptc)
888 QDomElement el = n.toElement();
889 int sc = project->getScenarioIndex(el.attribute("scenarioId")) - 1;
890 ptc.getTaskDependency()->setGapDuration
891 (sc, el.attribute("gapDuration", "0").toLong());
892 ptc.getTaskDependency()->setGapLength
893 (sc, el.attribute("gapLength", "0").toLong());
899 XMLFile::doNote(QDomNode& n, ParserTreeContext& ptc)
901 ptc.getTask()->setNote(n.toElement().text());
906 XMLFile::doResourceBooking(QDomNode& n, ParserTreeContext& ptc)
908 QDomElement el = n.toElement();
909 Resource* resource = project->getResource(el.attribute("resourceId"));
912 tjWarning(i18n("Booking for unknown resource %1")
913 .arg(el.attribute("resourceId")));
916 ptc.setResource(resource);
917 int sc = project->getScenarioIndex(el.attribute("scenarioId")) - 1;
920 tjWarning(i18n("Booking for unknown scenario %1")
921 .arg(el.attribute("scenarioId")));
924 ptc.setScenarioIndex(sc);
929 XMLFile::doBooking(QDomNode&, ParserTreeContext& ptc)
931 Interval* iv = new Interval();
937 XMLFile::doBookingPost(QDomNode& n, ParserTreeContext& ptc)
939 Task* t = project->getTask(n.toElement().attribute("taskId"));
942 tjWarning(i18n("Booking for unknown task %1")
943 .arg(n.toElement().attribute("taskId")));
946 ptc.getResource()->addBooking(ptc.getScenarioIndex(),
947 new Booking(ptc.getInterval(), t));