2 * ExpressionTreeFunction.cpp - TaskJuggler
4 * Copyright (c) 2001, 2002, 2003, 2004 by Chris Schlaeger <cs@suse.de>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of version 2 of the GNU General Public License as
8 * published by the Free Software Foundation.
14 #include "ExpressionTreeFunction.h"
15 #include "ExpressionTree.h"
16 #include "Operation.h"
17 #include "CoreAttributes.h"
24 #include "tjlib-internal.h"
29 ExpressionTreeFunction::checkCoreAttributesType(ExpressionTree* et)
31 if (supportedCoreAttributes.isEmpty())
34 QValueList<CAType>::iterator it;
35 for (it = supportedCoreAttributes.begin(); it !=
36 supportedCoreAttributes.end(); ++it)
37 if (et->getCoreAttributes()->getType() == *it)
44 ExpressionTreeFunction::longCall(ExpressionTree* et,
45 Operation* const ops[]) const
48 qDebug("Resolving %s as long", name.latin1());
49 return ((*this).*(longFunc))(et, ops);
53 ExpressionTreeFunction::findCoreAttributes(const CoreAttributes* ca,
54 const QString& id) const
56 const CoreAttributes* p;
58 switch (ca->getType())
61 p = ca->getProject()->getTask(id);
64 p = ca->getProject()->getResource(id);
67 p = ca->getProject()->getAccount(id);
70 p = ca->getProject()->getShift(id);
80 ExpressionTreeFunction::isChildOf(ExpressionTree* et,
81 Operation* const ops[]) const
83 const CoreAttributes* p;
84 if ((p = findCoreAttributes(et->getCoreAttributes(),
85 ops[0]->evalAsString(et))) == 0)
87 et->errorMessage(i18n("isChildOf: '%1' is unknown and not a "
89 .arg(et->getCoreAttributes()->getFullId())
90 .arg(ops[0]->evalAsString(et)));
94 if (et->getCoreAttributes()->getType() != p->getType())
97 ("isChildOf: '%1' and '%2' must be of same type")
98 .arg(et->getCoreAttributes()->getFullId())
99 .arg(ops[0]->evalAsString(et)));
103 return et->getCoreAttributes()->isDescendentOf(p);
107 ExpressionTreeFunction::isParentOf(ExpressionTree* et,
108 Operation* const ops[]) const
110 const CoreAttributes* p;
111 if ((p = findCoreAttributes(et->getCoreAttributes(),
112 ops[0]->evalAsString(et))) == 0)
114 et->errorMessage(i18n("isParentOf: '%1' is unknown and not a "
116 .arg(et->getCoreAttributes()->getFullId())
117 .arg(ops[0]->evalAsString(et)));
121 if (et->getCoreAttributes()->getType() != p->getType())
123 et->errorMessage(i18n
124 ("isParentOf: '%1' and '%2' must be of same type")
125 .arg(et->getCoreAttributes()->getFullId())
126 .arg(ops[0]->evalAsString(et)));
130 return et->getCoreAttributes()->isParentOf(p);
134 ExpressionTreeFunction::isLeaf(ExpressionTree* et,
135 Operation* const []) const
139 qDebug("isLeaf() called for (%d) %s => %d",
140 et->getCoreAttributes()->getType(),
141 et->getCoreAttributes()->getId().latin1(),
142 et->getCoreAttributes()->isLeaf());
144 return et->getCoreAttributes()->isLeaf();
148 ExpressionTreeFunction::treeLevel(ExpressionTree* et,
149 Operation* const []) const
151 return et->getCoreAttributes()->treeLevel() + 1;
155 ExpressionTreeFunction::isTask(ExpressionTree* et,
156 Operation* const ops[]) const
158 if (!ops[0]->isValid())
160 if (!et->getCoreAttributes()->getProject()->
161 getTask(ops[0]->evalAsString(et)))
163 et->errorMessage(i18n("isTask: task '%1' is unknown").
164 arg(ops[0]->evalAsString(et)));
170 return et->getCoreAttributes()->getType() == CA_Task &&
171 et->getCoreAttributes()->getId() == ops[0]->evalAsString(et);
175 ExpressionTreeFunction::isATask(ExpressionTree* et,
176 Operation* const []) const
178 return et->getCoreAttributes()->getType() == CA_Task;
182 ExpressionTreeFunction::isMilestone(ExpressionTree* et,
183 Operation* const[]) const
185 if (et->getCoreAttributes()->getType() != CA_Task)
188 return ((Task*) et->getCoreAttributes())->isMilestone();
192 ExpressionTreeFunction::isResource(ExpressionTree* et,
193 Operation* const ops[]) const
195 if (!ops[0]->isValid())
197 if (!et->getCoreAttributes()->getProject()->
198 getResource(ops[0]->evalAsString(et)))
200 et->errorMessage(i18n("isResource: resource '%1' is unknown").
201 arg(ops[0]->evalAsString(et)));
204 ops[0]->setValid(TRUE);
207 return et->getCoreAttributes()->getType() == CA_Resource &&
208 et->getCoreAttributes()->getId() == ops[0]->evalAsString(et);
212 ExpressionTreeFunction::isAResource(ExpressionTree* et,
213 Operation* const []) const
215 return et->getCoreAttributes()->getType() == CA_Resource;
219 ExpressionTreeFunction::isAccount(ExpressionTree* et,
220 Operation* const ops[]) const
222 if (!ops[0]->isValid())
224 if (!et->getCoreAttributes()->getProject()->
225 getAccount(ops[0]->evalAsString(et)))
227 et->errorMessage(i18n("isAccount: account '%1' is unknown").
228 arg(ops[0]->evalAsString(et)));
231 ops[0]->setValid(TRUE);
234 return et->getCoreAttributes()->getType() == CA_Account &&
235 et->getCoreAttributes()->getId() == ops[0]->evalAsString(et);
239 ExpressionTreeFunction::isAnAccount(ExpressionTree* et,
240 Operation* const []) const
242 return et->getCoreAttributes()->getType() == CA_Account;
246 ExpressionTreeFunction::isTaskStatus(ExpressionTree* et,
247 Operation* const ops[]) const
249 if (et->getCoreAttributes()->getType() != CA_Task)
253 if ((scenario = et->getCoreAttributes()->
254 getProject()->getScenarioIndex(ops[0]->evalAsString(et)) - 1) < 0)
256 et->errorMessage(i18n("isTaskStatus: Unknown scenario '%1")
257 .arg(ops[0]->evalAsString(et)));
261 static const char* stati[] = {
262 KW("undefined"), KW("notstarted"), KW("inprogresslate"),
263 KW("inprogress"), KW("ontime"), KW("inprogressearly"),
266 if (!ops[1]->isValid())
269 for (uint i = 0; i < (sizeof(stati) / sizeof(char*)); i++)
270 if (ops[1]->evalAsString(et) == stati[i])
277 et->errorMessage(i18n("isTaskStatus: Unknown task status '%1'")
278 .arg(ops[1]->evalAsString(et)));
284 return strcmp(stati[((Task*) et->getCoreAttributes())
285 ->getStatus(scenario)], ops[1]->evalAsString(et)) == 0;
289 ExpressionTreeFunction::startsBefore(ExpressionTree* et,
290 Operation* const ops[]) const
292 if (et->getCoreAttributes()->getType() != CA_Task)
296 if ((scenario = et->getCoreAttributes()->
297 getProject()->getScenarioIndex(ops[0]->evalAsString(et)) - 1) < 0)
299 et->errorMessage(i18n("startsBefore: Unknown scenario '%1'")
300 .arg(ops[0]->evalAsString(et).latin1()));
304 return ((Task*) et->getCoreAttributes())->getStart(scenario) <
305 ops[1]->evalAsTime(et);
309 ExpressionTreeFunction::startsAfter(ExpressionTree* et,
310 Operation* const ops[]) const
312 if (et->getCoreAttributes()->getType() != CA_Task)
316 if ((scenario = et->getCoreAttributes()->
317 getProject()->getScenarioIndex(ops[0]->evalAsString(et)) - 1) < 0)
319 et->errorMessage(i18n("startsAfter: Unknown scenario '%1'")
320 .arg(ops[0]->evalAsString(et)));
324 return ((Task*) et->getCoreAttributes())->getStart(scenario) >=
325 ops[1]->evalAsTime(et);
329 ExpressionTreeFunction::endsBefore(ExpressionTree* et,
330 Operation* const ops[]) const
332 if (et->getCoreAttributes()->getType() != CA_Task)
336 if ((scenario = et->getCoreAttributes()->
337 getProject()->getScenarioIndex(ops[0]->evalAsString(et)) - 1) < 0)
339 et->errorMessage(i18n("endsBefore: Unknown scenario '%s'")
340 .arg(ops[0]->evalAsString(et)));
344 return ((Task*) et->getCoreAttributes())->getEnd(scenario) <
345 ops[1]->evalAsTime(et);
349 ExpressionTreeFunction::endsAfter(ExpressionTree* et,
350 Operation* const ops[]) const
352 if (et->getCoreAttributes()->getType() != CA_Task)
356 if ((scenario = et->getCoreAttributes()->
357 getProject()->getScenarioIndex(ops[0]->evalAsString(et)) - 1) < 0)
359 et->errorMessage(i18n("endsAfter: Unknown scenario '%1'")
360 .arg(ops[0]->evalAsString(et)));
364 return ((Task*) et->getCoreAttributes())->getEnd(scenario) >
365 ops[1]->evalAsTime(et);
369 ExpressionTreeFunction::isSubTaskOf(ExpressionTree* et,
370 Operation* const ops[]) const
372 if (et->getCoreAttributes()->getType() != CA_Task)
376 if ((p = et->getCoreAttributes()->getProject()->getTask
377 (ops[0]->evalAsString(et))) == 0)
379 et->errorMessage(i18n("isSubTaskOf: task '%1' is unknown")
380 .arg(ops[0]->evalAsString(et)));
384 return p->isSubTask((Task*) et->getCoreAttributes());
388 ExpressionTreeFunction::containsTask(ExpressionTree* et,
389 Operation* const ops[]) const
391 if (et->getCoreAttributes()->getType() != CA_Task)
395 if ((st = et->getCoreAttributes()->getProject()->getTask
396 (ops[0]->evalAsString(et))) == 0)
398 et->errorMessage(i18n("containsTask: task '%1' is unknown")
399 .arg(et->getCoreAttributes()->getFullId()));
403 return ((Task*) et->getCoreAttributes())->isSubTask(st);
407 ExpressionTreeFunction::isTaskOfProject(ExpressionTree* et,
408 Operation* const ops[]) const
410 if (et->getCoreAttributes()->getType() != CA_Task)
413 if (!ops[0]->isValid())
415 if (!et->getCoreAttributes()->getProject()->isValidId
416 (ops[0]->evalAsString(et)))
418 et->errorMessage(i18n("isTaskOfProject: project ID '%1' is unkown")
419 .arg(ops[0]->evalAsString(et)));
425 return ops[0]->evalAsString(et) ==
426 ((Task*) (et->getCoreAttributes()))->getProjectId();
430 ExpressionTreeFunction::isAllocated(ExpressionTree* et,
431 Operation* const ops[]) const
437 if (et->getCoreAttributes()->getType() != CA_Resource)
439 et->errorMessage(i18n("isAllocated: '%1' is not a resource")
440 .arg(et->getCoreAttributes()->getFullId()));
444 int scenarioId = et->getCoreAttributes()->getProject()->
445 getScenarioIndex(ops[0]->evalAsString(et)) - 1;
448 et->errorMessage(i18n("isAllocated: unknown scenario '%1'")
449 .arg(ops[0]->evalAsString(et)));
453 time_t start = ops[1]->evalAsTime(et);
454 time_t end = ops[2]->evalAsTime(et);
457 et->errorMessage(i18n("isAllocated: start date is larger than end "
461 if (et->getCoreAttributes()->getProject()->getStart() > start)
462 start = et->getCoreAttributes()->getProject()->getStart();
463 if (et->getCoreAttributes()->getProject()->getEnd() < end)
464 end = et->getCoreAttributes()->getProject()->getEnd();
466 return ((Resource*) et->getCoreAttributes())->isAllocated
467 (scenarioId, Interval(start, end),
472 ExpressionTreeFunction::isDutyOf(ExpressionTree* et,
473 Operation* const ops[]) const
478 if (et->getCoreAttributes()->getType() != CA_Task)
481 Resource* resource = et->getCoreAttributes()->getProject()->
482 getResource(ops[0]->evalAsString(et));
485 et->errorMessage(i18n("isDutyOf: resource '%1' is unknown")
486 .arg(ops[0]->evalAsString(et)));
490 int scenarioId = et->getCoreAttributes()->getProject()->
491 getScenarioIndex(ops[1]->evalAsString(et)) - 1;
494 et->errorMessage(i18n("isDutyOf: unknown scenario '%1'")
495 .arg(ops[1]->evalAsString(et)));
499 return ((Task*) et->getCoreAttributes())->isDutyOf(scenarioId, resource);
503 ExpressionTreeFunction::isAllocatedToProject(ExpressionTree* et,
504 Operation* const ops[]) const
511 if (et->getCoreAttributes()->getType() != CA_Resource)
514 if (!ops[0]->isValid())
516 if (!et->getCoreAttributes()->getProject()->isValidId
517 (ops[0]->evalAsString(et)))
519 et->errorMessage(i18n("isAllocatedToProject: project ID '%1'"
521 .arg(ops[0]->evalAsString(et)));
527 int scenarioId = et->getCoreAttributes()->getProject()->
528 getScenarioIndex(ops[1]->evalAsString(et)) - 1;
531 et->errorMessage(i18n("isAllocatedToProject: unknown scenario '%1'")
532 .arg(ops[1]->evalAsString(et)));
535 time_t start = ops[2]->evalAsTime(et);
536 time_t end = ops[3]->evalAsTime(et);
539 et->errorMessage(i18n("isAllocatedToProject: start date is larger "
543 if (et->getCoreAttributes()->getProject()->getStart() > start)
544 start = et->getCoreAttributes()->getProject()->getStart();
545 if (et->getCoreAttributes()->getProject()->getEnd() < end)
546 end = et->getCoreAttributes()->getProject()->getEnd();
548 return ((Resource*) et->getCoreAttributes())->isAllocated
549 (scenarioId, Interval(start, end),
550 ops[0]->evalAsString(et));
554 ExpressionTreeFunction::isPlanAllocated(ExpressionTree* et,
555 Operation* const ops[]) const
557 if (et->getCoreAttributes()->getType() != CA_Resource)
559 et->errorMessage(i18n("isplanallocated: called for "
561 .arg(et->getCoreAttributes()->getFullId()));
564 int scenarioId = et->getCoreAttributes()->getProject()->
565 getScenarioIndex("plan") - 1;
568 et->errorMessage(i18n("isplanallocated: there is no "
569 "'plan' scenario."));
572 time_t start = ops[1]->evalAsTime(et);
573 time_t end = ops[2]->evalAsTime(et);
574 if (et->getCoreAttributes()->getProject()->getStart() > start)
575 start = et->getCoreAttributes()->getProject()->getStart();
576 if (et->getCoreAttributes()->getProject()->getEnd() < end)
577 end = et->getCoreAttributes()->getProject()->getEnd();
580 et->errorMessage(i18n("isPlanAllocated: start date "
581 "is larger than end date"));
585 return ((Resource*) et->getCoreAttributes())->isAllocated
586 (scenarioId, Interval(start, end),
587 ops[0]->evalAsString(et));
591 ExpressionTreeFunction::isActualAllocated(ExpressionTree* et,
592 Operation* const ops[]) const
594 if (et->getCoreAttributes()->getType() != CA_Resource)
596 et->errorMessage(i18n("isactualallocated: called for non-resource"));
599 int scenarioId = et->getCoreAttributes()->getProject()->
600 getScenarioIndex("actual") - 1;
603 et->errorMessage(i18n("isactualallocated: there is no 'actual'"
607 time_t start = ops[1]->evalAsTime(et);
608 time_t end = ops[2]->evalAsTime(et);
609 if (et->getCoreAttributes()->getProject()->getStart() > start)
610 start = et->getCoreAttributes()->getProject()->getStart();
611 if (et->getCoreAttributes()->getProject()->getEnd() < end)
612 end = et->getCoreAttributes()->getProject()->getEnd();
615 et->errorMessage(i18n("isActualAllocated: start date "
616 "is larger than end date"));
620 return ((Resource*) et->getCoreAttributes())->isAllocated
621 (scenarioId, Interval(start, end),
622 ops[0]->evalAsString(et));