/*
- * Report.cpp - TaskJuggler
+ * HTMLReportElement.cpp - TaskJuggler
*
- * Copyright (c) 2001, 2002, 2003 by Chris Schlaeger <cs@suse.de>
+ * Copyright (c) 2001, 2002, 2003, 2004, 2005 by Chris Schlaeger <cs@kde.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of version 2 of the GNU General Public License as
* $Id$
*/
-#include <config.h>
+#include "HTMLReportElement.h"
+
+#include <assert.h>
#include "TjMessageHandler.h"
#include "tjlib-internal.h"
#include "Project.h"
#include "Resource.h"
-#include "Report.h"
-#include "Booking.h"
+#include "Account.h"
#include "BookingList.h"
#include "Utility.h"
#include "MacroTable.h"
+#include "TableLineInfo.h"
+#include "TableCellInfo.h"
+#include "ReferenceAttribute.h"
+#include "TextAttribute.h"
+#include "HTMLReport.h"
+#include "UsageLimits.h"
+
+HTMLReportElement::HTMLReportElement(Report* r, const QString& df, int dl) :
+ ReportElement(r, df, dl),
+ HTMLPrimitives()
+{
+}
-#define KW(a) a
-
-/* The following encoding table was copied from the Qt library sources since
- * this information is not available over the public API. */
-
-struct Entity
-{
- const char * name;
- Q_UINT16 code;
-};
-
-static const Entity entitylist [] =
-{
- { "AElig", 0x00c6 },
- { "Aacute", 0x00c1 },
- { "Acirc", 0x00c2 },
- { "Agrave", 0x00c0 },
- { "Alpha", 0x0391 },
- { "AMP", 38 },
- { "Aring", 0x00c5 },
- { "Atilde", 0x00c3 },
- { "Auml", 0x00c4 },
- { "Beta", 0x0392 },
- { "Ccedil", 0x00c7 },
- { "Chi", 0x03a7 },
- { "Dagger", 0x2021 },
- { "Delta", 0x0394 },
- { "ETH", 0x00d0 },
- { "Eacute", 0x00c9 },
- { "Ecirc", 0x00ca },
- { "Egrave", 0x00c8 },
- { "Epsilon", 0x0395 },
- { "Eta", 0x0397 },
- { "Euml", 0x00cb },
- { "Gamma", 0x0393 },
- { "GT", 62 },
- { "Iacute", 0x00cd },
- { "Icirc", 0x00ce },
- { "Igrave", 0x00cc },
- { "Iota", 0x0399 },
- { "Iuml", 0x00cf },
- { "Kappa", 0x039a },
- { "Lambda", 0x039b },
- { "LT", 60 },
- { "Mu", 0x039c },
- { "Ntilde", 0x00d1 },
- { "Nu", 0x039d },
- { "OElig", 0x0152 },
- { "Oacute", 0x00d3 },
- { "Ocirc", 0x00d4 },
- { "Ograve", 0x00d2 },
- { "Omega", 0x03a9 },
- { "Omicron", 0x039f },
- { "Oslash", 0x00d8 },
- { "Otilde", 0x00d5 },
- { "Ouml", 0x00d6 },
- { "Phi", 0x03a6 },
- { "Pi", 0x03a0 },
- { "Prime", 0x2033 },
- { "Psi", 0x03a8 },
- { "QUOT", 34 },
- { "Rho", 0x03a1 },
- { "Scaron", 0x0160 },
- { "Sigma", 0x03a3 },
- { "THORN", 0x00de },
- { "Tau", 0x03a4 },
- { "Theta", 0x0398 },
- { "Uacute", 0x00da },
- { "Ucirc", 0x00db },
- { "Ugrave", 0x00d9 },
- { "Upsilon", 0x03a5 },
- { "Uuml", 0x00dc },
- { "Xi", 0x039e },
- { "Yacute", 0x00dd },
- { "Yuml", 0x0178 },
- { "Zeta", 0x0396 },
- { "aacute", 0x00e1 },
- { "acirc", 0x00e2 },
- { "acute", 0x00b4 },
- { "aelig", 0x00e6 },
- { "agrave", 0x00e0 },
- { "alefsym", 0x2135 },
- { "alpha", 0x03b1 },
- { "amp", 38 },
- { "and", 0x22a5 },
- { "ang", 0x2220 },
- { "apos", 0x0027 },
- { "aring", 0x00e5 },
- { "asymp", 0x2248 },
- { "atilde", 0x00e3 },
- { "auml", 0x00e4 },
- { "bdquo", 0x201e },
- { "beta", 0x03b2 },
- { "brvbar", 0x00a6 },
- { "bull", 0x2022 },
- { "cap", 0x2229 },
- { "ccedil", 0x00e7 },
- { "cedil", 0x00b8 },
- { "cent", 0x00a2 },
- { "chi", 0x03c7 },
- { "circ", 0x02c6 },
- { "clubs", 0x2663 },
- { "cong", 0x2245 },
- { "copy", 0x00a9 },
- { "crarr", 0x21b5 },
- { "cup", 0x222a },
- { "curren", 0x00a4 },
- { "dArr", 0x21d3 },
- { "dagger", 0x2020 },
- { "darr", 0x2193 },
- { "deg", 0x00b0 },
- { "delta", 0x03b4 },
- { "diams", 0x2666 },
- { "divide", 0x00f7 },
- { "eacute", 0x00e9 },
- { "ecirc", 0x00ea },
- { "egrave", 0x00e8 },
- { "empty", 0x2205 },
- { "emsp", 0x2003 },
- { "ensp", 0x2002 },
- { "epsilon", 0x03b5 },
- { "equiv", 0x2261 },
- { "eta", 0x03b7 },
- { "eth", 0x00f0 },
- { "euml", 0x00eb },
- { "euro", 0x20ac },
- { "exist", 0x2203 },
- { "fnof", 0x0192 },
- { "forall", 0x2200 },
- { "frac12", 0x00bd },
- { "frac14", 0x00bc },
- { "frac34", 0x00be },
- { "frasl", 0x2044 },
- { "gamma", 0x03b3 },
- { "ge", 0x2265 },
- { "gt", 62 },
- { "hArr", 0x21d4 },
- { "harr", 0x2194 },
- { "hearts", 0x2665 },
- { "hellip", 0x2026 },
- { "iacute", 0x00ed },
- { "icirc", 0x00ee },
- { "iexcl", 0x00a1 },
- { "igrave", 0x00ec },
- { "image", 0x2111 },
- { "infin", 0x221e },
- { "int", 0x222b },
- { "iota", 0x03b9 },
- { "iquest", 0x00bf },
- { "isin", 0x2208 },
- { "iuml", 0x00ef },
- { "kappa", 0x03ba },
- { "lArr", 0x21d0 },
- { "lambda", 0x03bb },
- { "lang", 0x2329 },
- { "laquo", 0x00ab },
- { "larr", 0x2190 },
- { "lceil", 0x2308 },
- { "ldquo", 0x201c },
- { "le", 0x2264 },
- { "lfloor", 0x230a },
- { "lowast", 0x2217 },
- { "loz", 0x25ca },
- { "lrm", 0x200e },
- { "lsaquo", 0x2039 },
- { "lsquo", 0x2018 },
- { "lt", 60 },
- { "macr", 0x00af },
- { "mdash", 0x2014 },
- { "micro", 0x00b5 },
- { "middot", 0x00b7 },
- { "minus", 0x2212 },
- { "mu", 0x03bc },
- { "nabla", 0x2207 },
- { "nbsp", 0x00a0 },
- { "ndash", 0x2013 },
- { "ne", 0x2260 },
- { "ni", 0x220b },
- { "not", 0x00ac },
- { "notin", 0x2209 },
- { "nsub", 0x2284 },
- { "ntilde", 0x00f1 },
- { "nu", 0x03bd },
- { "oacute", 0x00f3 },
- { "ocirc", 0x00f4 },
- { "oelig", 0x0153 },
- { "ograve", 0x00f2 },
- { "oline", 0x203e },
- { "omega", 0x03c9 },
- { "omicron", 0x03bf },
- { "oplus", 0x2295 },
- { "or", 0x22a6 },
- { "ordf", 0x00aa },
- { "ordm", 0x00ba },
- { "oslash", 0x00f8 },
- { "otilde", 0x00f5 },
- { "otimes", 0x2297 },
- { "ouml", 0x00f6 },
- { "para", 0x00b6 },
- { "part", 0x2202 },
- { "percnt", 0x0025 },
- { "permil", 0x2030 },
- { "perp", 0x22a5 },
- { "phi", 0x03c6 },
- { "pi", 0x03c0 },
- { "piv", 0x03d6 },
- { "plusmn", 0x00b1 },
- { "pound", 0x00a3 },
- { "prime", 0x2032 },
- { "prod", 0x220f },
- { "prop", 0x221d },
- { "psi", 0x03c8 },
- { "quot", 34 },
- { "rArr", 0x21d2 },
- { "radic", 0x221a },
- { "rang", 0x232a },
- { "raquo", 0x00bb },
- { "rarr", 0x2192 },
- { "rceil", 0x2309 },
- { "rdquo", 0x201d },
- { "real", 0x211c },
- { "reg", 0x00ae },
- { "rfloor", 0x230b },
- { "rho", 0x03c1 },
- { "rlm", 0x200f },
- { "rsaquo", 0x203a },
- { "rsquo", 0x2019 },
- { "sbquo", 0x201a },
- { "scaron", 0x0161 },
- { "sdot", 0x22c5 },
- { "sect", 0x00a7 },
- { "shy", 0x00ad },
- { "sigma", 0x03c3 },
- { "sigmaf", 0x03c2 },
- { "sim", 0x223c },
- { "spades", 0x2660 },
- { "sub", 0x2282 },
- { "sube", 0x2286 },
- { "sum", 0x2211 },
- { "sup1", 0x00b9 },
- { "sup2", 0x00b2 },
- { "sup3", 0x00b3 },
- { "sup", 0x2283 },
- { "supe", 0x2287 },
- { "szlig", 0x00df },
- { "tau", 0x03c4 },
- { "there4", 0x2234 },
- { "theta", 0x03b8 },
- { "thetasym", 0x03d1 },
- { "thinsp", 0x2009 },
- { "thorn", 0x00fe },
- { "tilde", 0x02dc },
- { "times", 0x00d7 },
- { "trade", 0x2122 },
- { "uArr", 0x21d1 },
- { "uacute", 0x00fa },
- { "uarr", 0x2191 },
- { "ucirc", 0x00fb },
- { "ugrave", 0x00f9 },
- { "uml", 0x00a8 },
- { "upsih", 0x03d2 },
- { "upsilon", 0x03c5 },
- { "uuml", 0x00fc },
- { "weierp", 0x2118 },
- { "xi", 0x03be },
- { "yacute", 0x00fd },
- { "yen", 0x00a5 },
- { "yuml", 0x00ff },
- { "zeta", 0x03b6 },
- { "zwj", 0x200d },
- { "zwnj", 0x200c },
- { "", 0x0000 }
-};
-
-static QMap<Q_UINT16, QCString> *HtmlMap = 0;
-
-HTMLReportElement::HTMLReportElement(Project* p, const QString& f, time_t s, time_t e,
- const QString& df, int dl) :
- Report(p, f, s, e, df, dl)
-{
- colDefault = 0xf3ebae;
- colDefaultLight = 0xfffadd;
- colWeekend = 0xffec80;
- colVacation = 0xfffc60;
- colAvailable = 0xa4ff8d;
- colBooked = 0xff5a5d;
- colBookedLight = 0xffbfbf;
- colHeader = 0xa5c2ff;
- colMilestone = 0xff2a2a;
- colCompleted = 0x87ff75;
- colCompletedLight = 0xa1ff9a;
- colToday = 0xa387ff;
-
- barLabels = BLT_LOAD;
-
- registerUrl(KW("dayheader"));
- registerUrl(KW("monthheader"));
- registerUrl(KW("resourcename"));
- registerUrl(KW("taskname"));
- registerUrl(KW("weekheader"));
- registerUrl(KW("yearheader"));
-}
-
-void
-HTMLReportElement::generateTask1stRow(const Task* t, const Resource* r, uint no)
-{
- s << "<tr valign=\"middle\">";
- for (QStringList::Iterator it = columns.begin(); it != columns.end();
- ++it )
- {
- if (*it == KW("seqno"))
- textMultiRows((r == 0 ? QString().sprintf("%d.",
- t->getSequenceNo()) :
- QString("")), r != 0, "");
- else if (*it == KW("no"))
- textMultiRows((r == 0 ? QString().sprintf("%d.", no) :
- QString("")), r != 0, "");
- else if (*it == KW("index"))
- textMultiRows((r == 0 ? QString().sprintf("%d.", t->getIndex()) :
- QString("")), r != 0, "");
- else if (*it == KW("id"))
- textMultiRows(htmlFilter(t->getId()), r != 0, "left");
- else if (*it == KW("name"))
- taskName(t, r, r == 0);
- else if (*it == KW("start"))
- s << "<td class=\""
- << (t->isStartOk(scenarios[0]) ?
- (r == 0 ? "default" : "defaultlight") : "milestone")
- << "\" style=\"text-align:left white-space:nowrap\">"
- << time2user(t->getStart(Task::Plan), timeFormat)
- << "</td>" << endl;
- else if (*it == KW("end"))
- s << "<td class=\""
- << (t->isEndOk(Task::Plan) ?
- (r == 0 ? "default" : "defaultlight") : "milestone")
- << "\" style=\"text-align:left white-space:nowrap\">"
- << time2user(t->getEnd(Task::Plan) + 1, timeFormat)
- << "</td>" << endl;
- else if (*it == KW("minstart"))
- textMultiRows(time2user(t->getMinStart(), timeFormat), r != 0, "");
- else if (*it == KW("maxstart"))
- textMultiRows(time2user(t->getMaxStart(), timeFormat),
- r != 0, "");
- else if (*it == KW("minend"))
- textMultiRows(time2user(t->getMinEnd(), timeFormat), r != 0, "");
- else if (*it == KW("maxend"))
- textMultiRows(time2user(t->getMaxEnd(), timeFormat), r != 0, "");
- else if (*it == KW("startbuffer"))
- textMultiRows(QString().sprintf
- ("%3.0f", t->getStartBuffer(Task::Plan)), r != 0,
- "right");
- else if (*it == KW("endbuffer"))
- textMultiRows(QString().sprintf
- ("%3.0f", t->getEndBuffer(Task::Plan)), r != 0,
- "right");
- else if (*it == KW("startbufferend"))
- textOneRow(time2user(t->getStartBufferEnd(Task::Plan) + 1,
- timeFormat), r != 0, "left");
- else if (*it == KW("endbufferstart"))
- textOneRow(time2user(t->getEndBufferStart(Task::Plan), timeFormat),
- r != 0, "left");
- else if (*it == KW("duration"))
- {
- s << "<td class=\""
- << (r == 0 ? "default" : "defaultlight")
- << "\" style=\"text-align:right white-space:nowrap\">"
- << scaledLoad(t->getCalcDuration(Task::Plan))
- << "</td>" << endl;
- }
- else if (*it == KW("effort"))
- {
- s << "<td class=\""
- << (r == 0 ? "default" : "defaultlight")
- << "\" style=\"text-align:right white-space:nowrap\">"
- << scaledLoad(t->getLoad(Task::Plan, Interval(start, end), r))
- << "</td>" << endl;
- }
- else if (*it == KW("projectid"))
- textMultiRows(t->getProjectId() + " (" +
- project->getIdIndex(t->getProjectId()) + ")", r != 0,
- "left");
- else if (*it == KW("resources"))
- scenarioResources(Task::Plan, t, r != 0);
- else if (*it == KW("responsible"))
- if (t->getResponsible())
- textMultiRows(htmlFilter(t->getResponsible()->getName()), r != 0,
- "left");
- else
- textMultiRows(" ", r != 0, "left");
- else if (*it == KW("responsibilities"))
- emptyPlan(r != 0);
- else if (*it == KW("depends"))
- generateDepends(t, r != 0);
- else if (*it == KW("follows"))
- generateFollows(t, r != 0);
- else if (*it == KW("schedule"))
- emptyPlan(r != 0);
- else if (*it == KW("mineffort"))
- emptyPlan(r != 0);
- else if (*it == KW("maxeffort"))
- emptyPlan(r != 0);
- else if (*it == KW("rate"))
- emptyPlan(r != 0);
- else if (*it == KW("kotrusid"))
- emptyPlan(r != 0);
- else if (*it == KW("note"))
- {
- s << "<td class=\""
- << (r == 0 ? "default" : "defaultlight")
- << "\" rowspan=\""
- << (showActual ? "2" : "1")
- << "\" style=\"text-align:left\">"
- << "<span style=\"font-size:100%\">";
- if (t->getNote().isEmpty())
- s << " ";
- else
- s << htmlFilter(t->getNote());
- s << "</span></td>" << endl;
- }
- else if (*it == KW("statusnote"))
- {
- s << "<td class=\""
- << (r == 0 ? "default" : "defaultlight")
- << "\" style=\"text-align:left\">"
- << "<span style=\"font-size:100%\">";
- if (t->getStatusNote(Task::Plan).isEmpty())
- s << " ";
- else
- s << htmlFilter(t->getStatusNote(Task::Plan));
- s << "</span></td>" << endl;
- }
- else if (*it == KW("costs"))
- textOneRow(
- QString().sprintf("%.*f", project->getCurrencyDigits(),
- t->getCredits(Task::Plan,
- Interval(start, end), r)),
- r != 0,
- "right");
- else if (*it == KW("priority"))
- textMultiRows(QString().sprintf("%d", t->getPriority()), r != 0,
- "right");
- else if (*it == KW("flags"))
- flagList(t, r);
- else if (*it == KW("completed"))
- if (t->getCompletionDegree(Task::Plan) ==
- t->getCalcedCompletionDegree(Task::Plan))
- {
- textOneRow(QString("%1%")
- .arg((int) t->getCompletionDegree(Task::Plan)),
- r != 0, "right");
- }
- else
- {
- textOneRow(QString("%1% (%2%)")
- .arg((int) t->getCompletionDegree(Task::Plan))
- .arg((int) t->getCalcedCompletionDegree(Task::Plan)),
- r != 0, "right");
- }
- else if (*it == KW("status"))
- generateTaskStatus(t->getStatus(Task::Plan), r != 0);
- else if (*it == KW("daily"))
- dailyTaskPlan(t, r);
- else if (*it == KW("weekly"))
- weeklyTaskPlan(t, r);
- else if (*it == KW("monthly"))
- monthlyTaskPlan(t, r);
- else
- qFatal("generatePlanTask: Unknown Column %s",
- (*it).latin1());
- }
- s << "</tr>" << endl;
+void
+HTMLReportElement::generateHeader()
+{
+ if (!rawHead.isEmpty())
+ {
+ puts(rawHead);
+ puts("\n");
+ }
+ if (!headline.isEmpty())
+ {
+ puts("<h3>");
+ puts(htmlFilter(headline));
+ puts("</h3>\n");
+ }
+ if (!caption.isEmpty())
+ {
+ puts("<p>");
+ puts(htmlFilter(caption));
+ puts("</p>\n");
+ }
}
void
-HTMLReportElement::generateActualTask(const Task* t, const Resource* r)
+HTMLReportElement::generateFooter()
{
- s << "<tr>" << endl;
- for (QStringList::Iterator it = columns.begin();
- it != columns.end();
- ++it )
- {
- if (*it == KW("start"))
- {
- s << "<td class=\""
- << (t->isStartOk(Task::Actual) ?
- (r == 0 ? "default" : "defaultlight") : "milestone")
- << "\" style=\"text-align:left white-space:nowrap\">"
- << time2user(t->getStart(Task::Actual), timeFormat)
- << "</td>" << endl;
- }
- else if (*it == KW("end"))
- {
- s << "<td class=\""
- << (t->isEndOk(Task::Actual) ?
- (r == 0 ? "default" : "defaultlight") : "milestone")
- << "\" style=\"white-space:nowrap\">"
- << time2user(t->getEnd(Task::Actual) + 1, timeFormat)
- << "</td>" << endl;
- }
- else if (*it == KW("startbufferend"))
- textOneRow(time2user(t->getStartBufferEnd(Task::Actual) + 1,
- timeFormat), r != 0, "left");
- else if (*it == KW("endbufferstart"))
- textOneRow(time2user(t->getEndBufferStart(Task::Actual),
- timeFormat), r != 0, "left");
- else if (*it == KW("duration"))
- {
- s << "<td class=\""
- << (r == 0 ? "default" : "defaultlight")
- << "\" style=\"text-align:right white-space:nowrap\">"
- << scaledLoad(t->getCalcDuration(Task::Actual))
- << "</td>" << endl;
- }
- else if (*it == KW("effort"))
- {
- s << "<td class=\""
- << (r == 0 ? "default" : "defaultlight")
- << "\" style=\"text-align:right white-space:nowrap\">"
- << scaledLoad(t->getLoad(Task::Actual, Interval(start, end), r))
- << "</td>" << endl;
- }
- else if (*it == KW("resources"))
- scenarioResources(Task::Actual, t, r != 0);
- else if (*it == "costs")
- textOneRow(
- QString().sprintf("%.*f", project->getCurrencyDigits(),
- t->getCredits(Task::Actual,
- Interval(start, end), r)),
- r != 0, "right");
- else if (*it == KW("completed"))
- if (t->getCompletionDegree(Task::Actual) ==
- t->getCalcedCompletionDegree(Task::Actual))
- {
- textOneRow(QString("%1%")
- .arg((int) t->getCompletionDegree(Task::Actual)),
- r != 0, "right");
- }
- else
- {
- textOneRow(QString("%1% (%2%)")
- .arg((int) t->getCompletionDegree(Task::Actual))
- .arg((int)
- t->getCalcedCompletionDegree(Task::Actual)),
- r != 0, "right");
- }
- else if (*it == KW("status"))
- generateTaskStatus(t->getStatus(Task::Actual), r != 0);
- else if (*it == KW("statusnote"))
- {
- s << "<td class=\""
- << (r == 0 ? "default" : "defaultlight")
- << "\" style=\"text-align:left\">"
- << "<span style=\"font-size:100%\">";
- if (t->getStatusNote(Task::Actual).isEmpty())
- s << " ";
- else
- s << htmlFilter(t->getStatusNote(Task::Actual));
- s << "</span></td>" << endl;
- }
- else if (*it == KW("daily"))
- dailyTaskActual(t, r);
- else if (*it == KW("weekly"))
- weeklyTaskActual(t, r);
- else if (*it == KW("monthly"))
- monthlyTaskActual(t, r);
- }
- s << "</tr>" << endl;
+ if (!rawTail.isEmpty())
+ {
+ puts(rawTail);
+ puts("\n");
+ }
}
void
-HTMLReportElement::generatePlanResource(const Resource* r, const Task* t, uint no)
+HTMLReportElement::generateTableHeader()
{
- s << "<tr valign=\"middle\">";
- for (QStringList::Iterator it = columns.begin(); it != columns.end();
- ++it )
- {
- if (*it == KW("seqno"))
- textMultiRows((t == 0 ? QString().sprintf("%d.", r->getSequenceNo()) :
- QString("")), t != 0, "");
- else if (*it == KW("no"))
- textMultiRows((t == 0 ? QString().sprintf("%d.", no) :
- QString("")), t != 0, "");
- else if (*it == KW("index"))
- textMultiRows((t == 0 ? QString().sprintf("%d.", r->getIndex()) :
- QString("")), t != 0, "");
- else if (*it == KW("id"))
- textMultiRows(htmlFilter(r->getId()), t != 0, "left");
- else if (*it == KW("name"))
- resourceName(r, t, FALSE);
- else if (*it == KW("start"))
- emptyPlan(t != 0);
- else if (*it == KW("end"))
- emptyPlan(t != 0);
- else if (*it == KW("minstart"))
- emptyPlan(t != 0);
- else if (*it == KW("maxstart"))
- emptyPlan(t != 0);
- else if (*it == KW("minend"))
- emptyPlan(t != 0);
- else if (*it == KW("maxend"))
- emptyPlan(t != 0);
- else if (*it == KW("startbuffer"))
- emptyPlan(t != 0);
- else if (*it == KW("endbuffer"))
- emptyPlan(t != 0);
- else if (*it == KW("startbufferend"))
- emptyPlan(t != 0);
- else if (*it == KW("endbufferstart"))
- emptyPlan(t != 0);
- else if (*it == KW("duration"))
- emptyPlan(t != 0);
- else if (*it == KW("effort"))
- {
- s << "<td class=\""
- << (t == 0 ? "default" : "defaultlight")
- << "\" style=\"text-align:right white-space:nowrap\">"
- << scaledLoad(r->getLoad(Task::Plan, Interval(start, end), t))
- << "</td>" << endl;
- }
- else if (*it == KW("projectid"))
- emptyPlan(t != 0);
- else if (*it == KW("resources"))
- emptyPlan(t != 0);
- else if (*it == KW("responsible"))
- emptyPlan(t != 0);
- else if (*it == KW("responsibilities"))
- generateResponsibilities(r, t != 0);
- else if (*it == KW("depends"))
- emptyPlan(t != 0);
- else if (*it == KW("follows"))
- emptyPlan(t != 0);
- else if (*it == KW("schedule"))
- generateSchedule(Task::Plan, r, t);
- else if (*it == KW("mineffort"))
- textMultiRows(QString().sprintf("%.2f", r->getMinEffort()), t != 0,
- "right");
- else if (*it == KW("maxeffort"))
- textMultiRows(QString().sprintf("%.2f", r->getMaxEffort()), t != 0,
- "right");
- else if (*it == KW("rate"))
- textMultiRows(QString().sprintf("%.*f", project->getCurrencyDigits(),
- r->getRate()), t != 0,
- "right");
- else if (*it == KW("kotrusid"))
- textMultiRows(r->getKotrusId(), t != 0, "left");
- else if (*it == KW("note"))
- emptyPlan(t != 0);
- else if (*it == KW("costs"))
- textOneRow(
- QString().sprintf("%.*f", project->getCurrencyDigits(),
- r->getCredits(Task::Plan,
- Interval(start, end), t)),
- t != 0, "right");
- else if (*it == KW("priority"))
- emptyPlan(t != 0);
- else if (*it == KW("flags"))
- flagList(r, t);
- else if (*it == KW("completed"))
- emptyPlan(t != 0);
- else if (*it == KW("status"))
- emptyPlan(t != 0);
- else if (*it == KW("daily"))
- dailyResourcePlan(r, t);
- else if (*it == KW("weekly"))
- weeklyResourcePlan(r, t);
- else if (*it == KW("monthly"))
- monthlyResourcePlan(r, t);
- else
- qFatal("generatePlanResource: Unknown Column %s",
- (*it).latin1());
- }
- s << "</tr>" << endl;
+ // Header line 1
+ s() << "<table align=\"center\" cellpadding=\"2\" "
+ << "style=\"background-color:#000000\"";
+ if (static_cast<HTMLReport*>(report)->hasStyleSheet())
+ s() << " class=\"tj_table\"";
+ s() << ">" << endl;
+ s() << " <thead>" << endl
+ << " <tr valign=\"middle\""
+ << " style=\"background-color:" << colors.getColorName("header") << "; "
+ << "font-size:110%; font-weight:bold; text-align:center\"";
+ if (static_cast<HTMLReport*>(report)->hasStyleSheet())
+ s() << " class=\"tj_header_row\"";
+ s() << ">" << endl;
+ for (QPtrListIterator<TableColumnInfo> it(columns); it; ++it )
+ {
+ if (columnFormat[(*it)->getName()])
+ {
+ TableCellInfo tci(columnFormat[(*it)->getName()], 0, *it);
+ (*this.*(columnFormat[(*it)->getName()]->genHeadLine1))
+ (&tci);
+ }
+ else if ((*it)->getName() == "costs")
+ {
+ TJMH.errorMessage
+ (i18n("'costs' has been deprecated. Use 'cost' instead."));
+ return;
+ }
+ else
+ {
+ TJMH.errorMessage
+ (i18n("Unknown Column '%1' for HTML Report")
+ .arg((*it)->getName()));
+ return;
+ }
+ }
+ s() << " </tr>" << endl;
+
+ // Header line 2
+ bool first = true;
+ for (QPtrListIterator<TableColumnInfo> it(columns); it; ++it )
+ {
+ if (columnFormat[(*it)->getName()])
+ if (columnFormat[(*it)->getName()]->genHeadLine2)
+ {
+ if (first)
+ {
+ s() << " <tr";
+ if (static_cast<HTMLReport*>(report)->hasStyleSheet())
+ s() << " class=\"tj_header_row\"";
+ s() << ">" << endl;
+ first = false;
+ }
+
+ TableCellInfo tci(columnFormat[(*it)->getName()], 0, *it);
+ (*this.*(columnFormat[(*it)->getName()]->genHeadLine2))
+ (&tci);
+ }
+ }
+ if (!first)
+ s() << " </tr>" << endl;
+
+ s() << " </thead>\n" << endl;
}
void
-HTMLReportElement::generateActualResource(const Resource* r, const Task* t)
+HTMLReportElement::generateLine(TableLineInfo* tli, int funcSel)
{
- s << "<tr valign=\"middle\">";
- for (QStringList::Iterator it = columns.begin(); it != columns.end();
- ++it )
- {
- if (*it == KW("effort"))
- {
- s << "<td class=\""
- << (t == 0 ? "default" : "defaultlight")
- << "\" style=\"text-align:right white-space:nowrap\">"
- << scaledLoad(r->getLoad(Task::Actual, Interval(start, end), t))
- << "</td>" << endl;
- }
- else if (*it == KW("schedule"))
- generateSchedule(Task::Actual, r, t);
- else if (*it == KW("costs"))
- textOneRow(
- QString().sprintf("%.*f", project->getCurrencyDigits(),
- r->getCredits(Task::Actual,
- Interval(start, end), t)),
- t != 0,
- "right");
- else if (*it == KW("daily"))
- dailyResourceActual(r, t);
- else if (*it == KW("weekly"))
- weeklyResourceActual(r, t);
- else if (*it == KW("monthly"))
- monthlyResourceActual(r, t);
- }
- s << "</tr>" << endl;
+ setMacros(tli);
+
+ puts(" <tr valign=\"middle\"");
+ if (tli->bgCol.isValid() || tli->boldText || tli->fontFactor != 100)
+ {
+ puts(" style=\"");
+ if (tli->bgCol.isValid())
+ {
+ puts("background-color:");
+ puts(tli->bgCol.name());
+ puts("; ");
+ }
+ if (tli->boldText)
+ puts("font-weight:bold; ");
+ if (tli->fontFactor != 100)
+ {
+ puts("font-size:");
+ puts(QString("%1").arg(tli->fontFactor));
+ puts("%; ");
+ }
+ puts("\"");
+ }
+ if (static_cast<HTMLReport*>(report)->hasStyleSheet())
+ puts(" class=\"tj_row\"");
+ puts(">\n");
+
+ for (QPtrListIterator<TableColumnInfo> it(columns); it; ++it )
+ {
+ TableCellInfo tci(columnFormat[(*it)->getName()], tli, *it);
+ if (columnFormat[(*it)->getName()])
+ {
+ GenCellPtr gcf = 0;
+ switch (funcSel)
+ {
+ case 0:
+ gcf = columnFormat[(*it)->getName()]->genHeadLine1;
+ break;
+ case 1:
+ gcf = columnFormat[(*it)->getName()]->genHeadLine2;
+ break;
+ case 2:
+ gcf = columnFormat[(*it)->getName()]->genTaskLine1;
+ break;
+ case 3:
+ gcf = columnFormat[(*it)->getName()]->genTaskLine2;
+ break;
+ case 4:
+ gcf = columnFormat[(*it)->getName()]->genResourceLine1;
+ break;
+ case 5:
+ gcf = columnFormat[(*it)->getName()]->genResourceLine2;
+ break;
+ case 6:
+ gcf = columnFormat[(*it)->getName()]->genAccountLine1;
+ break;
+ case 7:
+ gcf = columnFormat[(*it)->getName()]->genAccountLine2;
+ break;
+ case 8:
+ gcf = columnFormat[(*it)->getName()]->genSummaryLine1;
+ break;
+ case 9:
+ gcf = columnFormat[(*it)->getName()]->genSummaryLine2;
+ break;
+ default:
+ qFatal("Unknown function selector: %d", funcSel);
+ }
+ if (gcf)
+ {
+ (*this.*(gcf))(&tci);
+ }
+ }
+ }
+ puts(" </tr>\n");
}
void
-HTMLReportElement::reportHTMLHeader()
+HTMLReportElement::genCell(const QString& text, TableCellInfo* tci,
+ bool multi, bool filter)
{
- s << "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">"
- << endl
- << "<!-- Generated by TaskJuggler v"VERSION" -->" << endl
- << "<!-- For details about TaskJuggler see "
- << TJURL << " -->" << endl
- << "<html>" << endl
- << "<head>" << endl
- << "<title>Task Report</title>" << endl
- << "<style type=\"text/css\"><!--" << endl;
- if (rawStyleSheet.isEmpty())
+ if (!multi)
+ tci->setFontFactor(90);
+
+ puts(" <td");
+ if (tci->tcf->noWrap)
+ puts(" nowrap=\"nowrap\"");
+ if (tci->getRows() != 1 || (multi && scenarios.count() > 1))
+ puts(" rowspan=\"" + QString("%1")
+ .arg(tci->getRows() != 1 ?
+ tci->getRows() : scenarios.count()) + "\"");
+ if (tci->getColumns() != 1)
+ {
+ puts(" colspan=\"");
+ puts(QString("%1").arg(tci->getColumns()));
+ puts("\"");
+ }
+ if (!tci->getStatusText().isEmpty())
+ {
+ puts(" onmouseover=\"status='");
+ puts(tci->getStatusText());
+ puts("';return true;\"");
+ }
+ if (tci->tcf->hAlign != TableColumnFormat::center ||
+ !tci->getHAlign().isEmpty() ||
+ tci->getLeftPadding() > 0 ||
+ tci->getRightPadding() > 0 ||
+ tci->getBgColor().isValid() ||
+ tci->getFontFactor() != 100 ||
+ tci->getBoldText() ||
+ tci->tcf->fontFactor != 100)
+ {
+ puts(" style=\"");
+ if (tci->getBgColor().isValid())
+ {
+ puts("background-color:");
+ int r, g, b;
+ tci->getBgColor().rgb(&r, &g, &b);
+ char buf[10];
+ sprintf(buf, "#%02x%02x%02x; ", r, g, b);
+ puts(buf);
+ }
+ if (!tci->getHAlign().isEmpty())
+ {
+ puts("text-align:");
+ puts(tci->getHAlign());
+ puts("; ");
+ }
+ else if (tci->tcf->hAlign != TableColumnFormat::center)
+ {
+ puts("text-align:");
+ switch(tci->tcf->hAlign)
+ {
+ case TableColumnFormat::center:
+ puts("center");
+ break;
+ case TableColumnFormat::left:
+ puts("left");
+ break;
+ case TableColumnFormat::right:
+ puts("right");
+ break;
+ }
+ puts("; ");
+ }
+ if (tci->getLeftPadding() > 0)
+ {
+ puts("padding-left:");
+ puts(QString("%1").arg(tci->getLeftPadding()));
+ puts("; ");
+ }
+ if (tci->getRightPadding() > 0)
+ {
+ puts("padding-right:");
+ puts(QString("%1").arg(tci->getRightPadding()));
+ puts("; ");
+ }
+ if (tci->getBoldText())
+ puts("font-weight:bold; ");
+ if (tci->getFontFactor() != 100 || tci->tcf->fontFactor != 100)
+ {
+ puts("font-size:");
+ puts(QString("%1").arg(tci->getFontFactor() *
+ tci->tcf->fontFactor / 100));
+ puts("%; ");
+ }
+ puts("\"");
+ }
+ QString cellText;
+ if (tci->tli->ca1 == 0 ||
+ !isHidden(tci->tli->ca1, tci->tci->getHideCellText()))
+ {
+ cellText = filter ? htmlFilter(text) : text;
+ if (tci->tli->ca1 && !tci->tci->getCellText().isEmpty())
+ {
+ QStringList sl(text);
+ cellText = mt.expandReportVariable(tci->tci->getCellText(), &sl);
+ }
+ }
+ if (!tci->tci->getCellURL().isEmpty() && (tci->tli->ca1 == 0 ||
+ !isHidden(tci->tli->ca1, tci->tci->getHideCellURL())))
+ {
+ QStringList sl(text);
+ QString cellURL = mt.expandReportVariable(tci->tci->getCellURL(), &sl);
+ if (!cellURL.isEmpty())
{
- s.reset();
- s.setf(QTextStream::hex);
- s << ".default { background-color:#" << colDefault
- << "; font-size:70%; text-align:center }" << endl
- << ".defaultlight { background-color:#" << colDefaultLight
- << "; font-size:70%; text-align:center }" << endl
- << ".task { background-color:#" << colDefault
- << "; font-size:100%; text-align:left }" << endl
- << ".tasklight { background-color:#" << colDefaultLight
- << "; font-size:100%; text-align:left }" << endl
- << ".available { background-color:#" << colAvailable
- << "; font-size:70%; text-align:center }" << endl
- << ".vacation { background-color:#" << colVacation
- << "; font-size:70%; text-align:center }" << endl
- << ".weekend { background-color:#" << colWeekend
- << "; font-size:70%; text-align:center }" << endl
- << ".milestone { background-color:#" << colMilestone
- << "; font-size:70%; text-align:center }" << endl
- << ".booked { background-color:#" << colBooked
- << "; font-size:70%; text-align:center }" << endl
- << ".bookedlight { background-color:#" << colBookedLight
- << "; font-size:70%; text-align:center }" << endl
- << ".headersmall { background-color:#" << colHeader
- << "; font-size:70%; text-align:center }" << endl
- << ".headerbig { background-color:#" << colHeader
- << "; font-size:110%; font-weight:bold; text-align:center }" << endl
- << ".completed { background-color:#" << colCompleted
- << "; font-size:70%; text-align:center }" << endl
- << ".completedlight { background-color:#" << colCompletedLight
- << "; font-size:70%; text-align:center }" << endl
- << ".today { background-color:#" << colToday
- << "; font-size:70%; text-align:center }" << endl;
+ cellText = QString("<a href=\"") + cellURL
+ + "\">" + cellText + "</a>";
}
- else
- s << rawStyleSheet << endl;
- s << "--></style>" << endl;
- s << "</head>" << endl
- << "<body>" << endl;
+ }
+ if (cellText.isEmpty())
+ cellText = " ";
+ if (static_cast<HTMLReport*>(report)->hasStyleSheet())
+ puts(" class=\"tj_cell\"");
+ puts(">");
+ if (!tci->getToolTipText().isEmpty())
+ {
+ puts("<div id=\"");
+ puts(tci->getToolTipID());
+ puts("\" class=\"tj_tooltip\" style=\"visibility:hidden\">");
+ puts(tci->getToolTipText());
+ puts("</div>");
+ }
- if (!headline.isEmpty())
- s << "<h1>" << htmlFilter(headline) << "</h1>" << endl;
- if (!caption.isEmpty())
- s << "<p>" << htmlFilter(caption) << "</p>" << endl;
- if (!rawHead.isEmpty())
- s << rawHead << endl;
+ puts(cellText);
+ puts("</td>\n");
}
void
-HTMLReportElement::reportHTMLFooter()
+HTMLReportElement::reportTaskLoad(double load, TableCellInfo* tci,
+ const Interval& period)
{
- if (!rawTail.isEmpty())
- s << rawTail << endl;
+ QString text;
+ if (tci->tli->task->isActive(tci->tli->sc, period))
+ {
+ if (tci->tli->task->isContainer())
+ {
+ QString pre, post;
+ if (period.contains(tci->tli->task->getStart(tci->tli->sc)))
+ pre = "v=";
+ if (period.contains(tci->tli->task->getEnd(tci->tli->sc)))
+ post += "=v";
+ if (load > 0.0 && barLabels != BLT_EMPTY)
+ text = scaledLoad(load, tci->tcf->realFormat);
+ else if (pre.isEmpty() && post.isEmpty())
+ text = "==";
+ else if (!pre.isEmpty() && !post.isEmpty())
+ {
+ pre = post = "v";
+ text = "=";
+ }
+ text = pre + text + post;
+ tci->setBoldText(true);
+ }
+ else
+ {
+ if (tci->tli->task->isMilestone())
+ {
+ text += "<>";
+ tci->setBoldText(true);
+ }
+ else
+ {
+ QString pre, post;
+ if (period.contains(tci->tli->task->
+ getStart(tci->tli->sc)))
+ pre = "[=";
+ if (period.contains(tci->tli->task->
+ getEnd(tci->tli->sc)))
+ post = "=]";
+ if (!pre.isEmpty() && !post.isEmpty())
+ {
+ pre = "[";
+ post = "]";
+ }
+ if (load > 0.0 && barLabels != BLT_EMPTY)
+ text = scaledLoad(load, tci->tcf->realFormat);
+ else if (pre.isEmpty() && post.isEmpty())
+ text = "==";
+ else if (pre == "[")
+ text = "=";
+ text = pre + text + post;
+ }
+ }
+ tci->setHAlign("center");
+ tci->setStatusText(time2user(period.getStart(), "%Y-%m-%d / [") +
+ tci->tli->task->getId() + "] " +
+ htmlFilter(tci->tli->task->getName()));
+ }
+ else
+ {
+ tci->setStatusText("");
+ }
+ genCell(text, tci, false);
+}
- s << "<p><span style=\"font-size:0.7em\">";
- if (!project->getCopyright().isEmpty())
- s << htmlFilter(project->getCopyright()) << " - ";
- s << "Version " << htmlFilter(project->getVersion())
- << " - Created with <a HREF=\"" << TJURL <<
- "\">TaskJuggler v"
- << VERSION << "</a></span></p>" << endl << "</body>\n";
+void
+HTMLReportElement::reportResourceLoad(double load, TableCellInfo* tci,
+ const Interval& period)
+{
+ QString text;
+ if (load > 0.0)
+ {
+ if (barLabels != BLT_EMPTY)
+ text += scaledLoad(load, tci->tcf->realFormat);
+ if (tci->tli->resource->hasSubs())
+ tci->setBoldText(true);
+ tci->setHAlign("center");
+ tci->setStatusText(time2user(period.getStart(), "%Y-%m-%d / [") +
+ tci->tli->resource->getId() + "] " +
+ htmlFilter(tci->tli->resource->getName()));
+ }
+ else
+ {
+ tci->setStatusText("");
+ }
+ genCell(text, tci, false);
}
-bool
-HTMLReportElement::generateTableHeader()
+void
+HTMLReportElement::reportCurrency(double value, TableCellInfo* tci,
+ time_t iv_start)
{
- // Header line 1
- s << "<table align=\"center\" cellpadding=\"1\">\n" << endl;
- s << "<tr>" << endl;
- for (QStringList::Iterator it = columns.begin(); it != columns.end();
- ++it )
- {
- if (*it == KW("seqno"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Seq. No.") << "</td>";
- else if (*it == KW("no"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("No.") << "</td>";
- else if (*it == KW("index"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Index No.") << "</td>";
- else if (*it == KW("id"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("ID") << "</td>";
- else if (*it == KW("name"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Name") << "</td>";
- else if (*it == KW("start"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Start") << "</td>";
- else if (*it == KW("end"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("End") << "</td>";
- else if (*it == KW("minstart"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Min. Start") << "</td>";
- else if (*it == KW("maxstart"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Max. Start") << "</td>";
- else if (*it == KW("minend"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Min. End") << "</td>";
- else if (*it == KW("maxend"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Max. End") << "</td>";
- else if (*it == KW("startbufferend"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Start Buf. End") << "</td>";
- else if (*it == KW("endbufferstart"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("End Buf. Start") << "</td>";
- else if (*it == KW("startbuffer"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Start Buf.") << "</td>";
- else if (*it == KW("endbuffer"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("End Buf.") << "</td>";
- else if (*it == KW("duration"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Duration") << "</td>";
- else if (*it == KW("effort"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Effort") << "</td>";
- else if (*it == KW("projectid"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Project ID") << "</td>";
- else if (*it == KW("resources"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Resources") << "</td>";
- else if (*it == KW("responsible"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Responsible") << "</td>";
- else if (*it == KW("responsibilities"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Responsibilities") << "</td>";
- else if (*it == KW("depends"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Dependencies") << "</td>";
- else if (*it == KW("follows"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Followers") << "</td>";
- else if (*it == KW("schedule"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Schedule") << "</td>";
- else if (*it == KW("mineffort"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Min. Effort") << "</td>";
- else if (*it == KW("maxeffort"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Max. Effort") << "</td>";
- else if (*it == KW("flags"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Flags") << "</td>";
- else if (*it == KW("completed"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Completed") << "</td>";
- else if (*it == KW("status"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Status") << "</td>";
- else if (*it == KW("rate"))
- {
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Rate");
- if (!project->getCurrency().isEmpty())
- s << " " << htmlFilter(project->getCurrency());
- s << "</td>";
- }
- else if (*it == KW("kotrusid"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Kotrus ID") << "</td>";
- else if (*it == KW("note"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Note") << "</td>";
- else if (*it == KW("statusnote"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Status Note") << "</td>";
- else if (*it == KW("costs"))
- {
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Costs");
- if (!project->getCurrency().isEmpty())
- s << " " << htmlFilter(project->getCurrency());
- s << "</td>";
- }
- else if (*it == KW("priority"))
- s << "<td class=\"headerbig\" rowspan=\"2\">"
- << i18n("Priority") << "</td>";
- else if (*it == KW("daily"))
- htmlDailyHeaderMonths();
- else if (*it == KW("weekly"))
- htmlWeeklyHeaderMonths();
- else if (*it == KW("monthly"))
- htmlMonthlyHeaderYears();
- else
- {
- TJMH.errorMessage
- (i18n("Unknown Column '%1' for HTML Task Report")
- .arg(*it));
- return FALSE;
- }
- }
- s << "</tr>" << endl;
+ tci->setStatusText(time2user(iv_start, "%Y-%m-%d / [") +
+ tci->tli->account->getId() + "] " +
+ htmlFilter(tci->tli->account->getName()));
+ genCell(tci->tcf->realFormat.format(value, tci), tci, false);
+}
- // Header line 2
- bool td = FALSE;
- s << "<tr>" << endl;
- for (QStringList::Iterator it = columns.begin(); it != columns.end();
- ++it )
- {
- if (*it == KW("daily"))
- {
- td = TRUE;
- htmlDailyHeaderDays();
- }
- else if (*it == KW("weekly"))
- {
- td = TRUE;
- htmlWeeklyHeaderWeeks();
- }
- else if (*it == KW("monthly"))
- {
- td = TRUE;
- htmlMonthlyHeaderMonths();
- }
- }
- if (!td)
- s << "<td> </td>";
- s << "</tr>\n" << endl;
+void
+HTMLReportElement::generateTitle(TableCellInfo* tci, const QString& str)
+{
+ QStringList sl(str);
+ QString cellText;
+ if (!tci->tci->getTitle().isEmpty())
+ cellText = mt.expandReportVariable(tci->tci->getTitle(), &sl);
+ else
+ cellText = str;
+ cellText = htmlFilter(cellText);
+ QString cellURL = mt.expandReportVariable(tci->tci->getTitleURL(), &sl);
+ if (!cellURL.isEmpty())
+ cellText = QString("<a href=\"") + cellURL
+ + "\">" + cellText + "</a>";
+
+ puts(cellText);
+}
- return TRUE;
+void
+HTMLReportElement::generateSubTitle(TableCellInfo* tci, const QString& str)
+{
+ QStringList sl(str);
+ QString cellText;
+ if (!tci->tci->getSubTitle().isEmpty())
+ cellText = mt.expandReportVariable(tci->tci->getSubTitle(), &sl);
+ else
+ cellText = str;
+ cellText = htmlFilter(cellText);
+ QString cellURL = mt.expandReportVariable(tci->tci->getSubTitleURL(), &sl);
+ if (!cellURL.isEmpty())
+ cellText = QString("<a href=\"") + cellURL
+ + "\">" + cellText + "</a>";
+
+ puts(cellText);
+
+ tci->tci->increaseSubColumns();
}
void
-HTMLReportElement::htmlDailyHeaderDays(bool highlightNow)
+HTMLReportElement::generateRightIndented(TableCellInfo* tci, const QString& str)
{
- // Generates the 2nd header line for daily calendar views.
- for (time_t day = midnight(start); day < end; day = sameTimeNextDay(day))
- {
- int dom = dayOfMonth(day);
- s << "<td class=\"" <<
- (highlightNow && isSameDay(project->getNow(), day) ?
- "today" : isWeekend(day) ? "weekend" : "headersmall")
- << "\"><span style=\"font-size:0.8em\"> ";
- mt.clear();
- mt.addMacro(new Macro(KW("day"), QString().sprintf("%02d", dom),
- defFileName, defFileLine));
- mt.addMacro(new Macro(KW("month"),
- QString().sprintf("%02d", monthOfYear(day)),
- defFileName, defFileLine));
- mt.addMacro(new Macro(KW("year"),
- QString().sprintf("%04d", year(day)),
- defFileName, defFileLine));
- if (dom < 10)
- s << " ";
- s << generateUrl(KW("dayheader"), QString().sprintf("%d", dom));
- s << "</span></td>";
- }
+ int topIndent = 0, subIndent = 0, maxDepth = 0;
+ if (tci->tli->ca1->getType() == CA_Task)
+ {
+ if (taskSortCriteria[0] == CoreAttributesList::TreeMode)
+ subIndent = tci->tli->ca2 == 0 ? 8 : 5;
+ if (resourceSortCriteria[0] == CoreAttributesList::TreeMode)
+ topIndent = (tci->tli->ca2 != 0 ? 0 : 5) * maxDepthResourceList;
+ maxDepth = maxDepthTaskList;
+ }
+ else if (tci->tli->ca1->getType() == CA_Resource)
+ {
+ if (resourceSortCriteria[0] == CoreAttributesList::TreeMode)
+ subIndent = tci->tli->ca2 == 0 ? 8 : 5;
+ if (taskSortCriteria[0] == CoreAttributesList::TreeMode)
+ topIndent = (tci->tli->ca2 != 0 ? 0 : 5) * maxDepthTaskList;
+ maxDepth = maxDepthResourceList;
+ }
+
+ tci->setRightPadding(2 + topIndent +
+ (maxDepth - 1 - tci->tli->ca1->treeLevel()) *
+ subIndent);
+ genCell(str, tci, false);
}
void
-HTMLReportElement::htmlDailyHeaderMonths()
+HTMLReportElement::genHeadDefault(TableCellInfo* tci)
{
- // Generates the 1st header line for daily calendar views.
- if (!hidePlan && showActual)
- s << "<td class=\"headerbig\" rowspan=\"2\"> </td>";
+ puts(" <td rowspan=\"2\"");
+ if (static_cast<HTMLReport*>(report)->hasStyleSheet())
+ puts(" class=\"tj_header_cell\"");
+ puts(">");
+ generateTitle(tci, tci->tcf->getTitle());
+ puts("</td>\n");
+}
- for (time_t day = midnight(start); day < end;
- day = beginOfMonth(sameTimeNextMonth(day)))
- {
- int left = daysLeftInMonth(day);
- if (left > daysBetween(day, end))
- left = daysBetween(day, end);
- s << "<td class=\"headerbig\" colspan=\""
- << QString().sprintf("%d", left) << "\">";
- mt.clear();
- mt.addMacro(new Macro(KW("day"), QString().sprintf("%02d",
- dayOfMonth(day)),
- defFileName, defFileLine));
- mt.addMacro(new Macro(KW("month"),
- QString().sprintf("%02d", monthOfYear(day)),
- defFileName, defFileLine));
- mt.addMacro(new Macro(KW("year"),
- QString().sprintf("%04d", year(day)),
- defFileName, defFileLine));
- s << generateUrl(KW("monthheader"), monthAndYear(day));
- s << "</td>" << endl;
- }
+void
+HTMLReportElement::genHeadCurrency(TableCellInfo* tci)
+{
+ puts(" <td rowspan=\"2\"");
+ if (static_cast<HTMLReport*>(report)->hasStyleSheet())
+ puts(" class=\"tj_header_cell\"");
+ puts(">");
+ generateTitle(tci, tci->tcf->getTitle() +
+ (!report->getProject()->getCurrency().isEmpty() ?
+ QString(" ") + report->getProject()->getCurrency() :
+ QString()));
+ puts("</td>\n");
}
void
-HTMLReportElement::htmlWeeklyHeaderWeeks(bool highlightNow)
+HTMLReportElement::genHeadDaily1(TableCellInfo* tci)
{
- // Generates the 2nd header line for weekly calendar views.
- for (time_t week = beginOfWeek(start, weekStartsMonday); week < end;
- week = sameTimeNextWeek(week))
- {
- int woy = weekOfYear(week, weekStartsMonday);
- s << "<td class=\"" <<
- (highlightNow && isSameWeek(project->getNow(), week,
- weekStartsMonday) ?
- "today" : "headersmall")
- << "\"><span style=\"font-size:0.8em\"> ";
- if (woy < 10)
- s << " ";
- mt.clear();
- mt.addMacro(new Macro(KW("day"), QString().sprintf("%02d",
- dayOfMonth(woy)),
- defFileName, defFileLine));
- mt.addMacro(new Macro(KW("month"),
- QString().sprintf("%02d", monthOfYear(woy)),
- defFileName, defFileLine));
- mt.addMacro(new Macro(KW("year"),
- QString().sprintf("%04d", year(woy)),
- defFileName, defFileLine));
- s << generateUrl(KW("weekheader"), QString().sprintf("%d", woy));
- s << "</span></td>";
- }
+ // Generates the 1st header line for daily calendar views.
+ bool weekStartsMonday = report->getWeekStartsMonday();
+ for (time_t day = midnight(start); day < end;
+ day = sameTimeNextMonth(beginOfMonth(day)))
+ {
+ int left = daysLeftInMonth(day);
+ if (left > daysBetween(day, end))
+ left = daysBetween(day, end);
+ s() << " <td colspan=\""
+ << QString().sprintf("%d", left) << "\"";
+ if (static_cast<HTMLReport*>(report)->hasStyleSheet())
+ s() << " class=\"tj_header_cell\"";
+ s() << ">";
+ mt.setMacro(new Macro(KW("day"), "01",
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("month"),
+ QString().sprintf("%02d", monthOfYear(day)),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("quarter"),
+ QString().sprintf
+ ("%02d", quarterOfYear(day)),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("week"),
+ QString().sprintf
+ ("%02d", weekOfYear(day, weekStartsMonday)),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("year"),
+ QString().sprintf("%04d", year(day)),
+ defFileName, defFileLine));
+ generateTitle(tci, monthAndYear(day));
+ s() << "</td>" << endl;
+ }
}
void
-HTMLReportElement::htmlWeeklyHeaderMonths()
+HTMLReportElement::genHeadDaily2(TableCellInfo* tci)
{
- static const char* mnames[] =
- {
- I18N_NOOP("Jan"), I18N_NOOP("Feb"), I18N_NOOP("Mar"),
- I18N_NOOP("Apr"), I18N_NOOP("May"), I18N_NOOP("Jun"),
- I18N_NOOP("Jul"), I18N_NOOP("Aug"), I18N_NOOP("Sep"),
- I18N_NOOP("Oct"), I18N_NOOP("Nov"), I18N_NOOP("Dec")
- };
- // Generates the 1st header line for weekly calendar views.
- if (!hidePlan && showActual)
- s << "<td class=\"headerbig\" rowspan=\"2\"> </td>";
+ // Generates the 2nd header line for daily calendar views.
+ bool weekStartsMonday = report->getWeekStartsMonday();
+ for (time_t day = midnight(start); day < end; day = sameTimeNextDay(day))
+ {
+ int dom = dayOfMonth(day);
+ s() << " <td style=\"";
+ QColor bgCol = colors.getColor("header");
+ if (isWeekend(day))
+ bgCol = bgCol.dark(130);
+ if (isSameDay(report->getProject()->getNow(), day))
+ bgCol = colors.getColor("today");
+ s() << "background-color:" << bgCol.name() << "; "
+ << "font-size:80%; text-align:center\"";
+ if (static_cast<HTMLReport*>(report)->hasStyleSheet())
+ s() << " class=\"tj_header_cell\"";
+ s() << ">";
+ mt.setMacro(new Macro(KW("day"), QString().sprintf("%02d", dom),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("month"),
+ QString().sprintf("%02d", monthOfYear(day)),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("quarter"),
+ QString().sprintf
+ ("%02d", quarterOfYear(day)),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("week"),
+ QString().sprintf
+ ("%02d", weekOfYear(day, weekStartsMonday)),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("year"),
+ QString().sprintf("%04d", year(day)),
+ defFileName, defFileLine));
+ if (dom < 10)
+ s() << " ";
+ generateSubTitle(tci, QString().sprintf("%d", dom));
+ s() << "</td>" << endl;
+ }
+}
- for (time_t week = beginOfWeek(start, weekStartsMonday); week < end; )
- {
- int currMonth = monthOfWeek(week, weekStartsMonday);
- int left;
- time_t wi = sameTimeNextWeek(week);
- for (left = 1 ; wi < end &&
- monthOfWeek(wi, weekStartsMonday) == currMonth;
- wi = sameTimeNextWeek(wi))
- left++;
-
- s << "<td class=\"headerbig\" colspan=\""
- << QString().sprintf("%d", left) << "\">";
- mt.clear();
- mt.addMacro(new Macro(KW("month"),
- QString().sprintf("%02d", monthOfWeek(week,
- weekStartsMonday)),
- defFileName, defFileLine));
- mt.addMacro(new Macro(KW("year"),
- QString().sprintf("%04d", yearOfWeek(week,
- weekStartsMonday)),
- defFileName, defFileLine));
- s << generateUrl(KW("monthheader"),
- QString("%1 %2").
- arg(i18n(mnames[monthOfWeek(week, weekStartsMonday) -
- 1])).
- arg(yearOfWeek(week, weekStartsMonday)));
- s << "</td>" << endl;
- week = wi;
- }
+void
+HTMLReportElement::genHeadWeekly1(TableCellInfo* tci)
+{
+ // Generates the 1st header line for weekly calendar views.
+ bool weekStartsMonday = report->getWeekStartsMonday();
+ for (time_t week = beginOfWeek(start, weekStartsMonday); week < end; )
+ {
+ int currMonth = monthOfWeek(week, weekStartsMonday);
+ int left;
+ time_t wi = sameTimeNextWeek(week);
+ for (left = 1 ; wi < end &&
+ monthOfWeek(wi, weekStartsMonday) == currMonth;
+ wi = sameTimeNextWeek(wi))
+ left++;
+
+ s() << " <td colspan=\""
+ << QString().sprintf("%d", left) << "\"";
+ if (static_cast<HTMLReport*>(report)->hasStyleSheet())
+ s() << " class=\"tj_header_cell\"";
+ s() << ">";
+ mt.setMacro(new Macro(KW("day"), QString().sprintf
+ ("%02d", dayOfMonth(week)),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("month"),
+ QString().sprintf
+ ("%02d", monthOfWeek(week, weekStartsMonday)),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("quarter"),
+ QString().sprintf
+ ("%02d", quarterOfYear(week)),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("week"),
+ QString().sprintf
+ ("%02d", weekOfYear(week, weekStartsMonday)),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("year"),
+ QString().sprintf
+ ("%04d", yearOfWeek(week, weekStartsMonday)),
+ defFileName, defFileLine));
+ generateTitle(tci,
+ QString("%1 %2").arg(shortMonthName(monthOfWeek(week,
+ weekStartsMonday)
+ - 1)).
+ arg(yearOfWeek(week, weekStartsMonday)));
+ s() << "</td>" << endl;
+ week = wi;
+ }
}
void
-HTMLReportElement::htmlMonthlyHeaderMonths(bool highlightNow)
+HTMLReportElement::genHeadWeekly2(TableCellInfo* tci)
{
- // Generates 2nd header line of monthly calendar view.
- static const char* mnames[] =
- {
- I18N_NOOP("Jan"), I18N_NOOP("Feb"), I18N_NOOP("Mar"),
- I18N_NOOP("Apr"), I18N_NOOP("May"), I18N_NOOP("Jun"),
- I18N_NOOP("Jul"), I18N_NOOP("Aug"), I18N_NOOP("Sep"),
- I18N_NOOP("Oct"), I18N_NOOP("Nov"), I18N_NOOP("Dec")
- };
+ // Generates the 2nd header line for weekly calendar views.
+ bool wsm = report->getWeekStartsMonday();
+ for (time_t week = beginOfWeek(start, wsm); week < end;
+ week = sameTimeNextWeek(week))
+ {
+ int woy = weekOfYear(week, wsm);
+ s() << " <td style=\"";
+ QColor bgCol;
+ if (isSameWeek(report->getProject()->getNow(), week, wsm))
+ bgCol = colors.getColor("today");
+ else
+ bgCol = colors.getColor("header");
+ s() << "background-color:" << bgCol.name() << "; "
+ << "font-size:80%; text-align:center\"";
+ if (static_cast<HTMLReport*>(report)->hasStyleSheet())
+ s() << " class=\"tj_header_cell\"";
+ s() << ">";
+ if (woy < 10)
+ s() << " ";
+ mt.setMacro(new Macro(KW("day"), QString().sprintf
+ ("%02d", dayOfMonth(week)),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("month"),
+ QString().sprintf("%02d",
+ monthOfWeek(week, wsm)),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("quarter"),
+ QString().sprintf
+ ("%02d", quarterOfYear(week)),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("week"),
+ QString().sprintf("%02d", woy),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("year"),
+ QString().sprintf("%04d", yearOfWeek(week, wsm)),
+ defFileName, defFileLine));
+ generateSubTitle(tci, QString().sprintf("%d", woy));
+ s() << "</td>" << endl;
+ }
+}
- for (time_t month = beginOfMonth(start); month < end;
- month = sameTimeNextMonth(month))
- {
- int moy = monthOfYear(month);
- s << "<td class=\"" <<
- (highlightNow && isSameMonth(project->getNow(), month) ?
- "today" : "headersmall")
- << "\"><span style=\"font-size:0.8em\"> ";
- mt.clear();
- mt.addMacro(new Macro(KW("day"), QString().sprintf("%02d",
- dayOfMonth(moy)),
- defFileName, defFileLine));
- mt.addMacro(new Macro(KW("month"),
- QString().sprintf("%02d", monthOfYear(moy)),
- defFileName, defFileLine));
- mt.addMacro(new Macro(KW("year"),
- QString().sprintf("%04d", year(moy)),
- defFileName, defFileLine));
- s << generateUrl(KW("monthheader"), i18n(mnames[moy - 1]));
- s << "</span></td>";
- }
+void
+HTMLReportElement::genHeadMonthly1(TableCellInfo* tci)
+{
+ // Generates 1st header line of monthly calendar view.
+ for (time_t year = beginOfMonth(start); year < end;
+ year = sameTimeNextYear(beginOfYear(year)))
+ {
+ int left = monthLeftInYear(year);
+ if (left > monthsBetween(year, end))
+ left = monthsBetween(year, end);
+ s() << " <td colspan=\""
+ << QString().sprintf("%d", left) << "\"";
+ if (static_cast<HTMLReport*>(report)->hasStyleSheet())
+ s() << " class=\"tj_header_cell\"";
+ s() << ">";
+ mt.setMacro(new Macro(KW("day"), "01",
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("month"), "01",
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("quarter"), "1",
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("week"), "01",
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("year"),
+ QString().sprintf("%04d", ::year(year)),
+ defFileName, defFileLine));
+ generateTitle(tci, QString().sprintf("%d", ::year(year)));
+ s() << "</td>" << endl;
+ }
}
void
-HTMLReportElement::htmlMonthlyHeaderYears()
+HTMLReportElement::genHeadMonthly2(TableCellInfo* tci)
{
- // Generates 1st header line of monthly calendar view.
- if (!hidePlan && showActual)
- s << "<td class=\"headerbig\" rowspan=\"2\"> </td>";
+ // Generates 2nd header line of monthly calendar view.
+ bool weekStartsMonday = report->getWeekStartsMonday();
+ for (time_t month = beginOfMonth(start); month < end;
+ month = sameTimeNextMonth(month))
+ {
+ int moy = monthOfYear(month);
+ s() << " <td style=\"";
+ QColor bgCol;
+ if (isSameMonth(report->getProject()->getNow(), month))
+ bgCol = colors.getColor("today");
+ else
+ bgCol = colors.getColor("header");
+ s() << "background-color:" << bgCol.name() << "; "
+ << "font-size:80%; text-align:center\"";
+ if (static_cast<HTMLReport*>(report)->hasStyleSheet())
+ s() << " class=\"tj_header_cell\"";
+ s() << ">";
+ if (month < 10)
+ s() << " ";
+ mt.setMacro(new Macro(KW("day"), "01",
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("month"),
+ QString().sprintf("%02d", moy),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("quarter"),
+ QString().sprintf
+ ("%02d", quarterOfYear(month)),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("week"),
+ QString().sprintf
+ ("%02d", weekOfYear(month, weekStartsMonday)),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("year"),
+ QString().sprintf("%04d", year(month)),
+ defFileName, defFileLine));
+ generateSubTitle(tci, shortMonthName(moy - 1));
+ s() << "</td>" << endl;
+ }
+}
- for (time_t year = midnight(start); year < end;
- year = beginOfYear(sameTimeNextYear(year)))
- {
- int left = monthLeftInYear(year);
- if (left > monthsBetween(year, end))
- left = monthsBetween(year, end);
- s << "<td class=\"headerbig\" colspan=\""
- << QString().sprintf("%d", left) << "\">";
- mt.clear();
- mt.addMacro(new Macro(KW("day"), QString().sprintf("%02d",
- dayOfMonth(year)),
- defFileName, defFileLine));
- mt.addMacro(new Macro(KW("month"),
- QString().sprintf("%02d", monthOfYear(year)),
- defFileName, defFileLine));
- mt.addMacro(new Macro(KW("year"),
- QString().sprintf("%04d", ::year(year)),
- defFileName, defFileLine));
- s << generateUrl(KW("yearheader"),
- QString().sprintf("%d", ::year(year)));
- s << "</td>" << endl;
- }
+void
+HTMLReportElement::genHeadQuarterly1(TableCellInfo* tci)
+{
+ // Generates 1st header line of quarterly calendar view.
+ for (time_t year = beginOfQuarter(start); year < end;
+ year = sameTimeNextYear(beginOfYear(year)))
+ {
+ int left = quartersLeftInYear(year);
+ if (left > quartersBetween(year, end))
+ left = quartersBetween(year, end);
+ s() << " <td colspan=\""
+ << QString().sprintf("%d", left) << "\"";
+ if (static_cast<HTMLReport*>(report)->hasStyleSheet())
+ s() << " class=\"tj_header_cell\"";
+ s() << ">";
+ mt.setMacro(new Macro(KW("day"), "01",
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("month"), "01",
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("quarter"), "1",
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("week"), "01",
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("year"),
+ QString().sprintf("%04d", ::year(year)),
+ defFileName, defFileLine));
+ generateTitle(tci, QString().sprintf("%d", ::year(year)));
+ s() << "</td>" << endl;
+ }
}
void
-HTMLReportElement::emptyPlan(bool light)
+HTMLReportElement::genHeadQuarterly2(TableCellInfo* tci)
{
- s << "<td class=\""
- << (light ? "defaultlight" : "default")
- << "\" rowspan=\""
- << (showActual ? "2" : "1")
- << "\"> </td>";
+ // Generates 2nd header line of quarterly calendar view.
+ static const char* qnames[] =
+ {
+ I18N_NOOP("1st Quarter"), I18N_NOOP("2nd Quarter"),
+ I18N_NOOP("3rd Quarter"), I18N_NOOP("4th Quarter")
+ };
+
+ bool weekStartsMonday = report->getWeekStartsMonday();
+ for (time_t quarter = beginOfQuarter(start); quarter < end;
+ quarter = sameTimeNextQuarter(quarter))
+ {
+ int qoy = quarterOfYear(quarter);
+ s() << " <td style=\"";
+ QColor bgCol;
+ if (isSameQuarter(report->getProject()->getNow(), quarter))
+ bgCol = colors.getColor("today");
+ else
+ bgCol = colors.getColor("header");
+ s() << "background-color:" << bgCol.name() << "; "
+ << "font-size:80%; text-align:center\"";
+ if (static_cast<HTMLReport*>(report)->hasStyleSheet())
+ s() << " class=\"tj_header_cell\"";
+ s() << ">";
+ mt.setMacro(new Macro(KW("day"), QString().sprintf("%02d",
+ dayOfMonth(quarter)),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("month"),
+ QString().sprintf("%02d", monthOfYear(quarter)),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("quarter"),
+ QString().sprintf("%d", qoy),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("week"),
+ QString().sprintf
+ ("%02d", weekOfYear(quarter, weekStartsMonday)),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("year"),
+ QString().sprintf("%04d", year(quarter)),
+ defFileName, defFileLine));
+ generateSubTitle(tci, i18n(qnames[qoy - 1]));
+ s() << "</td>" << endl;
+ }
}
void
-HTMLReportElement::emptyActual(bool light)
+HTMLReportElement::genHeadYear(TableCellInfo* tci)
{
- s << "<td class=\""
- << (light ? "defaultlight" : "default")
- << "\"> </td>";
+ // Generates 1st header line of monthly calendar view.
+ for (time_t year = beginOfYear(start); year < end;
+ year = sameTimeNextYear(year))
+ {
+ s() << " <td rowspan=\"2\"";
+ if (static_cast<HTMLReport*>(report)->hasStyleSheet())
+ s() << " class=\"tj_header_cell\"";
+ s() << ">";
+ mt.setMacro(new Macro(KW("day"), QString().sprintf("%02d",
+ dayOfMonth(year)),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("month"),
+ QString().sprintf("%02d", monthOfYear(year)),
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("quarter"), "1",
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("week"), "01",
+ defFileName, defFileLine));
+ mt.setMacro(new Macro(KW("year"),
+ QString().sprintf("%04d", ::year(year)),
+ defFileName, defFileLine));
+ generateTitle(tci, QString().sprintf("%d", ::year(year)));
+ s() << "</td>" << endl;
+ }
}
void
-HTMLReportElement::textOneRow(const QString& text, bool light, const QString& align)
+HTMLReportElement::genCellEmpty(TableCellInfo* tci)
{
- s << "<td class=\""
- << (light ? "defaultlight" : "default") << "\"";
- if (!align.isEmpty())
- s << " style=\"text-align:" << align << " white-space:nowrap\"";
- s << ">" << text << "</td>";
+ genCell("", tci, true);
}
void
-HTMLReportElement::textMultiRows(const QString& text, bool light,
- const QString& align)
+HTMLReportElement::genCellSequenceNo(TableCellInfo* tci)
{
- s << "<td class=\""
- << (light ? "defaultlight" : "default")
- << "\" rowspan=\""
- << scenarios.count() << "\"";
- if (!align.isEmpty())
- s << " style=\"text-align:" << align << "; white-space:nowrap\"";
- s << ">" << text << "</td>";
+ genCell(tci->tli->ca2 == 0 ?
+ QString().sprintf("%d.", tci->tli->ca1->getSequenceNo()) :
+ QString::null, tci, true);
}
void
-HTMLReportElement::dailyResourcePlan(const Resource* r, const Task* t)
+HTMLReportElement::genCellNo(TableCellInfo* tci)
{
- if (hidePlan)
- return;
+ genCell(tci->tli->ca2 == 0 ? QString().sprintf("%d.", tci->tli->idxNo) :
+ QString::null, tci, true);
+}
- if (showActual)
- s << "<td class=\"headersmall\">Plan</td>" << endl;
+void
+HTMLReportElement::genCellHierarchNo(TableCellInfo* tci)
+{
+ genCell(tci->tli->ca2 == 0 ?
+ tci->tli->ca1->getHierarchNo() : QString::null, tci, true);
+}
- for (time_t day = midnight(start); day < end;
- day = sameTimeNextDay(day))
- {
- double load = r->getLoad(Task::Plan, Interval(day).firstDay(), t);
- QString bgCol =
- load > r->getMinEffort() * r->getEfficiency() ?
- (t == 0 ? "booked" : "bookedlight") :
- isSameDay(project->getNow(), day) ? "today" :
- isWeekend(day) ? "weekend" :
- project->isVacation(day) || r->hasVacationDay(day) ?
- "vacation" :
- (t == 0 ? "default" : "defaultlight");
- reportLoad(load, bgCol, !r->isGroup());
- }
+void
+HTMLReportElement::genCellIndex(TableCellInfo* tci)
+{
+ genCell(tci->tli->ca2 == 0 ?
+ QString().sprintf("%d.", tci->tli->ca1->getIndex()) :
+ QString::null, tci, true);
}
void
-HTMLReportElement::dailyResourceActual(const Resource* r, const Task* t)
+HTMLReportElement::genCellHierarchIndex(TableCellInfo* tci)
{
- if (!hidePlan)
- s << "<td class=\"headersmall\">Actual</td>" << endl;
+ genCell(tci->tli->ca2 == 0 ?
+ tci->tli->ca1->getHierarchIndex() : QString::null, tci, true);
+}
- for (time_t day = midnight(start); day < end;
- day = sameTimeNextDay(day))
- {
- double load = r->getLoad(Task::Actual, Interval(day).firstDay(), t);
- QString bgCol =
- load > r->getMinEffort() * r->getEfficiency() ?
- (t == 0 ? "booked" :
- (t->isCompleted(Task::Plan, sameTimeNextDay(day) - 1) ?
- "completedlight" : "bookedlight")) :
- isSameDay(project->getNow(), day) ? "today" :
- isWeekend(day) ? "weekend" :
- project->isVacation(day) || r->hasVacationDay(day) ?
- "vacation" :
- (t == 0 ? "default" : "defaultlight");
- reportLoad(load, bgCol, !r->isGroup());
- }
+void
+HTMLReportElement::genCellId(TableCellInfo* tci)
+{
+ genCell(tci->tli->ca1->getId(), tci, true);
}
-void
-HTMLReportElement::dailyTaskPlan(const Task* t, const Resource* r)
+void
+HTMLReportElement::genCellName(TableCellInfo* tci)
{
- if (hidePlan)
- return;
+ int lPadding = 0;
+ int fontSize = tci->tli->ca2 == 0 ? 100 : 90;
+ if ((tci->tli->ca2 && tci->tli->ca2->getType() == CA_Resource &&
+ resourceSortCriteria[0] == CoreAttributesList::TreeMode) ||
+ (tci->tli->ca2 && tci->tli->ca2->getType() == CA_Task &&
+ taskSortCriteria[0] == CoreAttributesList::TreeMode) ||
+ (tci->tli->ca2 && tci->tli->ca2->getType() == CA_Account &&
+ accountSortCriteria[0] == CoreAttributesList::TreeMode))
+ for (const CoreAttributes* cp = tci->tli->ca2 ; cp != 0;
+ cp = cp->getParent())
+ lPadding++;
+
+ QString text;
+ if (tci->tli->specialName.isNull())
+ {
+ if (tci->tli->task)
+ mt.setMacro(new Macro(KW("taskid"), tci->tli->task->getId(),
+ defFileName, defFileLine));
+ if (tci->tli->resource)
+ mt.setMacro(new Macro(KW("resourceid"), tci->tli->resource->getId(),
+ defFileName, defFileLine));
+ if (tci->tli->account)
+ mt.setMacro(new Macro(KW("accountid"), tci->tli->account->getId(),
+ defFileName, defFileLine));
+
+ if ((tci->tli->ca1->getType() == CA_Resource &&
+ resourceSortCriteria[0] == CoreAttributesList::TreeMode) ||
+ (tci->tli->ca1->getType() == CA_Task &&
+ taskSortCriteria[0] == CoreAttributesList::TreeMode) ||
+ (tci->tli->ca1->getType() == CA_Account &&
+ accountSortCriteria[0] == CoreAttributesList::TreeMode))
+ {
+ lPadding += tci->tli->ca1->treeLevel();
+ tci->setFontFactor(fontSize + 5 * (maxDepthTaskList - 1 -
+ tci->tli->ca1->treeLevel()));
+ }
+ tci->setLeftPadding(2 + lPadding * 15);
+ text = tci->tli->ca1->getName();
+ }
+ else
+ text = tci->tli->specialName;
+ genCell(text, tci, true);
+}
- if (showActual)
- s << "<td class=\"headersmall\">Plan</td>" << endl;
+void
+HTMLReportElement::genCellStart(TableCellInfo* tci)
+{
+ if (!tci->tli->task->isStartOk(tci->tli->sc))
+ tci->setBgColor(colors.getColor("error"));
+ genCell(time2user(tci->tli->task->getStart(tci->tli->sc), timeFormat),
+ tci, false);
+}
- for (time_t day = midnight(start); day < end;
- day = sameTimeNextDay(day))
- {
- double load = t->getLoad(Task::Plan, Interval(day).firstDay(), r);
- QString bgCol =
- t->isActive(Task::Plan, Interval(day).firstDay()) ?
- (t->isMilestone() ? "milestone" :
- (r == 0 && !t->isBuffer(Task::Plan, Interval(day).firstDay()) ?
- "booked" : "bookedlight")) :
- isSameDay(project->getNow(), day) ? "today" :
- isWeekend(day) ? "weekend" :
- project->isVacation(day) ? "vacation" :
- (r == 0 ? "default" : "defaultlight");
- if (showPIDs)
- {
- QString pids = r->getProjectIDs(Task::Plan,
- Interval(day).firstDay(), t);
- reportPIDs(pids, bgCol, !r->isGroup());
- }
- else
- reportLoad(load, bgCol, !t->isContainer());
- }
+void
+HTMLReportElement::genCellEnd(TableCellInfo* tci)
+{
+ if (!tci->tli->task->isEndOk(tci->tli->sc))
+ tci->setBgColor(colors.getColor("error"));
+ genCell(time2user(tci->tli->task->getEnd(tci->tli->sc) + 1, timeFormat),
+ tci, false);
}
+#define GCMMSE(a, b) \
+void \
+HTMLReportElement::genCell##a(TableCellInfo* tci) \
+{ \
+ genCell(tci->tli->task->get##a(tci->tli->sc) == 0 ? QString() : \
+ time2user(tci->tli->task->get##a(tci->tli->sc) + b, timeFormat), \
+ tci, false); \
+}
+
+GCMMSE(MinStart, 0)
+GCMMSE(MaxStart, 0)
+GCMMSE(MinEnd, 1)
+GCMMSE(MaxEnd, 1)
+
+#define GCSEBUFFER(a) \
+void \
+HTMLReportElement::genCell##a##Buffer(TableCellInfo* tci) \
+{ \
+ genCell(QString().sprintf \
+ ("%3.0f", tci->tli->task->get##a##Buffer(tci->tli->sc)), \
+ tci, false); \
+}
+
+GCSEBUFFER(Start)
+GCSEBUFFER(End)
+
void
-HTMLReportElement::dailyTaskActual(const Task* t, const Resource* r)
+HTMLReportElement::genCellStartBufferEnd(TableCellInfo* tci)
{
- if (!hidePlan)
- s << "<td class=\"headersmall\">Actual</td>" << endl;
+ genCell(time2user(tci->tli->task->getStartBufferEnd
+ (tci->tli->sc), timeFormat), tci, false);
+}
- for (time_t day = midnight(start); day < end;
- day = sameTimeNextDay(day))
- {
- double load = t->getLoad(Task::Actual, Interval(day).firstDay(), r);
- QString bgCol =
- t->isActive(Task::Actual, Interval(day).firstDay()) ?
- (t->isCompleted(Task::Plan, sameTimeNextDay(day) - 1) ?
- (r == 0 ? "completed" : "completedlight") :
- t->isMilestone() ? "milestone" :
- (r == 0 && !t->isBuffer(Task::Actual, Interval(day).firstDay())
- ? "booked" : "bookedlight")) :
- isSameDay(project->getNow(), day) ? "today" :
- isWeekend(day) ? "weekend" :
- project->isVacation(day) ? "vacation" :
- (r == 0 ? "default" : "defaultlight");
- if (showPIDs)
- {
- QString pids = r->getProjectIDs(Task::Actual,
- Interval(day).firstDay(), t);
- reportPIDs(pids, bgCol, !r->isGroup());
- }
- else
- reportLoad(load, bgCol, !t->isContainer());
- }
+void
+HTMLReportElement::genCellEndBufferStart(TableCellInfo* tci)
+{
+ genCell(time2user(tci->tli->task->getStartBufferEnd
+ (tci->tli->sc) + 1, timeFormat), tci, false);
}
void
-HTMLReportElement::weeklyResourcePlan(const Resource* r, const Task* t)
+HTMLReportElement::genCellDuration(TableCellInfo* tci)
{
- if (hidePlan)
- return;
+ genCell(scaledDuration(tci->tli->task->getCalcDuration(tci->tli->sc),
+ tci->tcf->realFormat),
+ tci, false);
+}
- if (showActual)
- s << "<td class=\"headersmall\">Plan</td>" << endl;
+void
+HTMLReportElement::genCellEffort(TableCellInfo* tci)
+{
+ double val = 0.0;
+ if (tci->tli->ca1->getType() == CA_Task)
+ {
+ val = tci->tli->task->getLoad(tci->tli->sc, Interval(start, end),
+ tci->tli->resource);
+ }
+ else if (tci->tli->ca1->getType() == CA_Resource)
+ {
+ val = tci->tli->resource->getEffectiveLoad
+ (tci->tli->sc, Interval(start, end), AllAccounts, tci->tli->task);
+ }
- for (time_t week = beginOfWeek(start, weekStartsMonday); week < end;
- week = sameTimeNextWeek(week))
- {
- double load =
- r->getLoad(Task::Plan,
- Interval(week).firstWeek(weekStartsMonday), t);
- QString bgCol =
- load > r->getMinEffort() * r->getEfficiency() ?
- (t == 0 ? "booked" : "bookedlight") :
- isSameWeek(project->getNow(), week, weekStartsMonday) ? "today" :
- (t == 0 ? "default" : "defaultlight");
- if (showPIDs)
- {
- QString pids =
- r->getProjectIDs(Task::Plan, Interval(week).
- firstWeek(weekStartsMonday), t);
- reportPIDs(pids, bgCol, !r->isGroup());
- }
- else
- reportLoad(load, bgCol, !r->isGroup());
- }
+ generateRightIndented(tci, scaledLoad(val, tci->tcf->realFormat));
}
void
-HTMLReportElement::weeklyResourceActual(const Resource* r, const Task* t)
+HTMLReportElement::genCellFreeLoad(TableCellInfo* tci)
{
- if (!hidePlan)
- s << "<td class=\"headersmall\">Actual</td>" << endl;
+ double val = 0.0;
+ if (tci->tli->ca1->getType() == CA_Resource)
+ {
+ val = tci->tli->resource->getEffectiveFreeLoad
+ (tci->tli->sc, Interval(start, end));
+ }
- for (time_t week = beginOfWeek(start, weekStartsMonday); week < end;
- week = sameTimeNextWeek(week))
- {
- double load =
- r->getLoad(Task::Actual,
- Interval(week).firstWeek(weekStartsMonday), t);
- QString bgCol =
- load > r->getMinEffort() * r->getEfficiency() ?
- (t == 0 ? "booked" :
- (t->isCompleted(Task::Plan, sameTimeNextWeek(week) - 1) ?
- "completedlight" : "bookedlight")) :
- isSameWeek(project->getNow(), week, weekStartsMonday) ? "today" :
- (t == 0 ? "default" : "defaultlight");
- if (showPIDs)
- {
- QString pids = r->getProjectIDs(Task::Actual, Interval(week).
- firstWeek(weekStartsMonday), t);
- reportPIDs(pids, bgCol, !r->isGroup());
- }
- else
- reportLoad(load, bgCol, !r->isGroup());
- }
+ generateRightIndented(tci, scaledLoad(val, tci->tcf->realFormat));
}
-void
-HTMLReportElement::weeklyTaskPlan(const Task* t, const Resource* r)
+void
+HTMLReportElement::genCellUtilization(TableCellInfo* tci)
{
- if (hidePlan)
- return;
+ double val = 0.0;
+ if (tci->tli->ca1->getType() == CA_Resource)
+ {
+ double load = tci->tli->resource->getEffectiveLoad
+ (tci->tli->sc, Interval(start, end));
+ if (load > 0.0)
+ {
+ double availableLoad =
+ tci->tli->resource->getEffectiveFreeLoad
+ (tci->tli->sc, Interval(start, end));
+
+ val = 100.0 / (1.0 + availableLoad / load);
+ }
+ }
- if (showActual)
- s << "<td class=\"headersmall\">Plan</td>" << endl;
+ generateRightIndented(tci, QString().sprintf("%.1f%%", val));
+}
- for (time_t week = beginOfWeek(start, weekStartsMonday); week < end;
- week = sameTimeNextWeek(week))
- {
- double load = t->getLoad(Task::Plan, Interval(week).
- firstWeek(weekStartsMonday), r);
- QString bgCol =
- t->isActive(Task::Plan,
- Interval(week).firstWeek(weekStartsMonday)) ?
- (t->isMilestone() ? "milestone" :
- (r == 0 && !t->isBuffer(Task::Plan, Interval(week).
- firstWeek(weekStartsMonday))
- ? "booked" : "bookedlight")) :
- isSameWeek(project->getNow(), week, weekStartsMonday) ? "today" :
- (r == 0 ? "default" : "defaultlight");
- reportLoad(load, bgCol, !t->isContainer());
- }
+void
+HTMLReportElement::genCellCriticalness(TableCellInfo* tci)
+{
+ generateRightIndented
+ (tci, scaledLoad(tci->tli->task->getCriticalness(tci->tli->sc),
+ tci->tcf->realFormat));
}
void
-HTMLReportElement::weeklyTaskActual(const Task* t, const Resource* r)
+HTMLReportElement::genCellPathCriticalness(TableCellInfo* tci)
{
- if (!hidePlan)
- s << "<td class=\"headersmall\">Actual</td>" << endl;
+ generateRightIndented
+ (tci, scaledLoad(tci->tli->task->getPathCriticalness(tci->tli->sc),
+ tci->tcf->realFormat));
+}
- for (time_t week = beginOfWeek(start, weekStartsMonday); week < end;
- week = sameTimeNextWeek(week))
- {
- double load = t->getLoad(Task::Actual, Interval(week).
- firstWeek(weekStartsMonday), r);
- QString bgCol =
- t->isActive(Task::Actual,
- Interval(week).firstWeek(weekStartsMonday)) ?
- (t->isCompleted(Task::Plan, sameTimeNextWeek(week) - 1) ?
- (r == 0 ? "completed" : "completedlight") :
- t->isMilestone() ? "milestone" :
- (r == 0 && !t->isBuffer(Task::Actual, Interval(week).
- firstWeek(weekStartsMonday))
- ? "booked" : "bookedlight")) :
- isSameWeek(project->getNow(), week, weekStartsMonday) ? "today" :
- (r == 0 ? "default" : "defaultlight");
- reportLoad(load, bgCol, !t->isContainer());
- }
+void
+HTMLReportElement::genCellProjectId(TableCellInfo* tci)
+{
+ genCell(tci->tli->task->getProjectId() + " (" +
+ report->getProject()->getIdIndex(tci->tli->task->
+ getProjectId()) + ")", tci,
+ true);
}
void
-HTMLReportElement::monthlyResourcePlan(const Resource* r, const Task* t)
+HTMLReportElement::genCellProjectIDs(TableCellInfo* tci)
{
- if (hidePlan)
- return;
+ genCell(tci->tli->resource->getProjectIDs(tci->tli->sc,
+ Interval(start, end)), tci, true);
+}
- if (showActual)
- s << "<td class=\"headersmall\">Plan</td>" << endl;
+void
+HTMLReportElement::genCellResources(TableCellInfo* tci)
+{
+ QString text;
+ for (ResourceListIterator rli(tci->tli->task->
+ getBookedResourcesIterator(tci->tli->sc));
+ *rli != 0; ++rli)
+ {
+ if (!text.isEmpty())
+ text += ", ";
+
+ text += (*rli)->getName();
+ }
+ genCell(text, tci, false);
+}
- for (time_t month = beginOfMonth(start); month < end;
- month = sameTimeNextMonth(month))
- {
- double load = r->getLoad(Task::Plan, Interval(month).firstMonth(), t);
- QString bgCol =
- load > r->getMinEffort() * r->getEfficiency() ?
- (t == 0 ? "booked" : "bookedlight") :
- isSameMonth(project->getNow(), month) ? "today" :
- (t == 0 ? "default" : "defaultlight");
- reportLoad(load, bgCol, !r->isGroup());
- }
+void
+HTMLReportElement::genCellResponsible(TableCellInfo* tci)
+{
+ if (tci->tli->task->getResponsible())
+ genCell(tci->tli->task->getResponsible()->getName(),
+ tci, true);
+ else
+ genCell("", tci, true);
}
void
-HTMLReportElement::monthlyResourceActual(const Resource* r, const Task* t)
+HTMLReportElement::genCellText(TableCellInfo* tci)
{
- if (!hidePlan)
- s << "<td class=\"headersmall\">Actual</td>" << endl;
+ if (tci->tcf->getId() == "note")
+ {
+ if (tci->tli->task->getNote().isEmpty())
+ genCell("", tci, true);
+ else
+ genCell(tci->tli->task->getNote(), tci, true);
+ return;
+ }
- for (time_t month = beginOfMonth(start); month < end;
- month = sameTimeNextMonth(month))
- {
- double load = r->getLoad(Task::Actual, Interval(month).firstMonth(), t);
- QString bgCol =
- load > r->getMinEffort() * r->getEfficiency() ?
- (t == 0 ? "booked" :
- (t->isCompleted(Task::Plan, sameTimeNextMonth(month) - 1) ?
- "completedlight" : "bookedlight")) :
- isSameMonth(project->getNow(), month) ? "today" :
- (t == 0 ? "default" : "defaultlight");
- reportLoad(load, bgCol, !r->isGroup());
- }
+ const TextAttribute* ta = static_cast<const TextAttribute*>
+ (tci->tli->ca1->getCustomAttribute(tci->tcf->getId()));
+ if (!ta || ta->getText().isEmpty())
+ genCell("", tci, true);
+ else
+ genCell(ta->getText(), tci, true);
}
void
-HTMLReportElement::monthlyTaskPlan(const Task* t, const Resource* r)
+HTMLReportElement::genCellStatusNote(TableCellInfo* tci)
{
- if (hidePlan)
- return;
+ if (tci->tli->task->getStatusNote(tci->tli->sc).isEmpty())
+ genCell("", tci, true);
+ else
+ genCell(tci->tli->task->getStatusNote(tci->tli->sc),
+ tci, true);
+}
- if (showActual)
- s << "<td class=\"headersmall\">Plan</td>" << endl;
+void
+HTMLReportElement::genCellCost(TableCellInfo* tci)
+{
+ double val = 0.0;
+ if (tci->tli->ca1->getType() == CA_Task)
+ {
+ val = tci->tli->task->getCredits(tci->tli->sc, Interval(start, end),
+ Cost, tci->tli->resource);
+ }
+ else if (tci->tli->ca1->getType() == CA_Resource)
+ {
+ val = tci->tli->resource->getCredits(tci->tli->sc, Interval(start, end),
+ Cost, tci->tli->task);
+ }
+ generateRightIndented(tci, tci->tcf->realFormat.format(val, tci));
+}
- for (time_t month = beginOfMonth(start); month < end;
- month = sameTimeNextMonth(month))
- {
- double load = t->getLoad(Task::Plan, Interval(month).firstMonth(), r);
- QString bgCol =
- t->isActive(Task::Plan, Interval(month).firstMonth()) ?
- (t->isMilestone() ? "milestone" :
- (r == 0 && !t->isBuffer(Task::Plan, Interval(month).firstMonth())
- ? "booked" : "bookedlight")) :
- isSameMonth(project->getNow(), month) ? "today" :
- (r == 0 ? "default" : "defaultlight");
- reportLoad(load, bgCol, !t->isContainer());
- }
+void
+HTMLReportElement::genCellRevenue(TableCellInfo* tci)
+{
+ double val = 0.0;
+ if (tci->tli->ca1->getType() == CA_Task)
+ {
+ val = tci->tli->task->getCredits(tci->tli->sc, Interval(start, end),
+ Revenue, tci->tli->resource);
+ }
+ else if (tci->tli->ca1->getType() == CA_Resource)
+ {
+ val = tci->tli->resource->getCredits(tci->tli->sc, Interval(start, end),
+ Revenue, tci->tli->task);
+ }
+ generateRightIndented(tci, tci->tcf->realFormat.format(val, tci));
}
void
-HTMLReportElement::monthlyTaskActual(const Task* t, const Resource* r)
+HTMLReportElement::genCellProfit(TableCellInfo* tci)
{
- if (!hidePlan)
- s << "<td class=\"headersmall\">Actual</td>" << endl;
+ double val = 0.0;
+ if (tci->tli->ca1->getType() == CA_Task)
+ {
+ val = tci->tli->task->getCredits(tci->tli->sc, Interval(start, end),
+ Revenue, tci->tli->resource) -
+ tci->tli->task->getCredits(tci->tli->sc, Interval(start, end),
+ Cost, tci->tli->resource);
+ }
+ else if (tci->tli->ca1->getType() == CA_Resource)
+ {
+ val = tci->tli->resource->getCredits(tci->tli->sc, Interval(start, end),
+ Revenue, tci->tli->task) -
+ tci->tli->resource->getCredits(tci->tli->sc, Interval(start, end),
+ Cost, tci->tli->task);
+ }
+ generateRightIndented(tci, tci->tcf->realFormat.format(val, tci));
+}
- for (time_t month = beginOfMonth(start); month < end;
- month = sameTimeNextMonth(month))
- {
- double load = t->getLoad(Task::Actual, Interval(month).firstMonth(), r);
- QString bgCol =
- t->isActive(Task::Actual, Interval(month).firstMonth()) ?
- (t->isCompleted(Task::Plan, sameTimeNextMonth(month) - 1) ?
- (r == 0 ? "completed" : "completedlight"):
- t->isMilestone() ? "milestone" :
- (r == 0 && !t->isBuffer(Task::Actual,
- Interval(month).firstMonth())
- ? "booked" : "bookedlight")) :
- isSameMonth(project->getNow(), month) ? "today" :
- (r == 0 ? "default" : "defaultlight");
- reportLoad(load, bgCol, !t->isContainer());
- }
+void
+HTMLReportElement::genCellPriority(TableCellInfo* tci)
+{
+ genCell(QString().sprintf("%d", tci->tli->task->getPriority()),
+ tci, true);
}
void
-HTMLReportElement::taskName(const Task* t, const Resource* r, bool big)
+HTMLReportElement::genCellFlags(TableCellInfo* tci)
{
- QString spaces;
- int fontSize = big ? 100 : 90;
- if (resourceSortCriteria[0] == CoreAttributesList::TreeMode)
- for (const Resource* rp = r ; rp != 0; rp = rp->getParent())
- spaces += " ";
+ FlagList allFlags = tci->tli->ca1->getFlagList();
+ QString flagStr;
+ for (QStringList::Iterator it = allFlags.begin();
+ it != allFlags.end(); ++it)
+ {
+ if (it != allFlags.begin())
+ flagStr += ", ";
+ flagStr += *it;
+ }
+ genCell(flagStr, tci, true);
+}
- mt.clear();
- mt.addMacro(new Macro(KW("taskid"), t->getId(), defFileName,
- defFileLine));
+void
+HTMLReportElement::genCellCompleted(TableCellInfo* tci)
+{
+ double calcedCompletionDegree =
+ tci->tli->task->getCalcedCompletionDegree(tci->tli->sc);
+ double providedCompletionDegree =
+ tci->tli->task->getCompletionDegree(tci->tli->sc);
+
+ if (calcedCompletionDegree < 0)
+ {
+ if (calcedCompletionDegree == providedCompletionDegree)
+ {
+ genCell(QString(i18n("in progress")), tci, false);
+ }
+ else
+ {
+ genCell(QString(i18n("%1% (in progress)"))
+ .arg((int) providedCompletionDegree),
+ tci, false);
+ }
+ }
+ else
+ {
+ if (calcedCompletionDegree == providedCompletionDegree)
+ {
+ genCell(QString("%1%").arg((int) providedCompletionDegree),
+ tci, false);
+ }
+ else
+ {
+ genCell(QString("%1% (%2%)")
+ .arg((int) providedCompletionDegree)
+ .arg((int) calcedCompletionDegree),
+ tci, false);
+ }
+ }
+}
- if (taskSortCriteria[0] == CoreAttributesList::TreeMode)
- {
- for (uint i = 0; i < t->treeLevel(); i++)
- spaces += " ";
- fontSize = fontSize + 5 * (maxDepthTaskList - 1 - t->treeLevel());
- s << "<td class=\""
- << (r == 0 ? "task" : "tasklight") << "\" rowspan=\""
- << (showActual ? "2" : "1") << "\" style=\"white-space:nowrap\">"
- << spaces
- << "<span style=\"font-size:"
- << QString().sprintf("%d", fontSize) << "%\">";
- if (r == 0)
- s << "<a name=\"task_" << t->getId() << "\"></a>";
- s << generateUrl(KW("taskname"), t->getName());
- s << "</span></td>" << endl;
- }
- else
- {
- s << "<td class=\""
- << (r == 0 ? "task" : "tasklight") << "\" rowspan=\""
- << (showActual ? "2" : "1") << "\" style=\"white-space:nowrap\">"
- << spaces;
- if (r == 0)
- s << "<a name=\"task_" << t->getFullId() << "\"></a>";
- s << generateUrl(KW("taskname"), t->getName());
- s << "</td>" << endl;
- }
+void
+HTMLReportElement::genCellCompletedEffort(TableCellInfo* tci)
+{
+ double val = 0.0;
+
+ if (!tci->tli->resource && tci->tli->task->isLeaf())
+ {
+ // Task line, no resource.
+ val = tci->tli->task->getCompletedLoad(tci->tli->sc);
+ }
+ else if (tci->tli->ca2->getType() == CA_Resource &&
+ tci->tli->task && tci->tli->task->isLeaf())
+ {
+ // Task line, nested into a resource
+ const Project* project = report->getProject();
+ time_t now = project->getNow();
+ if (now < project->getStart())
+ now = project->getStart();
+ if (now > project->getEnd())
+ now = project->getEnd();
+ Interval iv = Interval(project->getStart(), now);
+ val = tci->tli->task->getLoad(tci->tli->sc, iv, tci->tli->resource);
+ }
+ else
+ {
+ genCell("", tci, false);
+ return;
+ }
+ generateRightIndented(tci, scaledLoad(val, tci->tcf->realFormat));
}
void
-HTMLReportElement::resourceName(const Resource* r, const Task* t, bool big)
+HTMLReportElement::genCellRemainingEffort(TableCellInfo* tci)
{
- QString spaces;
- int fontSize = big ? 100 : 90;
- if (taskSortCriteria[0] == CoreAttributesList::TreeMode)
- for (const Task* tp = t; tp != 0; tp = tp->getParent())
- spaces += " ";
+ double val = 0.0;
- mt.clear();
- mt.addMacro(new Macro(KW("resourceid"), r->getId(), defFileName,
- defFileLine));
-
- if (resourceSortCriteria[0] == CoreAttributesList::TreeMode)
- {
- for (uint i = 0; i < r->treeLevel(); i++)
- spaces += " ";
- fontSize = fontSize + 5 * (maxDepthResourceList - 1 - r->treeLevel());
- s << "<td class=\""
- << (t == 0 ? "task" : "tasklight") << "\" rowspan=\""
- << (showActual ? "2" : "1") << "\" style=\"white-space:nowrap\">"
- << spaces
- << "<span style=\"font-size:"
- << QString().sprintf("%d", fontSize) << "%\">";
- if (t == 0)
- s << "<a name=\"resource_" << r->getId() << "\"></a>";
- s << generateUrl(KW("resourcename"), r->getName());
- s << "</span></td>" << endl;
- }
- else
- {
- s << "<td class=\""
- << (t == 0 ? "task" : "tasklight") << "\" rowspan=\""
- << (showActual ? "2" : "1") << "\" style=\"white-space:nowrap\">"
- << spaces;
- if (t == 0)
- s << "<a name=\"resource_" << r->getId() << "\"></a>";
- s << generateUrl(KW("resourcename"), r->getName());
- s << "</td>" << endl;
- }
+ if (!tci->tli->resource && tci->tli->task->isLeaf())
+ {
+ // Task line, no resource.
+ val = tci->tli->task->getRemainingLoad(tci->tli->sc);
+ }
+ else if (tci->tli->ca2->getType() == CA_Resource &&
+ tci->tli->task && tci->tli->task->isLeaf())
+ {
+ // Task line, nested into a resource
+ const Project* project = report->getProject();
+ time_t now = project->getNow();
+ if (now < project->getStart())
+ now = project->getStart();
+ if (now > project->getEnd())
+ now = project->getEnd();
+ Interval iv = Interval(now, project->getEnd());
+ val = tci->tli->task->getLoad(tci->tli->sc, iv, tci->tli->resource);
+ }
+ else
+ {
+ genCell("", tci, false);
+ return;
+ }
+
+ generateRightIndented(tci, scaledLoad(val, tci->tcf->realFormat));
}
void
-HTMLReportElement::scenarioResources(int sc, const Task* t, bool light)
+HTMLReportElement::genCellStatus(TableCellInfo* tci)
{
- s << "<td class=\""
- << (light ? "defaultlight" : "default")
- << "\" style=\"text-align:left\">"
- << "<span style=\"font-size:100%\">";
- bool first = TRUE;
- for (ResourceListIterator rli(t->getBookedResourcesIterator(sc));
- *rli != 0; ++rli)
- {
- if (!first)
- s << ", ";
-
- s << htmlFilter((*rli)->getName());
- first = FALSE;
- }
- s << "</span></td>" << endl;
+ genCell(tci->tli->task->getStatusText(tci->tli->sc), tci, false);
}
void
-HTMLReportElement::generateDepends(const Task* t, bool light)
+HTMLReportElement::genCellReference(TableCellInfo* tci)
{
- s << "<td class=\""
- << (light ? "defaultlight" : "default")
- << "\" rowspan=\""
- << (showActual ? "2" : "1")
- << "\" style=\"text-align:left\"><span style=\"font-size:100%\">";
- bool first = TRUE;
- for (TaskListIterator tli(t->getPreviousIterator()); *tli != 0; ++tli)
- {
- if (!first)
- s << ", ";
- else
- first = FALSE;
- s << (*tli)->getId();
- }
- s << "</span</td>" << endl;
+ if (tci->tcf->getId() == "reference")
+ {
+ if (tci->tli->task->getReference().isEmpty())
+ genCell("", tci, true);
+ else
+ {
+ QString text ="<a href=\"" + tci->tli->task->getReference() + "\">";
+ if (tci->tli->task->getReferenceLabel().isEmpty())
+ text += htmlFilter(tci->tli->task->getReference());
+ else
+ text += htmlFilter(tci->tli->task->getReferenceLabel());
+ text += "</a>";
+ genCell(text, tci, true, false);
+ }
+ return;
+ }
+
+ const ReferenceAttribute* ra = static_cast<const ReferenceAttribute*>
+ (tci->tli->ca1->getCustomAttribute(tci->tcf->getId()));
+ if (!ra || ra->getURL().isEmpty())
+ genCell("", tci, true);
+ else
+ {
+ QString text ="<a href=\"" + ra->getURL() + "\">";
+ if (ra->getLabel().isEmpty())
+ text += htmlFilter(ra->getURL());
+ else
+ text += htmlFilter(ra->getLabel());
+ text += "</a>";
+ genCell(text, tci, true, false);
+ }
}
void
-HTMLReportElement::generateFollows(const Task* t, bool light)
+HTMLReportElement::genCellScenario(TableCellInfo* tci)
{
- s << "<td class=\""
- << (light ? "defaultlight" : "default")
- << "\" rowspan=\""
- << (showActual ? "2" : "1")
- << "\" style=\"text-align:left\">"
- "<span style=\"font-size:100%\">";
- bool first = TRUE;
- for (TaskListIterator tli(t->getFollowersIterator()); *tli != 0; ++tli)
- {
- if (!first)
- s << ", ";
- s << (*tli)->getId();
- first = FALSE;
- }
- s << "</span</td>" << endl;
+ genCell(report->getProject()->getScenarioName(tci->tli->sc), tci, false);
+}
+
+#define GCDEPFOL(a, b) \
+void \
+HTMLReportElement::genCell##a(TableCellInfo* tci) \
+{ \
+ QString text; \
+ for (TaskListIterator it(tci->tli->task->get##b##Iterator()); *it != 0; \
+ ++it) \
+ { \
+ if (!text.isEmpty()) \
+ text += ", "; \
+ text += (*it)->getId(); \
+ } \
+ genCell(text, tci, true); \
+}
+
+GCDEPFOL(Depends, Previous)
+GCDEPFOL(Follows, Followers)
+
+QColor
+HTMLReportElement::selectTaskBgColor(TableCellInfo* tci, double load,
+ const Interval& period, bool daily)
+{
+ QColor bgCol;
+ if (tci->tli->task->isActive(tci->tli->sc, period) &&
+ ((tci->tli->resource != 0 && load > 0.0) || tci->tli->resource == 0))
+ {
+ if (tci->tli->task->isCompleted(tci->tli->sc, period.getEnd()))
+ {
+ if (tci->tli->ca2 == 0)
+ bgCol = colors.getColor("completed");
+ else
+ bgCol = colors.getColor("completed").light(130);
+ }
+ else
+ {
+ if (tci->tli->ca2 == 0 &&
+ !tci->tli->task->isBuffer(tci->tli->sc, period))
+ {
+ bgCol = colors.getColor("booked");
+ }
+ else
+ {
+ bgCol = colors.getColor("booked").light(130);
+ }
+ }
+ }
+ else if (period.contains(report->getProject()->getNow()))
+ {
+ bgCol = colors.getColor("today");
+ }
+ else if (daily && (isWeekend(period.getStart()) ||
+ report->getProject()->isVacation(period.getStart())))
+ {
+ bgCol = colors.getColor("vacation");
+ }
+
+ return bgCol;
+}
+
+QColor
+HTMLReportElement::selectResourceBgColor(TableCellInfo* tci, double load,
+ const Interval& period, bool)
+{
+ QColor bgCol;
+ if ((load > tci->tli->resource->getMinEffort() *
+ tci->tli->resource->getEfficiency()) ||
+ (load == 0.0 && tci->tli->resource->isAllocated(tci->tli->sc, period)))
+ {
+ if (tci->tli->ca2 == 0)
+ {
+ bgCol = colors.getColor("booked");
+ }
+ else
+ {
+ if (tci->tli->task->isCompleted(tci->tli->sc, period.getEnd()))
+ bgCol = colors.getColor("completed").light(130);
+ else
+ bgCol = colors.getColor("booked").light(130);
+ }
+ }
+ else if (period.contains(report->getProject()->getNow()))
+ {
+ bgCol = colors.getColor("today");
+ }
+ else if (tci->tli->resource->getEffectiveLoad
+ (tci->tli->sc, period) == 0.0 &&
+ tci->tli->resource->getEffectiveFreeLoad(tci->tli->sc, period) ==
+ 0.0)
+ {
+ bgCol = colors.getColor("vacation");
+ }
+
+ return bgCol;
}
void
-HTMLReportElement::generateResponsibilities(const Resource*r, bool light)
+HTMLReportElement::genCellTaskFunc(TableCellInfo* tci, bool daily,
+ time_t (*beginOfT)(time_t),
+ time_t (*sameTimeNextT)(time_t))
{
- s << "<td class=\""
- << (light ? "defaultlight" : "default")
- << "\" rowspan=\""
- << (showActual ? "2" : "1")
- << "\" style=\"text-align:left\">"
- "<span style=\"font-size:100%\">";
- bool first = TRUE;
- for (TaskListIterator tli(project->getTaskListIterator()); *tli != 0;
- ++tli)
- {
- if ((*tli)->getResponsible() == r)
- {
- if (!first)
- s << ", ";
- s << (*tli)->getId();
- first = FALSE;
- }
- }
- s << "</span></td>" << endl;
+ for (time_t t = (*beginOfT)(start); t < end; t = (*sameTimeNextT)(t))
+ {
+ Interval period = Interval(t, sameTimeNextT(t) - 1);
+ double load = tci->tli->task->getLoad(tci->tli->sc, period,
+ tci->tli->resource);
+ QColor bgCol = selectTaskBgColor(tci, load, period, daily);
+
+ int runLength = 1;
+ if (!tci->tli->task->isActive(tci->tli->sc, period))
+ {
+ time_t lastEndT = t;
+ for (time_t endT = sameTimeNextT(t); endT < end;
+ endT = sameTimeNextT(endT))
+ {
+ Interval periodProbe = Interval(endT, sameTimeNextT(endT) - 1);
+ double loadProbe = tci->tli->task->getLoad(tci->tli->sc,
+ periodProbe,
+ tci->tli->resource);
+ QColor bgColProbe = selectTaskBgColor(tci, loadProbe,
+ periodProbe, daily);
+ if (load != loadProbe || bgCol != bgColProbe)
+ break;
+ lastEndT = endT;
+ runLength++;
+ }
+ t = lastEndT;
+ }
+ tci->setColumns(runLength);
+ tci->setBgColor(bgCol);
+
+ reportTaskLoad(load, tci, period);
+ }
}
void
-HTMLReportElement::generateSchedule(int sc, const Resource* r, const Task* t)
+HTMLReportElement::genCellResourceFunc(TableCellInfo* tci, bool daily,
+ time_t (*beginOfT)(time_t),
+ time_t (*sameTimeNextT)(time_t))
{
- s << "<td class=\""
- << (t == 0 ? "default" : "defaultlight")
- << "\" style=\"text-align:left\">";
+ for (time_t t = beginOfT(start); t < end; t = sameTimeNextT(t))
+ {
+ Interval period = Interval(t, sameTimeNextT(t) - 1);
+ double load = tci->tli->resource->getEffectiveLoad
+ (tci->tli->sc, period, AllAccounts, tci->tli->task);
+ QColor bgCol = selectResourceBgColor(tci, load, period, daily);
+
+ int runLength = 1;
+ if (load == 0.0)
+ {
+ time_t lastEndT = t;
+ for (time_t endT = sameTimeNextT(t); endT < end;
+ endT = sameTimeNextT(endT))
+ {
+ Interval periodProbe = Interval(endT, sameTimeNextT(endT) - 1);
+ double loadProbe = tci->tli->resource->getEffectiveLoad
+ (tci->tli->sc, periodProbe, AllAccounts, tci->tli->task);
+ QColor bgColProbe = selectResourceBgColor(tci, loadProbe,
+ periodProbe, daily);
+
+ if (load != loadProbe || bgCol != bgColProbe)
+ break;
+ lastEndT = endT;
+ runLength++;
+ }
+ t = lastEndT;
+ }
+ tci->setColumns(runLength);
+ tci->setBgColor(bgCol);
+
+ reportResourceLoad(load, tci, period);
+ }
+}
- if (r)
- {
- BookingList jobs = r->getJobs(sc);
- jobs.setAutoDelete(TRUE);
- time_t prevTime = 0;
- Interval reportPeriod(start, end);
- s << "<table style=\"width:150px; font-size:100%; "
- "text-align:left\"><tr><th style=\"width:35%\"></th>"
- "<th style=\"width:65%\"></th></tr>" << endl;
- for (BookingListIterator bli(jobs); *bli != 0; ++bli)
- {
- if ((t == 0 || t == (*bli)->getTask()) &&
- reportPeriod.overlaps(Interval((*bli)->getStart(),
- (*bli)->getEnd())))
- {
- /* If the reporting interval is not more than a day, we
- * do not print the day since this information is most
- * likely given by the context of the report. */
- if (!isSameDay(prevTime, (*bli)->getStart()) &&
- !isSameDay(start, end - 1))
- {
- s << "<tr><td colspan=\"2\" style=\"font-size:120%\">"
- << time2weekday((*bli)->getStart()) << ", "
- << time2date((*bli)->getStart()) << "</td></tr>"
- << endl;
- }
- s << "<tr><td>";
- Interval workPeriod((*bli)->getStart(), (*bli)->getEnd());
- workPeriod.overlap(reportPeriod);
- s << time2user(workPeriod.getStart(), shortTimeFormat)
- << " - "
- << time2user(workPeriod.getEnd() + 1, shortTimeFormat);
- s << "</td><td>";
- if (t == 0)
- s << " " << htmlFilter((*bli)->getTask()->getName());
- s << "</td>" << endl;
- prevTime = (*bli)->getStart();
- s << "</tr>" << endl;
- }
- }
- s << "</table>" << endl;
- }
- else
- s << " ";
+void
+HTMLReportElement::genCellAccountFunc(TableCellInfo* tci,
+ time_t (*beginOfT)(time_t),
+ time_t (*sameTimeNextT)(time_t))
+{
+ tci->tcf->realFormat = currencyFormat;
+ for (time_t t = beginOfT(start); t < end; t = sameTimeNextT(t))
+ {
+ double volume = tci->tli->account->
+ getVolume(tci->tli->sc, Interval(t, sameTimeNextT(t) - 1));
+ if ((accountSortCriteria[0] == CoreAttributesList::TreeMode &&
+ tci->tli->account->isRoot()) ||
+ (accountSortCriteria[0] != CoreAttributesList::TreeMode))
+ tci->tci->addToSum(tci->tli->sc, time2ISO(t), volume);
+ reportCurrency(volume, tci, t);
+ }
+}
- s << "</td>" << endl;
+void
+HTMLReportElement::genCellDailyTask(TableCellInfo* tci)
+{
+ genCellTaskFunc(tci, true, midnight, sameTimeNextDay);
}
void
-HTMLReportElement::flagList(const CoreAttributes* c1, const CoreAttributes* c2)
+HTMLReportElement::genCellDailyResource(TableCellInfo* tci)
{
- FlagList allFlags = c1->getFlagList();
- QString flagStr;
- for (QStringList::Iterator it = allFlags.begin();
- it != allFlags.end(); ++it)
- {
- if (it != allFlags.begin())
- flagStr += ", ";
- flagStr += htmlFilter(*it);
- }
- if (flagStr.isEmpty())
- flagStr = " ";
- textMultiRows(flagStr, c2 != 0, "left");
+ genCellResourceFunc(tci, true, midnight, sameTimeNextDay);
}
void
-HTMLReportElement::generateTaskStatus(TaskStatus status, bool light)
+HTMLReportElement::genCellDailyAccount(TableCellInfo* tci)
{
- QString text;
- switch (status)
- {
- case NotStarted:
- text = "Not yet started";
- break;
- case InProgressLate:
- text = "Behind schedule";
- break;
- case InProgress:
- text = "Work in progress";
- break;
- case OnTime:
- text = "On schedule";
- break;
- case InProgressEarly:
- text = "Ahead of schedule";
- break;
- case Finished:
- text = "Finished";
- break;
- default:
- text = "Unknown status";
- break;
- }
- textOneRow(text, light, "center");
+ genCellAccountFunc(tci, midnight, sameTimeNextDay);
}
-QString
-HTMLReportElement::htmlFilter(const QString& s) const
+void
+HTMLReportElement::genCellWeeklyTask(TableCellInfo* tci)
{
- if (!HtmlMap)
- {
- HtmlMap = new QMap<Q_UINT16, QCString>;
+ bool weekStartsMonday = report->getWeekStartsMonday();
+ for (time_t week = beginOfWeek(start, weekStartsMonday); week < end;
+ week = sameTimeNextWeek(week))
+ {
+ Interval period = Interval(week, sameTimeNextWeek(week) - 1);
+ double load = tci->tli->task->getLoad(tci->tli->sc, period,
+ tci->tli->resource);
+ QColor bgCol = selectTaskBgColor(tci, load, period, false);
+
+ int runLength = 1;
+ if (!tci->tli->task->isActive(tci->tli->sc, period))
+ {
+ time_t lastEndWeek = week;
+ for (time_t endWeek = sameTimeNextWeek(week); endWeek < end;
+ endWeek = sameTimeNextWeek(endWeek))
+ {
+ Interval periodProbe = Interval(endWeek)
+ .firstWeek(weekStartsMonday);
+ double loadProbe = tci->tli->task->getLoad(tci->tli->sc,
+ periodProbe,
+ tci->tli->resource);
+ QColor bgColProbe = selectTaskBgColor(tci, loadProbe,
+ periodProbe, false);
+ if (load != loadProbe || bgCol != bgColProbe)
+ break;
+ lastEndWeek = endWeek;
+ runLength++;
+ }
+ week = lastEndWeek;
+ }
+ tci->setColumns(runLength);
+ tci->setBgColor(bgCol);
+
+ reportTaskLoad(load, tci, period);
+ }
+}
- const Entity* ent = entitylist;
- while(ent->code)
- {
- HtmlMap->insert(ent->code, ent->name);
- ent++;
- }
+void
+HTMLReportElement::genCellWeeklyResource(TableCellInfo* tci)
+{
+ bool weekStartsMonday = report->getWeekStartsMonday();
+ for (time_t week = beginOfWeek(start, weekStartsMonday); week < end;
+ week = sameTimeNextWeek(week))
+ {
+ Interval period = Interval(week, sameTimeNextWeek(week) - 1);
+ double load = tci->tli->resource->getEffectiveLoad
+ (tci->tli->sc, period, AllAccounts, tci->tli->task);
+ QColor bgCol = selectResourceBgColor(tci, load, period, false);
+
+ int runLength = 1;
+ if (load == 0.0)
+ {
+ time_t lastEndWeek = week;
+ for (time_t endWeek = sameTimeNextWeek(week); endWeek < end;
+ endWeek = sameTimeNextWeek(endWeek))
+ {
+ Interval periodProbe = Interval(endWeek)
+ .firstWeek(weekStartsMonday);
+ double loadProbe = tci->tli->resource->getEffectiveLoad
+ (tci->tli->sc, periodProbe, AllAccounts, tci->tli->task);
+ QColor bgColProbe = selectResourceBgColor(tci, loadProbe,
+ periodProbe, false);
+ if (load != loadProbe || bgCol != bgColProbe)
+ break;
+ lastEndWeek = endWeek;
+ runLength++;
+ }
+ week = lastEndWeek;
+ }
+ tci->setColumns(runLength);
+ tci->setBgColor(bgCol);
+
+ reportResourceLoad(load, tci, period);
}
-
- QString out;
- bool parTags = FALSE;
- for (uint i = 0; i < s.length(); i++)
- {
- QString repl;
- if (HtmlMap->find(s[i]) != HtmlMap->end())
- repl = QString("&") + QString(*(HtmlMap->find(s[i]))) + ";";
- else if (s.mid(i, 2) == "\n\n")
- {
- repl = "</p><p>";
- parTags = TRUE;
- i++;
- }
-
- if (repl.isEmpty())
- out += s[i];
- else
- out += repl;
- }
+}
- return parTags ? QString("<p>") + out + "</p>" : out;
+void
+HTMLReportElement::genCellWeeklyAccount(TableCellInfo* tci)
+{
+ bool weekStartsMonday = report->getWeekStartsMonday();
+ for (time_t week = beginOfWeek(start, weekStartsMonday); week < end;
+ week = sameTimeNextWeek(week))
+ {
+ double volume = tci->tli->account->
+ getVolume(tci->tli->sc, Interval(week, sameTimeNextWeek(week) - 1));
+ if ((accountSortCriteria[0] == CoreAttributesList::TreeMode &&
+ tci->tli->account->isRoot()) ||
+ (accountSortCriteria[0] != CoreAttributesList::TreeMode))
+ tci->tci->addToSum(tci->tli->sc, time2ISO(week), volume);
+ reportCurrency(volume, tci, week);
+ }
}
void
-HTMLReportElement::reportLoad(double load, const QString& bgCol, bool bold)
+HTMLReportElement::genCellMonthlyTask(TableCellInfo* tci)
{
- if (load > 0.0 && barLabels != BLT_EMPTY)
- {
- s << "<td class=\""
- << bgCol << "\">";
- if (bold)
- s << "<b>";
- s << scaledLoad(load);
- if (bold)
- s << "</b>";
- s << "</td>" << endl;
- }
- else
- s << "<td class=\""
- << bgCol << "\"> </td>" << endl;
+ genCellTaskFunc(tci, false, beginOfMonth, sameTimeNextMonth);
}
void
-HTMLReportElement::reportPIDs(const QString& pids, const QString bgCol, bool bold)
+HTMLReportElement::genCellMonthlyResource(TableCellInfo* tci)
{
- s << "<td class=\""
- << bgCol << "\" style=\"white-space:nowrap\">";
- if (bold)
- s << "<b>";
- s << pids;
- if (bold)
- s << "</b>";
- s << "</td>" << endl;
+ genCellResourceFunc(tci, false, beginOfMonth, sameTimeNextMonth);
}
-bool
-HTMLReportElement::setUrl(const QString& key, const QString& url)
+void
+HTMLReportElement::genCellMonthlyAccount(TableCellInfo* tci)
{
- if (urls.find(key) == urls.end())
- return FALSE;
+ genCellAccountFunc(tci, beginOfMonth, sameTimeNextMonth);
+}
- urls[key] = url;
- return TRUE;
+void
+HTMLReportElement::genCellQuarterlyTask(TableCellInfo* tci)
+{
+ genCellTaskFunc(tci, false, beginOfQuarter, sameTimeNextQuarter);
}
-const QString*
-HTMLReportElement::getUrl(const QString& key) const
+void
+HTMLReportElement::genCellQuarterlyResource(TableCellInfo* tci)
{
- if (urls.find(key) == urls.end() || urls[key] == "")
- return 0;
- return &urls[key];
+ genCellResourceFunc(tci, false, beginOfQuarter, sameTimeNextQuarter);
}
-QString
-HTMLReportElement::generateUrl(const QString& key, const QString& txt)
+void
+HTMLReportElement::genCellQuarterlyAccount(TableCellInfo* tci)
{
- if (getUrl(key))
- {
- mt.setLocation(defFileName, defFileLine);
- return QString("<a href=\"") + mt.expand(*getUrl(key))
- + "\">" + htmlFilter(txt) + "</a>";
- }
- else
- return htmlFilter(txt);
+ genCellAccountFunc(tci, beginOfQuarter, sameTimeNextQuarter);
+}
+
+void
+HTMLReportElement::genCellYearlyTask(TableCellInfo* tci)
+{
+ genCellTaskFunc(tci, false, beginOfYear, sameTimeNextYear);
+}
+
+void
+HTMLReportElement::genCellYearlyResource(TableCellInfo* tci)
+{
+ genCellResourceFunc(tci, false, beginOfYear, sameTimeNextYear);
+}
+
+void
+HTMLReportElement::genCellYearlyAccount(TableCellInfo* tci)
+{
+ genCellAccountFunc(tci, beginOfYear, sameTimeNextYear);
+}
+
+void
+HTMLReportElement::genCellResponsibilities(TableCellInfo* tci)
+{
+ QString text;
+ for (TaskListIterator it(report->getProject()->getTaskListIterator());
+ *it != 0; ++it)
+ {
+ if ((*it)->getResponsible() == tci->tli->resource)
+ {
+ if (!text.isEmpty())
+ text += ", ";
+ text += (*it)->getId();
+ }
+ }
+ genCell(text, tci, true);
+}
+
+void
+HTMLReportElement::genCellScheduling(TableCellInfo* tci)
+{
+ genCell(tci->tli->task->getSchedulingText(), tci, true);
+}
+
+void
+HTMLReportElement::genCellSchedule(TableCellInfo* tci)
+{
+ s() << " <td>" << endl;
+
+ if (tci->tli->resource)
+ {
+ BookingList jobs = tci->tli->resource->getJobs(tci->tli->sc);
+ jobs.setAutoDelete(true);
+ time_t prevTime = 0;
+ Interval reportPeriod(start, end);
+ s() << " <table style=\"width:150px; font-size:100%; "
+ << "text-align:left\">" << endl
+ << " <tr>" << endl
+ << " <th style=\"width:35%\"></th>" << endl
+ << " <th style=\"width:65%\"></th>" << endl
+ << " </tr>" << endl;
+ for (BookingList::Iterator bli(jobs); *bli != 0; ++bli)
+ {
+ if ((tci->tli->ca2 == 0 || tci->tli->task == (*bli)->getTask()) &&
+ reportPeriod.overlaps(Interval((*bli)->getStart(),
+ (*bli)->getEnd())))
+ {
+ /* If the reporting interval is not more than a day, we
+ * do not print the day since this information is most
+ * likely given by the context of the report. */
+ if (!isSameDay(prevTime, (*bli)->getStart()) &&
+ !isSameDay(start, end - 1))
+ {
+ s() << " <tr>" << endl
+ << " <td colspan=\"2\" style=\"font-size:120%\">"
+ << time2weekday((*bli)->getStart()) << ", "
+ << time2date((*bli)->getStart()) << "</td>" << endl
+ << " </tr>"
+ << endl;
+ }
+ s() << " <tr>" << endl
+ << " <td>";
+ Interval workPeriod((*bli)->getStart(), (*bli)->getEnd());
+ workPeriod.overlap(reportPeriod);
+ s() << time2user(workPeriod.getStart(), shortTimeFormat)
+ << " - "
+ << time2user(workPeriod.getEnd() + 1, shortTimeFormat);
+ s() << "</td>" << endl
+ << " <td>";
+ if (tci->tli->ca2 == 0)
+ s() << " " << htmlFilter((*bli)->getTask()->getName());
+ s() << " </td>" << endl;
+ prevTime = (*bli)->getStart();
+ s() << " </tr>" << endl;
+ }
+ }
+ s() << " </table>" << endl;
+ }
+ else
+ s() << " ";
+
+ s() << " </td>" << endl;
+}
+
+#define GCEFFORT(a) \
+void \
+HTMLReportElement::genCell##a##Effort(TableCellInfo* tci) \
+{ \
+ genCell(tci->tcf->realFormat.format \
+ (tci->tli->resource->get##a##Effort(), false), \
+ tci, true); \
+}
+
+GCEFFORT(Min)
+
+void
+HTMLReportElement::genCellMaxEffort(TableCellInfo* tci)
+{
+ genCell(tci->tcf->realFormat.format
+ (tci->tli->resource->getLimits() ?
+ tci->tli->resource->getLimits()->getDailyMax() : 0, false),
+ tci, true);
+}
+
+void
+HTMLReportElement::genCellEfficiency(TableCellInfo* tci)
+{
+ genCell(tci->tcf->realFormat.format(tci->tli->resource->getEfficiency(),
+ tci), tci, true);
+}
+
+void
+HTMLReportElement::genCellRate(TableCellInfo* tci)
+{
+ genCell(tci->tcf->realFormat.format(tci->tli->resource->getRate(), tci),
+ tci, true);
+}
+
+void
+HTMLReportElement::genCellTotal(TableCellInfo* tci)
+{
+ double value = tci->tli->account->getVolume(tci->tli->sc,
+ Interval(start, end));
+ if (tci->tli->account->isLeaf())
+ tci->tci->addToSum(tci->tli->sc, "total", value);
+ genCell(tci->tcf->realFormat.format(value, tci), tci, false);
+}
+
+void
+HTMLReportElement::genCellSummary(TableCellInfo* tci)
+{
+ QMap<QString, double>::ConstIterator it;
+ const QMap<QString, double>* sum = tci->tci->getSum();
+ assert(sum != 0);
+
+ uint sc = tci->tli->sc;
+ double val = 0.0;
+ if (sum[sc].begin() != sum[sc].end())
+ {
+ for (it = sum[sc].begin(); it != sum[sc].end(); ++it)
+ {
+ if (accumulate)
+ val += *it;
+ else
+ val = *it;
+ genCell(tci->tcf->realFormat.format(val, tci), tci, false);
+ }
+ }
+ else
+ {
+ // The column counter is not set in all cases. These are always single
+ // column cases.
+ if (tci->tci->getSubColumns() > 0)
+ for (uint col = 0; col < tci->tci->getSubColumns(); ++col)
+ genCell(tci->tcf->realFormat.format(0.0, tci), tci, false);
+ else
+ genCell(tci->tcf->realFormat.format(0.0, tci), tci, false);
+ }
}