* Copyright (c) 2001, 2002 by Chris Schlaeger <cs@suse.de>
*
* This program is free software; you can redistribute it and/or modify
- * it under the terms version 2 of the GNU General Public License as
+ * it under the terms of version 2 of the GNU General Public License as
* published by the Free Software Foundation.
*
* $Id$
#include <ctype.h>
#include <stdio.h>
+#include <stdlib.h>
#include <stream.h>
#include <unistd.h>
#include "ExpressionTree.h"
#include "kotrus.h"
-extern Kotrus *kotrus;
+// Dummy marco to mark all keywords of taskjuggler syntax
+#define KW(a) a
#define READ_DATE(a, b) \
(token == a) \
QString
FileInfo::getPath() const
{
- if (file.find('/'))
+ if (file.find('/') >= 0)
return file.left(file.findRev('/') + 1);
else
return "";
case ' ':
case '\t':
break;
+ case '/':
+ /* This code skips c-style comments like the one you are just
+ * reading. */
+ if ((c = getC(FALSE)) == '*')
+ {
+ do
+ {
+ while ((c = getC(FALSE)) != '*')
+ {
+ if (c == '\n')
+ currLine++;
+ else if (c == EOF)
+ {
+ fatalError("Unterminated comment");
+ return EndOfFile;
+ }
+ }
+ } while ((c = getC(FALSE)) != '/');
+ }
+ else
+ {
+ ungetC(c);
+ ungetC('/');
+ goto BLANKS_DONE;
+ }
+ break;
case '#': // Comments start with '#' and reach towards end of line
while ((c = getC(FALSE)) != '\n' && c != EOF)
;
token += c;
if (c == '-')
{
- // this must be a ISO date yyyy-mm-dd[-hh:mm]
+ // this must be a ISO date yyyy-mm-dd[[-hh:mm]-TZ]
getDateFragment(token, c);
if (c != '-')
{
}
getDateFragment(token, c);
}
+ int i = 0;
+ if (c == '-')
+ {
+ token += c;
+ while ((c = getC()) != EOF && isalnum(c) && i++ < 12)
+ token += c;
+ }
ungetC(c);
return DATE;
}
char buf[1024];
if (getcwd(buf, 1023) != 0)
absFileName = QString(buf) + "/" + absFileName;
+ else
+ qFatal("ProjectFile::open(): getcwd failed");
}
else
absFileName = openFiles.last()->getPath() + absFileName;
+ if (debugLevel > 2)
+ qWarning("Expanded filename to %s", absFileName.latin1());
}
- while (absFileName.find("/../") >= 0)
+ int end = 0;
+ while (absFileName.find("/../", end) >= 0)
{
- int end = absFileName.find("/../");
+ end = absFileName.find("/../");
int start = absFileName.findRev('/', end - 1);
- absFileName.replace(start, end + strlen("/../") - start, "/");
+ if (start < 0)
+ start = 0;
+ else
+ start++; // move after '/'
+ if (start < end && absFileName.mid(start, end - start) != "..")
+ absFileName.remove(start, end + strlen("/../") - start);
+ end += strlen("/..");
}
// Make sure that we include each file only once.
if (includedFiles.findIndex(absFileName) != -1)
+ {
+ if (debugLevel > 2)
+ qWarning("Ignoring already read file %s",
+ absFileName.latin1());
return TRUE;
+ }
FileInfo* fi = new FileInfo(this, absFileName);
return FALSE;
}
+ if (debugLevel > 2)
+ qWarning("Reading %s", absFileName.latin1());
+
openFiles.append(fi);
includedFiles.append(absFileName);
return TRUE;
case EndOfFile:
return TRUE;
case ID:
- if (token == "task")
+ if (token == KW("task"))
{
if (!readTask(0))
return FALSE;
break;
}
- if (token == "account")
+ if (token == KW("account"))
{
if (!readAccount(0))
return FALSE;
break;
}
- else if (token == "resource")
+ else if (token == KW("resource"))
{
if (!readResource(0))
return FALSE;
break;
}
- else if (token == "vacation")
+ else if (token == KW("shift"))
+ {
+ if (!readShift(0))
+ return FALSE;
+ break;
+ }
+ else if (token == KW("vacation"))
{
time_t from, to;
+ bool isResourceVacation;
QString name;
- if (!readVacation(from, to, TRUE, &name))
+ if (!readVacation(from, to, TRUE, &name,
+ &isResourceVacation))
return FALSE;
+ if (isResourceVacation)
+ proj->getResource(name)->addVacation(
+ new Interval(from, to));
proj->addVacation(name, from, to);
break;
}
- else if (token == "priority")
+ else if (token == KW("priority"))
{
int priority;
if (!readPriority(priority))
proj->setPriority(priority);
break;
}
- else if (token == "now")
+ else if (token == KW("now"))
{
if (nextToken(token) != DATE)
{
proj->setNow(date2time(token));
break;
}
- else if (token == "mineffort")
+ else if (token == KW("mineffort"))
{
if (nextToken(token) != REAL)
{
proj->setMinEffort(token.toDouble());
break;
}
- else if (token == "maxeffort")
+ else if (token == KW("maxeffort"))
{
if (nextToken(token) != REAL)
{
proj->setMaxEffort(token.toDouble());
break;
}
- else if (token == "rate")
+ else if (token == KW("rate"))
{
if (nextToken(token) != REAL)
{
proj->setRate(token.toDouble());
break;
}
- else if (token == "currency")
+ else if (token == KW("currency"))
{
if (nextToken(token) != STRING)
{
proj->setCurrency(token);
break;
}
- else if (token == "currencydigits")
+ else if (token == KW("currencydigits"))
{
if (nextToken(token) != INTEGER)
{
proj->setCurrencyDigits(token.toInt());
break;
}
- else if (token == "timingresolution")
+ else if (token == KW("timingresolution"))
{
ulong resolution;
if (!readTimeValue(resolution))
return FALSE;
+ if (proj->resourceCount() > 0)
+ {
+ fatalError("The timing resolution cannot be changed after "
+ "resources have been declared.");
+ return FALSE;
+ }
if (resolution < 60 * 5)
{
- fatalError("scheduleGranularity must be at least 5 min");
+ fatalError("timing resolution must be at least 5 min");
return FALSE;
}
proj->setScheduleGranularity(resolution);
break;
}
- else if (token == "copyright")
+ else if (token == KW("copyright"))
{
if (nextToken(token) != STRING)
{
proj->setCopyright(token);
break;
}
- else if (token == "include")
+ else if (token == KW("include"))
{
if (!readInclude())
return FALSE;
break;
}
- else if (token == "macro")
+ else if (token == KW("macro"))
{
QString id;
if (nextToken(id) != ID)
}
break;
}
- else if (token == "flags")
+ else if (token == KW("flags"))
{
for ( ; ; )
{
}
break;
}
- else if (token == "project")
+ else if (token == KW("project"))
{
if (nextToken(token) != ID)
{
proj->setEnd(end);
break;
}
- else if (token == "projectid")
+ else if (token == KW("projectid"))
{
for ( ; ; )
{
}
break;
}
- else if (token == "xmltaskreport" )
+ else if (token == KW("xmltaskreport"))
{
if( !readXMLTaskReport())
return FALSE;
break;
}
- else if (token == "htmltaskreport" ||
- token == "htmlresourcereport")
+#ifdef HAVE_KDE
+ else if (token == "icalreport" )
+ {
+ if( !readICalTaskReport())
+ return FALSE;
+ break;
+ }
+#endif
+ else if (token == KW("htmltaskreport") ||
+ token == KW("htmlresourcereport"))
{
if (!readHTMLReport(token))
return FALSE;
break;
}
- else if (token == "htmlaccountreport")
+ else if (token == KW("htmlaccountreport"))
{
if (!readHTMLAccountReport())
return FALSE;
break;
}
- else if( token == "kotrusmode" )
- {
- if( kotrus )
- {
- if( nextToken(token) != STRING )
- {
- kotrus->setKotrusMode( "NoKotrus" );
- }
- else
- {
- if( token == "db" || token == "xml" || token == "nokotrus" )
- kotrus->setKotrusMode( token );
- else
- {
- fatalError( "Unknown kotrus-mode");
- return( false );
- }
- }
- }
- break;
+ else if (token == KW("export"))
+ {
+ if (!readExportReport())
+ return FALSE;
+ break;
+ }
+ else if (token == KW("kotrusmode"))
+ {
+ if (nextToken(token) != STRING ||
+ (token != KW("db") && token != KW("xml") &&
+ token != KW("nokotrus")))
+ {
+ fatalError("Unknown kotrus mode");
+ return FALSE;
+ }
+ if (token != KW("nokotrus"))
+ {
+ Kotrus* kotrus = new Kotrus();
+ kotrus->setKotrusMode(token);
+ proj->setKotrus(kotrus);
+ }
+ break;
}
+ else if (token == KW("supplement"))
+ {
+ if (nextToken(token) != ID ||
+ (token != KW("task") && (token != KW("resource"))))
+ {
+ fatalError("'task' or 'resource' expected");
+ return FALSE;
+ }
+ if ((token == "task" && !readTaskSupplement()) ||
+ (token == "resource" && !readResourceSupplement()))
+ return FALSE;
+ break;
+ }
// break missing on purpose!
default:
fatalError(QString("Syntax Error at '") + token + "'!");
}
if (parent)
- {
id = parent->getId() + "." + id;
- // We need to check that the task id has not been declared before.
- TaskList tl;
- parent->getSubTaskList(tl);
- for (Task* t = tl.first(); t != 0; t = tl.next())
- if (t->getId() == id)
- {
- fatalError(QString().sprintf(
- "Task %s has already been declared", id.latin1()));
- return FALSE;
- }
- }
+
+ // We need to check that the task id has not been declared before.
+ TaskList tl = proj->getTaskList();
+ for (Task* t = tl.first(); t != 0; t = tl.next())
+ if (t->getId() == id)
+ {
+ fatalError(QString().sprintf
+ ("Task %s has already been declared", id.latin1()));
+ return FALSE;
+ }
Task* task = new Task(proj, id, name, parent, getFile(), getLine());
if (parent)
parent->addSub(task);
+
+ if (!readTaskBody(task))
+ return FALSE;
+
+ if (task->getName().isEmpty())
+ {
+ fatalError(QString("No name specified for task ") + id + "!");
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+bool
+ProjectFile::readTaskSupplement()
+{
+ QString token;
+ TokenType tt;
+ Task* task;
+
+ if (((tt = nextToken(token)) != ID && tt != RELATIVE_ID) ||
+ ((task = proj->getTask(token)) == 0))
+ {
+ fatalError("Already defined task ID expected");
+ return FALSE;
+ }
+ if (nextToken(token) != LCBRACE)
+ {
+ fatalError("'}' expected");
+ return FALSE;
+ }
+ return readTaskBody(task);
+}
+
+bool
+ProjectFile::readTaskBody(Task* task)
+{
+ QString token;
+ TokenType tt;
+
for (bool done = false ; !done; )
{
switch (tt = nextToken(token))
{
case ID:
- if (token == "task")
+ if (token == KW("task"))
{
if (!readTask(task))
return FALSE;
}
- else if (token == "note")
+ else if (token == KW("note"))
{
if ((tt = nextToken(token)) == STRING)
task->setNote(token);
return FALSE;
}
}
- else if (token == "milestone")
+ else if (token == KW("milestone"))
{
task->setMilestone();
}
- else if READ_DATE("start", setPlanStart)
- else if READ_DATE("end", setPlanEnd)
- else if READ_DATE("minstart", setMinStart)
- else if READ_DATE("maxstart", setMaxStart)
- else if READ_DATE("minend", setMinEnd)
- else if READ_DATE("maxend", setMaxEnd)
- else if READ_DATE("actualstart", setActualStart)
- else if READ_DATE("actualsnd", setActualEnd)
- else if (token == "length")
+ else if READ_DATE(KW("start"), setPlanStart)
+ else if READ_DATE(KW("end"), setPlanEnd)
+ else if READ_DATE(KW("minstart"), setMinStart)
+ else if READ_DATE(KW("maxstart"), setMaxStart)
+ else if READ_DATE(KW("minend"), setMinEnd)
+ else if READ_DATE(KW("maxend"), setMaxEnd)
+ else if READ_DATE(KW("actualstart"), setActualStart)
+ else if READ_DATE(KW("actualend"), setActualEnd)
+ else if (token == KW("length"))
{
double d;
if (!readPlanTimeFrame(task, d))
return FALSE;
task->setPlanLength(d);
}
- else if (token == "effort")
+ else if (token == KW("effort"))
{
double d;
if (!readPlanTimeFrame(task, d))
return FALSE;
task->setPlanEffort(d);
}
- else if (token == "duration")
+ else if (token == KW("duration"))
{
double d;
if (!readPlanTimeFrame(task, d))
return FALSE;
task->setPlanDuration(d);
}
- else if (token == "actuallength")
+ else if (token == KW("actuallength"))
{
double d;
if (!readPlanTimeFrame(task, d))
return FALSE;
task->setActualLength(d);
}
- else if (token == "actualeffort")
+ else if (token == KW("actualeffort"))
{
double d;
if (!readPlanTimeFrame(task, d))
return FALSE;
task->setActualEffort(d);
}
- else if (token == "actualduration")
+ else if (token == KW("actualduration"))
{
double d;
if (!readPlanTimeFrame(task, d))
return FALSE;
task->setActualDuration(d);
}
- else if (token == "complete")
+ else if (token == KW("complete"))
{
if (nextToken(token) != INTEGER)
{
}
task->setComplete(complete);
}
- else if (token == "responsible")
+ else if (token == KW("responsible"))
{
Resource* r;
if (nextToken(token) != ID ||
}
task->setResponsible(r);
}
- else if (token == "allocate")
+ else if (token == KW("allocate"))
{
if (!readAllocate(task))
return FALSE;
}
- else if (token == "depends")
+ else if (token == KW("depends"))
{
for ( ; ; )
{
}
}
}
- else if (token == "preceeds")
+ else if (token == KW("preceeds"))
{
for ( ; ; )
{
}
}
}
- else if (token == "scheduling")
+ else if (token == KW("scheduling"))
{
nextToken(token);
- if (token == "asap")
+ if (token == KW("asap"))
task->setScheduling(Task::ASAP);
- else if (token == "alap")
+ else if (token == KW("alap"))
task->setScheduling(Task::ALAP);
else
{
return FALSE;
}
}
- else if (token == "flags")
+ else if (token == KW("flags"))
{
for ( ; ; )
{
}
}
}
- else if (token == "priority")
+ else if (token == KW("priority"))
{
int priority;
if (!readPriority(priority))
task->setPriority(priority);
break;
}
- else if (token == "account")
+ else if (token == KW("account"))
{
QString account;
if (nextToken(account) != ID ||
task->setAccount(proj->getAccount(account));
break;
}
- else if (token == "startcredit")
+ else if (token == KW("startcredit"))
{
if (nextToken(token) != REAL)
{
task->setStartCredit(token.toDouble());
break;
}
- else if (token == "endcredit")
+ else if (token == KW("endcredit"))
{
if (nextToken(token) != REAL)
{
task->setEndCredit(token.toDouble());
break;
}
- else if (token == "projectid")
+ else if (token == KW("projectid"))
{
if (nextToken(token) != ID ||
!proj->isValidId(token))
task->setProjectId(token);
break;
}
- else if (token == "include")
+ else if (token == KW("include"))
{
if (!readInclude())
return FALSE;
done = true;
break;
default:
- qDebug("%s", token.latin1());
fatalError(QString("Syntax Error at '") + token + "'");
return FALSE;
}
}
- if (task->getName().isEmpty())
- {
- fatalError(QString("No name specified for task ") + id + "!");
- return FALSE;
- }
-
return TRUE;
}
bool
-ProjectFile::readVacation(time_t& from, time_t& to, bool readName, QString* n)
+ProjectFile::readVacation(time_t& from, time_t& to, bool readName,
+ QString* n, bool* isResourceVacation)
{
TokenType tt;
if (readName)
{
- if ((tt = nextToken(*n)) != STRING)
+ /* If we find a string then we expect a global vacation
+ * definition. If we find an ID then this is an out-of-scope
+ * vacation definition for the resource with this particular
+ * ID. */
+ *isResourceVacation = FALSE;
+ if ((tt = nextToken(*n)) == STRING)
+ ; // We don't have to do anything
+#if 0
+ else if (tt == ID)
+ {
+ if (!proj->getResource(*n))
+ {
+ fatalError(QString().sprintf(
+ "Resource %s is undefined", n->latin1()));
+ return FALSE;
+ }
+ *isResourceVacation = TRUE;
+ }
+#endif
+ else
{
fatalError("String expected");
return FALSE;
if ((tt = nextToken(token)) == LCBRACE)
{
// read optional attributes
- while ((tt = nextToken(token)) != RCBRACE)
+ if (!readResourceBody(r))
+ return FALSE;
+ }
+ else
+ openFiles.last()->returnToken(tt, token);
+
+ proj->addResource(r);
+
+ return TRUE;
+}
+
+bool
+ProjectFile::readResourceSupplement()
+{
+ QString token;
+ Resource* r;
+ if (nextToken(token) != ID || (r = proj->getResource(token)) == 0)
+ {
+ fatalError("Already defined resource ID expected");
+ return FALSE;
+ }
+ if (nextToken(token) != LCBRACE)
+ {
+ fatalError("'{' expected");
+ return FALSE;
+ }
+ return readResourceBody(r);
+}
+
+bool
+ProjectFile::readResourceBody(Resource* r)
+{
+ QString token;
+ TokenType tt;
+
+ while ((tt = nextToken(token)) != RCBRACE)
+ {
+ if (tt != ID)
{
- if (tt != ID)
+ fatalError(QString("Unknown attribute '") + token + "'");
+ return FALSE;
+ }
+ if (token == KW("resource"))
+ {
+ if (!readResource(r))
+ return FALSE;
+ }
+ else if (token == KW("mineffort"))
+ {
+ if (nextToken(token) != REAL)
{
- fatalError(QString("Unknown attribute '") + token + "'");
+ fatalError("Real value exptected");
return FALSE;
}
- if (token == "resource")
+ r->setMinEffort(token.toDouble());
+ }
+ else if (token == KW("maxeffort"))
+ {
+ if (nextToken(token) != REAL)
{
- if (!readResource(r))
- return FALSE;
+ fatalError("Real value exptected");
+ return FALSE;
}
- else if (token == "mineffort")
+ r->setMaxEffort(token.toDouble());
+ }
+ else if (token == KW("efficiency"))
+ {
+ if (nextToken(token) != REAL)
{
- if (nextToken(token) != REAL)
- {
- fatalError("Real value exptected");
- return FALSE;
- }
- r->setMinEffort(token.toDouble());
+ fatalError("Read value expected");
+ return FALSE;
}
- else if (token == "maxeffort")
+ r->setEfficiency(token.toDouble());
+ }
+ else if (token == KW("rate"))
+ {
+ if (nextToken(token) != REAL)
{
- if (nextToken(token) != REAL)
- {
- fatalError("Real value exptected");
- return FALSE;
- }
- r->setMaxEffort(token.toDouble());
+ fatalError("Real value exptected");
+ return FALSE;
}
- else if (token == "efficiency")
+ r->setRate(token.toDouble());
+ }
+ else if (token == KW("kotrusid"))
+ {
+ if (nextToken(token) != STRING)
{
- if (nextToken(token) != REAL)
- {
- fatalError("Read value expected");
- return FALSE;
- }
- r->setEfficiency(token.toDouble());
+ fatalError("String expected");
+ return FALSE;
}
- else if (token == "rate")
+ r->setKotrusId(token);
+ }
+ else if (token == KW("vacation"))
+ {
+ time_t from, to;
+ if (!readVacation(from, to))
+ return FALSE;
+ r->addVacation(new Interval(from, to));
+ }
+ else if (token == KW("workinghours"))
+ {
+ int dow;
+ QPtrList<Interval>* l = new QPtrList<Interval>();
+ if (!readWorkingHours(dow, l))
+ return FALSE;
+
+ r->setWorkingHours(dow, l);
+ }
+ else if (token == KW("shift"))
+ {
+ QString id;
+ if (nextToken(id) != ID)
{
- if (nextToken(token) != REAL)
- {
- fatalError("Real value exptected");
- return FALSE;
- }
- r->setRate(token.toDouble());
+ fatalError("Shift ID expected");
+ return FALSE;
}
- else if (token == "kotrusid")
+ Shift* s;
+ if ((s = proj->getShift(id)) == 0)
{
- if (nextToken(token) != STRING)
+ fatalError("Unknown shift");
+ return FALSE;
+ }
+ time_t from, to;
+ if (!readVacation(from, to))
+ return FALSE;
+ if (!r->addShift(Interval(from, to), s))
+ {
+ fatalError("Shift interval overlaps with other");
+ return FALSE;
+ }
+ }
+ else if (token == KW("flags"))
+ {
+ for ( ; ; )
+ {
+ QString flag;
+ if (nextToken(flag) != ID || !proj->isAllowedFlag(flag))
{
- fatalError("String expected");
+ fatalError("flag unknown");
return FALSE;
}
- r->setKotrusId(token);
+ r->addFlag(flag);
+ if ((tt = nextToken(token)) != COMMA)
+ {
+ openFiles.last()->returnToken(tt, token);
+ break;
+ }
}
- else if (token == "vacation")
+ }
+ else if (token == KW("include"))
+ {
+ if (!readInclude())
+ return FALSE;
+ break;
+ }
+ else
+ {
+ fatalError(QString("Unknown attribute '") + token + "'");
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+bool
+ProjectFile::readShift(Shift* parent)
+{
+ // Syntax: 'shift id "name" { ... }
+ QString id;
+ if (nextToken(id) != ID)
+ {
+ fatalError("ID expected");
+ return FALSE;
+ }
+ QString name;
+ if (nextToken(name) != STRING)
+ {
+ fatalError("String expected");
+ return FALSE;
+ }
+
+ if (proj->getShift(id))
+ {
+ fatalError(QString().sprintf(
+ "Shift %s has already been defined", id.latin1()));
+ return FALSE;
+ }
+
+ Shift* s = new Shift(proj, id, name, parent);
+
+ TokenType tt;
+ QString token;
+ if ((tt = nextToken(token)) == LCBRACE)
+ {
+ // read optional attributes
+ while ((tt = nextToken(token)) != RCBRACE)
+ {
+ if (tt != ID)
{
- time_t from, to;
- if (!readVacation(from, to))
+ fatalError(QString("Unknown attribute '") + token + "'");
+ return FALSE;
+ }
+ if (token == KW("shift"))
+ {
+ if (!readShift(s))
return FALSE;
- r->addVacation(new Interval(from, to));
}
- else if (token == "workinghours")
+ else if (token == KW("workinghours"))
{
int dow;
QPtrList<Interval>* l = new QPtrList<Interval>();
if (!readWorkingHours(dow, l))
return FALSE;
- r->setWorkingHours(dow, l);
- }
- else if (token == "flags")
- {
- for ( ; ; )
- {
- QString flag;
- if (nextToken(flag) != ID || !proj->isAllowedFlag(flag))
- {
- fatalError("flag unknown");
- return FALSE;
- }
- r->addFlag(flag);
- if ((tt = nextToken(token)) != COMMA)
- {
- openFiles.last()->returnToken(tt, token);
- break;
- }
- }
+ s->setWorkingHours(dow, l);
}
- else if (token == "include")
+ else if (token == KW("include"))
{
if (!readInclude())
return FALSE;
else
openFiles.last()->returnToken(tt, token);
- proj->addResource(r);
+ proj->addShift(s);
return TRUE;
}
/* Only accounts with no parent can have a type specifier. All
* sub accounts inherit the type of the parent. */
QString at;
- if (nextToken(at) != ID && (at != "cost" || at != "revenue"))
+ if (nextToken(at) != ID && (at != KW("cost") ||
+ at != KW("revenue")))
{
fatalError("Account type 'cost' or 'revenue' expected");
return FALSE;
}
- acctType = at == "cost" ? Account::Cost : Account::Revenue;
+ acctType = at == KW("cost") ? Account::Cost : Account::Revenue;
}
else
- acctType = parent->getType();
+ acctType = parent->getAcctType();
Account* a = new Account(proj, id, name, parent, acctType);
if (parent)
fatalError(QString("Unknown attribute '") + token + "'");
return FALSE;
}
- if (token == "account" && !cantBeParent)
+ if (token == KW("account") && !cantBeParent)
{
if (!readAccount(a))
return FALSE;
hasSubAccounts = TRUE;
}
- else if (token == "credit")
+ else if (token == KW("credit"))
{
if (!readCredit(a))
return FALSE;
}
- else if (token == "kotrusid" && !hasSubAccounts)
+ else if (token == KW("kotrusid") && !hasSubAccounts)
{
if (nextToken(token) != STRING)
{
a->setKotrusId(token);
cantBeParent = TRUE;
}
- else if (token == "include")
+ else if (token == KW("include"))
{
if (!readInclude())
return FALSE;
fatalError(QString("Unknown attribute '") + token + "'");
return FALSE;
}
- if (token == "load")
+ if (token == KW("load"))
{
if (nextToken(token) != REAL)
{
}
a->setLoad((int) (100 * load));
}
- else if (token == "persistent")
+ else if (token == KW("persistent"))
{
a->setPersistent(TRUE);
}
- else if (token == "alternative")
+ else if (token == KW("alternative"))
{
do
{
fatalError("Unit expected");
return FALSE;
}
- if (unit == "min")
+ if (unit == KW("min"))
value = val.toULong() * 60;
- else if (unit == "h")
+ else if (unit == KW("h"))
value = val.toULong() * (60 * 60);
- else if (unit == "d")
+ else if (unit == KW("d"))
value = val.toULong() * (60 * 60 * 24);
- else if (unit == "w")
+ else if (unit == KW("w"))
value = val.toULong() * (60 * 60 * 24 * 7);
- else if (unit == "m")
+ else if (unit == KW("m"))
value = val.toULong() * (60 * 60 * 24 * 30);
- else if (unit == "y")
+ else if (unit == KW("y"))
value = val.toULong() * (60 * 60 * 24 * 356);
else
{
fatalError("Unit expected");
return FALSE;
}
- if (unit == "min")
+ if (unit == KW("min"))
value = val.toDouble() / (8 * 60);
- else if (unit == "h")
+ else if (unit == KW("h"))
value = val.toDouble() / 8;
- else if (unit == "d")
+ else if (unit == KW("d"))
value = val.toDouble();
- else if (unit == "w")
+ else if (unit == KW("w"))
value = val.toDouble() * 5;
- else if (unit == "m")
+ else if (unit == KW("m"))
value = val.toDouble() * 20;
- else if (unit == "y")
+ else if (unit == KW("y"))
value = val.toDouble() * 240;
else
{
fatalError("Weekday expected");
return FALSE;
}
- const char* days[] = { "SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT" };
+ const char* days[] = { KW("sun"), KW("mon"), KW("tue"), KW("wed"),
+ KW("thu"), KW("fri"), KW("sat") };
for (dayOfWeek = 0; dayOfWeek < 7; dayOfWeek++)
if (days[dayOfWeek] == day)
break;
fatalError("Weekday expected");
return FALSE;
}
+
+ QString token;
+ TokenType tt;
+ if ((tt = nextToken(token)) == ID && token == KW("off"))
+ return TRUE;
+ else
+ returnToken(tt, token);
+
for ( ; ; )
{
QString start;
return TRUE;
}
+#ifdef HAVE_KDE
+bool
+ProjectFile::readICalTaskReport()
+{
+ QString token;
+ if (nextToken(token) != STRING)
+ {
+ fatalError("File name expected");
+ return FALSE;
+ }
+ ReportICal *rep = new ReportICal( proj, token, proj->getStart(), proj->getEnd());
+ proj->addICalReport( rep );
+
+ return( true );
+}
+#endif
+
bool
ProjectFile::readXMLTaskReport()
{
fatalError("File name expected");
return FALSE;
}
- ReportXML *rep = new ReportXML( proj, token, proj->getStart(), proj->getEnd());
+ ReportXML *rep = new ReportXML(proj, token, proj->getStart(),
+ proj->getEnd());
proj->addXMLReport( rep );
return( true );
}
ReportHtml* report;
- if (reportType == "htmltaskreport")
+ if (reportType == KW("htmltaskreport"))
report = new HTMLTaskReport(proj, token, proj->getStart(),
proj->getEnd());
- else if (reportType == "htmlresourcereport")
+ else if (reportType == KW("htmlresourcereport"))
report = new HTMLResourceReport(proj, token, proj->getStart(),
proj->getEnd());
else
fatalError("Attribute ID or '}' expected");
return FALSE;
}
- if (token == "columns")
+ if (token == KW("columns"))
{
report->clearColumns();
for ( ; ; )
}
}
}
- else if (token == "start")
+ else if (token == KW("start"))
{
if (nextToken(token) != DATE)
{
}
report->setStart(date2time(token));
}
- else if (token == "end")
+ else if (token == KW("end"))
{
if (nextToken(token) != DATE)
{
}
report->setEnd(date2time(token));
}
- else if (token == "headline")
+ else if (token == KW("headline"))
{
if (nextToken(token) != STRING)
{
}
report->setHeadline(token);
}
- else if (token == "caption")
+ else if (token == KW("caption"))
{
if (nextToken(token) != STRING)
{
}
report->setCaption(token);
}
- else if (token == "showactual")
+ else if (token == KW("showactual"))
{
report->setShowActual(TRUE);
}
- else if (token == "showprojectids")
+ else if (token == KW("showprojectids"))
{
report->setShowPIDs(TRUE);
}
- else if (token == "hidetask")
+ else if (token == KW("hidetask"))
{
Operation* op;
if ((op = readLogicalExpression()) == 0)
ExpressionTree* et = new ExpressionTree(op);
report->setHideTask(et);
}
- else if (token == "rolluptask")
+ else if (token == KW("rolluptask"))
{
Operation* op;
if ((op = readLogicalExpression()) == 0)
ExpressionTree* et = new ExpressionTree(op);
report->setRollUpTask(et);
}
- else if (token == "sorttasks")
+ else if (token == KW("sorttasks"))
{
if (!readSorting(report, 0))
return FALSE;
}
- else if (token == "hideresource")
+ else if (token == KW("hideresource"))
{
Operation* op;
if ((op = readLogicalExpression()) == 0)
ExpressionTree* et = new ExpressionTree(op);
report->setHideResource(et);
}
- else if (token == "rollupresource")
+ else if (token == KW("rollupresource"))
{
Operation* op;
if ((op = readLogicalExpression()) == 0)
ExpressionTree* et = new ExpressionTree(op);
report->setRollUpResource(et);
}
- else if (token == "sortresources")
+ else if (token == KW("sortresources"))
{
if (!readSorting(report, 1))
return FALSE;
}
}
- if (reportType == "htmltaskreport")
+ if (reportType == KW("htmltaskreport"))
proj->addHTMLTaskReport((HTMLTaskReport*) report);
else
proj->addHTMLResourceReport((HTMLResourceReport*) report);
fatalError("Attribute ID or '}' expected");
return FALSE;
}
- if (token == "columns")
+ if (token == KW("columns"))
{
report->clearColumns();
for ( ; ; )
}
}
}
- else if (token == "start")
+ else if (token == KW("start"))
{
if (nextToken(token) != DATE)
{
}
report->setStart(date2time(token));
}
- else if (token == "end")
+ else if (token == KW("end"))
{
if (nextToken(token) != DATE)
{
}
report->setEnd(date2time(token));
}
- else if (token == "headline")
+ else if (token == KW("headline"))
{
if (nextToken(token) != STRING)
{
}
report->setHeadline(token);
}
- else if (token == "caption")
+ else if (token == KW("caption"))
{
if (nextToken(token) != STRING)
{
}
report->setCaption(token);
}
- else if (token == "hideplan")
+ else if (token == KW("hideplan"))
{
report->setHidePlan(TRUE);
}
- else if (token == "showactual")
+ else if (token == KW("showactual"))
{
report->setShowActual(TRUE);
}
- else if (token == "accumulate")
+ else if (token == KW("accumulate"))
{
report->setAccumulate(TRUE);
}
- else if (token == "hideaccount")
+ else if (token == KW("hideaccount"))
{
Operation* op;
if ((op = readLogicalExpression()) == 0)
ExpressionTree* et = new ExpressionTree(op);
report->setHideAccount(et);
}
- else if (token == "rollupaccount")
+ else if (token == KW("rollupaccount"))
{
Operation* op;
if ((op = readLogicalExpression()) == 0)
ExpressionTree* et = new ExpressionTree(op);
report->setRollUpAccount(et);
}
- else if (token == "sortaccounts")
+ else if (token == KW("sortaccounts"))
{
if (!readSorting(report, 2))
return FALSE;
return TRUE;
}
+bool
+ProjectFile::readExportReport()
+{
+ QString token;
+ if (nextToken(token) != STRING)
+ {
+ fatalError("File name expected");
+ return FALSE;
+ }
+
+ ExportReport* report;
+ report = new ExportReport(proj, token);
+
+ TokenType tt;
+ if ((tt = nextToken(token)) != LCBRACE)
+ {
+ openFiles.last()->returnToken(tt, token);
+ return TRUE;
+ }
+
+ for ( ; ; )
+ {
+ if ((tt = nextToken(token)) == RCBRACE)
+ break;
+ else if (tt != ID)
+ {
+ fatalError("Attribute ID or '}' expected");
+ return FALSE;
+ }
+
+ if (token == KW("hidetask"))
+ {
+ Operation* op;
+ if ((op = readLogicalExpression()) == 0)
+ return FALSE;
+ ExpressionTree* et = new ExpressionTree(op);
+ report->setHideTask(et);
+ }
+ else if (token == KW("rolluptask"))
+ {
+ Operation* op;
+ if ((op = readLogicalExpression()) == 0)
+ return FALSE;
+ ExpressionTree* et = new ExpressionTree(op);
+ report->setRollUpTask(et);
+ }
+ else
+ {
+ fatalError("Illegal attribute");
+ return FALSE;
+ }
+ }
+
+ proj->addExportReport(report);
+
+ return TRUE;
+}
+
Operation*
ProjectFile::readLogicalExpression(int precedence)
{
QString token;
TokenType tt;
- qDebug("readLogicalExpression");
- if ((tt = nextToken(token)) == ID || tt == INTEGER)
+ if ((tt = nextToken(token)) == ID || tt == RELATIVE_ID)
{
- if (tt == ID)
+ if (proj->isAllowedFlag(token))
+ op = new Operation(token);
+ else if (proj->getTask(token))
+ op = new Operation(Operation::TaskId, token);
+ else if (proj->getResource(token))
+ op = new Operation(Operation::ResourceId, token);
+ else if (proj->getAccount(token))
+ op = new Operation(Operation::AccountId, token);
+ else if (ExpressionTree::isFunction(token))
{
- if (!proj->isAllowedFlag(token))
- {
- fatalError(QString("Flag ") + token + " is unknown.");
- qDebug("Done 0");
+ if ((op = readFunctionCall(token)) == 0)
return 0;
- }
- op = new Operation(token);
- qDebug(token);
}
else
- op = new Operation(token.toLong());
- if (precedence == 0)
{
- if ((tt = nextToken(token)) != AND && tt != OR)
- {
- returnToken(tt, token);
- }
- else if (tt == AND)
- {
- qDebug("&");
- Operation* op2 = readLogicalExpression();
- op = new Operation(op, Operation::And, op2);
- }
- else if (tt == OR)
- {
- qDebug("|");
- Operation* op2 = readLogicalExpression();
- op = new Operation(op, Operation::Or, op2);
- }
+ fatalError(QString("Flag or function '") + token + "' is unknown.");
+ return 0;
}
}
+ else if (tt == INTEGER)
+ {
+ op = new Operation(token.toLong());
+ }
else if (tt == TILDE)
{
- qDebug("~");
if ((op = readLogicalExpression(1)) == 0)
{
- qDebug("Done 0");
return 0;
}
op = new Operation(op, Operation::Not);
}
else if (tt == LBRACE)
{
- qDebug("(");
if ((op = readLogicalExpression()) == 0)
{
- qDebug("Done 0");
return 0;
}
if ((tt = nextToken(token)) != RBRACE)
{
fatalError("')' expected");
- qDebug("Done 0");
return 0;
}
- qDebug(")");
}
else
{
fatalError("Logical expression expected");
- qDebug("Done 0");
return 0;
}
- qDebug("Done op");
+ if (precedence < 1)
+ {
+ if ((tt = nextToken(token)) != AND && tt != OR)
+ {
+ returnToken(tt, token);
+ }
+ else if (tt == AND)
+ {
+ Operation* op2 = readLogicalExpression();
+ op = new Operation(op, Operation::And, op2);
+ }
+ else if (tt == OR)
+ {
+ Operation* op2 = readLogicalExpression();
+ op = new Operation(op, Operation::Or, op2);
+ }
+ }
+
return op;
}
+Operation*
+ProjectFile::readFunctionCall(const QString& name)
+{
+ QString token;
+ TokenType tt;
+
+ if ((tt = nextToken(token)) != LBRACE)
+ {
+ fatalError("'(' expected");
+ return 0;
+ }
+ QPtrList<Operation> args;
+ for (int i = 0; i < ExpressionTree::arguments(name); i++)
+ {
+ Operation* op;
+ if ((op = readLogicalExpression()) == 0)
+ return 0;
+ args.append(op);
+ if ((i < ExpressionTree::arguments(name) - 1) &&
+ nextToken(token) != COMMA)
+ {
+ fatalError("Comma expected");
+ return 0;
+ }
+ }
+ if ((tt = nextToken(token)) != RBRACE)
+ {
+ fatalError("')' expected");
+ return 0;
+ }
+ return new Operation(name, args);
+}
+
bool
ProjectFile::readSorting(Report* report, int which)
{
nextToken(token);
CoreAttributesList::SortCriteria sorting;
- if (token == "tree")
+ if (token == KW("tree"))
sorting = CoreAttributesList::TreeMode;
- else if (token == "indexup")
+ else if (token == KW("indexup"))
sorting = CoreAttributesList::IndexUp;
- else if (token == "indexdown")
+ else if (token == KW("indexdown"))
sorting = CoreAttributesList::IndexDown;
- else if (token == "idup")
+ else if (token == KW("idup"))
sorting = CoreAttributesList::IdUp;
- else if (token == "iddown")
+ else if (token == KW("iddown"))
sorting = CoreAttributesList::IdDown;
- else if (token == "fullnameup")
+ else if (token == KW("fullnameup"))
sorting = CoreAttributesList::FullNameUp;
- else if (token == "fullnamedown")
+ else if (token == KW("fullnamedown"))
sorting = CoreAttributesList::FullNameDown;
- else if (token == "nameup")
+ else if (token == KW("nameup"))
sorting = CoreAttributesList::NameUp;
- else if (token == "namedown")
+ else if (token == KW("namedown"))
sorting = CoreAttributesList::NameDown;
- else if (token == "startup")
+ else if (token == KW("startup"))
sorting = CoreAttributesList::StartUp;
- else if (token == "startdown")
+ else if (token == KW("startdown"))
sorting = CoreAttributesList::StartDown;
- else if (token == "endup")
+ else if (token == KW("endup"))
sorting = CoreAttributesList::EndUp;
- else if (token == "enddown")
+ else if (token == KW("enddown"))
sorting = CoreAttributesList::EndDown;
- else if (token == "priorityup")
+ else if (token == KW("priorityup"))
sorting = CoreAttributesList::PrioUp;
- else if (token == "prioritydown")
+ else if (token == KW("prioritydown"))
sorting = CoreAttributesList::PrioDown;
- else if (token == "responsibleup")
+ else if (token == KW("responsibleup"))
sorting = CoreAttributesList::ResponsibleUp;
- else if (token == "responsibledown")
+ else if (token == KW("responsibledown"))
sorting = CoreAttributesList::ResponsibleDown;
- else if (token == "mineffortup")
+ else if (token == KW("mineffortup"))
sorting = CoreAttributesList::MinEffortUp;
- else if (token == "mineffortdown")
+ else if (token == KW("mineffortdown"))
sorting = CoreAttributesList::MinEffortDown;
- else if (token == "maxeffortup")
+ else if (token == KW("maxeffortup"))
sorting = CoreAttributesList::MaxEffortUp;
- else if (token == "maxeffortdown")
+ else if (token == KW("maxeffortdown"))
sorting = CoreAttributesList::MaxEffortDown;
- else if (token == "rateup")
+ else if (token == KW("rateup"))
sorting = CoreAttributesList::RateUp;
- else if (token == "ratedown")
+ else if (token == KW("ratedown"))
sorting = CoreAttributesList::RateDown;
- else if (token == "kotrusidup")
+ else if (token == KW("kotrusidup"))
sorting = CoreAttributesList::KotrusIdUp;
- else if (token == "kotrusiddown")
+ else if (token == KW("kotrusiddown"))
sorting = CoreAttributesList::KotrusIdDown;
else
{
ProjectFile::date2time(const QString& date)
{
int y, m, d, hour, min;
- if (date.find(':') == -1)
- {
- sscanf(date, "%d-%d-%d", &y, &m, &d);
+ char tZone[16] = "";
+ if (sscanf(date, "%d-%d-%d-%d:%d-%s", &y, &m, &d, &hour, &min, tZone) == 6)
+ ;
+ else if (sscanf(date, "%d-%d-%d-%d:%d", &y, &m, &d, &hour, &min) == 5)
+ tZone[0] = '\0';
+ else if (sscanf(date, "%d-%d-%d", &y, &m, &d) == 3)
+ {
+ tZone[0] = '\0';
hour = min = 0;
}
- else
- sscanf(date, "%d-%d-%d-%d:%d", &y, &m, &d, &hour, &min);
+ char savedTZ[16] = "";
+ if (strcmp(tZone, "") != 0)
+ {
+ if (getenv("TZ"))
+ strcpy(getenv("TZ"), savedTZ);
+ setenv("TZ", tZone, 1);
+ }
+
if (y < 1970)
{
fatalError("Year must be larger than 1969");
struct tm t = { 0, min, hour, d, m - 1, y - 1900, 0, 0, -1, 0, 0 };
time_t localTime = mktime(&t);
+ if (strcmp(savedTZ, "") != 0)
+ setenv("TZ", savedTZ, 1);
+ else
+ unsetenv("TZ");
+
return localTime;
}