2 * HTMLReportElement.cpp - TaskJuggler
4 * Copyright (c) 2001, 2002, 2003, 2004, 2005 by Chris Schlaeger <cs@kde.org>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of version 2 of the GNU General Public License as
8 * published by the Free Software Foundation.
13 #include "HTMLReportElement.h"
17 #include "TjMessageHandler.h"
18 #include "tjlib-internal.h"
22 #include "BookingList.h"
24 #include "MacroTable.h"
25 #include "TableLineInfo.h"
26 #include "TableCellInfo.h"
27 #include "ReferenceAttribute.h"
28 #include "TextAttribute.h"
29 #include "HTMLReport.h"
30 #include "UsageLimits.h"
32 HTMLReportElement::HTMLReportElement(Report* r, const QString& df, int dl) :
33 ReportElement(r, df, dl),
39 HTMLReportElement::generateHeader()
41 if (!rawHead.isEmpty())
46 if (!headline.isEmpty())
49 puts(htmlFilter(headline));
52 if (!caption.isEmpty())
55 puts(htmlFilter(caption));
61 HTMLReportElement::generateFooter()
63 if (!rawTail.isEmpty())
71 HTMLReportElement::generateTableHeader()
74 s() << "<table align=\"center\" cellpadding=\"2\" "
75 << "style=\"background-color:#000000\"";
76 if (static_cast<HTMLReport*>(report)->hasStyleSheet())
77 s() << " class=\"tj_table\"";
79 s() << " <thead>" << endl
80 << " <tr valign=\"middle\""
81 << " style=\"background-color:" << colors.getColorName("header") << "; "
82 << "font-size:110%; font-weight:bold; text-align:center\"";
83 if (static_cast<HTMLReport*>(report)->hasStyleSheet())
84 s() << " class=\"tj_header_row\"";
86 for (QPtrListIterator<TableColumnInfo> it(columns); it; ++it )
88 if (columnFormat[(*it)->getName()])
90 TableCellInfo tci(columnFormat[(*it)->getName()], 0, *it);
91 (*this.*(columnFormat[(*it)->getName()]->genHeadLine1))
94 else if ((*it)->getName() == "costs")
97 (i18n("'costs' has been deprecated. Use 'cost' instead."));
103 (i18n("Unknown Column '%1' for HTML Report")
104 .arg((*it)->getName()));
108 s() << " </tr>" << endl;
112 for (QPtrListIterator<TableColumnInfo> it(columns); it; ++it )
114 if (columnFormat[(*it)->getName()])
115 if (columnFormat[(*it)->getName()]->genHeadLine2)
120 if (static_cast<HTMLReport*>(report)->hasStyleSheet())
121 s() << " class=\"tj_header_row\"";
126 TableCellInfo tci(columnFormat[(*it)->getName()], 0, *it);
127 (*this.*(columnFormat[(*it)->getName()]->genHeadLine2))
132 s() << " </tr>" << endl;
134 s() << " </thead>\n" << endl;
138 HTMLReportElement::generateLine(TableLineInfo* tli, int funcSel)
142 puts(" <tr valign=\"middle\"");
143 if (tli->bgCol.isValid() || tli->boldText || tli->fontFactor != 100)
146 if (tli->bgCol.isValid())
148 puts("background-color:");
149 puts(tli->bgCol.name());
153 puts("font-weight:bold; ");
154 if (tli->fontFactor != 100)
157 puts(QString("%1").arg(tli->fontFactor));
162 if (static_cast<HTMLReport*>(report)->hasStyleSheet())
163 puts(" class=\"tj_row\"");
166 for (QPtrListIterator<TableColumnInfo> it(columns); it; ++it )
168 TableCellInfo tci(columnFormat[(*it)->getName()], tli, *it);
169 if (columnFormat[(*it)->getName()])
175 gcf = columnFormat[(*it)->getName()]->genHeadLine1;
178 gcf = columnFormat[(*it)->getName()]->genHeadLine2;
181 gcf = columnFormat[(*it)->getName()]->genTaskLine1;
184 gcf = columnFormat[(*it)->getName()]->genTaskLine2;
187 gcf = columnFormat[(*it)->getName()]->genResourceLine1;
190 gcf = columnFormat[(*it)->getName()]->genResourceLine2;
193 gcf = columnFormat[(*it)->getName()]->genAccountLine1;
196 gcf = columnFormat[(*it)->getName()]->genAccountLine2;
199 gcf = columnFormat[(*it)->getName()]->genSummaryLine1;
202 gcf = columnFormat[(*it)->getName()]->genSummaryLine2;
205 qFatal("Unknown function selector: %d", funcSel);
209 (*this.*(gcf))(&tci);
217 HTMLReportElement::genCell(const QString& text, TableCellInfo* tci,
218 bool multi, bool filter)
221 tci->setFontFactor(90);
224 if (tci->tcf->noWrap)
225 puts(" nowrap=\"nowrap\"");
226 if (tci->getRows() != 1 || (multi && scenarios.count() > 1))
227 puts(" rowspan=\"" + QString("%1")
228 .arg(tci->getRows() != 1 ?
229 tci->getRows() : scenarios.count()) + "\"");
230 if (tci->getColumns() != 1)
233 puts(QString("%1").arg(tci->getColumns()));
236 if (!tci->getStatusText().isEmpty())
238 puts(" onmouseover=\"status='");
239 puts(tci->getStatusText());
240 puts("';return true;\"");
242 if (tci->tcf->hAlign != TableColumnFormat::center ||
243 !tci->getHAlign().isEmpty() ||
244 tci->getLeftPadding() > 0 ||
245 tci->getRightPadding() > 0 ||
246 tci->getBgColor().isValid() ||
247 tci->getFontFactor() != 100 ||
248 tci->getBoldText() ||
249 tci->tcf->fontFactor != 100)
252 if (tci->getBgColor().isValid())
254 puts("background-color:");
256 tci->getBgColor().rgb(&r, &g, &b);
258 sprintf(buf, "#%02x%02x%02x; ", r, g, b);
261 if (!tci->getHAlign().isEmpty())
264 puts(tci->getHAlign());
267 else if (tci->tcf->hAlign != TableColumnFormat::center)
270 switch(tci->tcf->hAlign)
272 case TableColumnFormat::center:
275 case TableColumnFormat::left:
278 case TableColumnFormat::right:
284 if (tci->getLeftPadding() > 0)
286 puts("padding-left:");
287 puts(QString("%1").arg(tci->getLeftPadding()));
290 if (tci->getRightPadding() > 0)
292 puts("padding-right:");
293 puts(QString("%1").arg(tci->getRightPadding()));
296 if (tci->getBoldText())
297 puts("font-weight:bold; ");
298 if (tci->getFontFactor() != 100 || tci->tcf->fontFactor != 100)
301 puts(QString("%1").arg(tci->getFontFactor() *
302 tci->tcf->fontFactor / 100));
308 if (tci->tli->ca1 == 0 ||
309 !isHidden(tci->tli->ca1, tci->tci->getHideCellText()))
311 cellText = filter ? htmlFilter(text) : text;
312 if (tci->tli->ca1 && !tci->tci->getCellText().isEmpty())
314 QStringList sl(text);
315 cellText = mt.expandReportVariable(tci->tci->getCellText(), &sl);
318 if (!tci->tci->getCellURL().isEmpty() && (tci->tli->ca1 == 0 ||
319 !isHidden(tci->tli->ca1, tci->tci->getHideCellURL())))
321 QStringList sl(text);
322 QString cellURL = mt.expandReportVariable(tci->tci->getCellURL(), &sl);
323 if (!cellURL.isEmpty())
325 cellText = QString("<a href=\"") + cellURL
326 + "\">" + cellText + "</a>";
329 if (cellText.isEmpty())
331 if (static_cast<HTMLReport*>(report)->hasStyleSheet())
332 puts(" class=\"tj_cell\"");
334 if (!tci->getToolTipText().isEmpty())
337 puts(tci->getToolTipID());
338 puts("\" class=\"tj_tooltip\" style=\"visibility:hidden\">");
339 puts(tci->getToolTipText());
348 HTMLReportElement::reportTaskLoad(double load, TableCellInfo* tci,
349 const Interval& period)
352 if (tci->tli->task->isActive(tci->tli->sc, period))
354 if (tci->tli->task->isContainer())
357 if (period.contains(tci->tli->task->getStart(tci->tli->sc)))
359 if (period.contains(tci->tli->task->getEnd(tci->tli->sc)))
361 if (load > 0.0 && barLabels != BLT_EMPTY)
362 text = scaledLoad(load, tci->tcf->realFormat);
363 else if (pre.isEmpty() && post.isEmpty())
365 else if (!pre.isEmpty() && !post.isEmpty())
370 text = pre + text + post;
371 tci->setBoldText(true);
375 if (tci->tli->task->isMilestone())
378 tci->setBoldText(true);
383 if (period.contains(tci->tli->task->
384 getStart(tci->tli->sc)))
386 if (period.contains(tci->tli->task->
387 getEnd(tci->tli->sc)))
389 if (!pre.isEmpty() && !post.isEmpty())
394 if (load > 0.0 && barLabels != BLT_EMPTY)
395 text = scaledLoad(load, tci->tcf->realFormat);
396 else if (pre.isEmpty() && post.isEmpty())
400 text = pre + text + post;
403 tci->setHAlign("center");
404 tci->setStatusText(time2user(period.getStart(), "%Y-%m-%d / [") +
405 tci->tli->task->getId() + "] " +
406 htmlFilter(tci->tli->task->getName()));
410 tci->setStatusText("");
412 genCell(text, tci, false);
416 HTMLReportElement::reportResourceLoad(double load, TableCellInfo* tci,
417 const Interval& period)
422 if (barLabels != BLT_EMPTY)
423 text += scaledLoad(load, tci->tcf->realFormat);
424 if (tci->tli->resource->hasSubs())
425 tci->setBoldText(true);
426 tci->setHAlign("center");
427 tci->setStatusText(time2user(period.getStart(), "%Y-%m-%d / [") +
428 tci->tli->resource->getId() + "] " +
429 htmlFilter(tci->tli->resource->getName()));
433 tci->setStatusText("");
435 genCell(text, tci, false);
439 HTMLReportElement::reportCurrency(double value, TableCellInfo* tci,
442 tci->setStatusText(time2user(iv_start, "%Y-%m-%d / [") +
443 tci->tli->account->getId() + "] " +
444 htmlFilter(tci->tli->account->getName()));
445 genCell(tci->tcf->realFormat.format(value, tci), tci, false);
449 HTMLReportElement::generateTitle(TableCellInfo* tci, const QString& str)
453 if (!tci->tci->getTitle().isEmpty())
454 cellText = mt.expandReportVariable(tci->tci->getTitle(), &sl);
457 cellText = htmlFilter(cellText);
458 QString cellURL = mt.expandReportVariable(tci->tci->getTitleURL(), &sl);
459 if (!cellURL.isEmpty())
460 cellText = QString("<a href=\"") + cellURL
461 + "\">" + cellText + "</a>";
467 HTMLReportElement::generateSubTitle(TableCellInfo* tci, const QString& str)
471 if (!tci->tci->getSubTitle().isEmpty())
472 cellText = mt.expandReportVariable(tci->tci->getSubTitle(), &sl);
475 cellText = htmlFilter(cellText);
476 QString cellURL = mt.expandReportVariable(tci->tci->getSubTitleURL(), &sl);
477 if (!cellURL.isEmpty())
478 cellText = QString("<a href=\"") + cellURL
479 + "\">" + cellText + "</a>";
483 tci->tci->increaseSubColumns();
487 HTMLReportElement::generateRightIndented(TableCellInfo* tci, const QString& str)
489 int topIndent = 0, subIndent = 0, maxDepth = 0;
490 if (tci->tli->ca1->getType() == CA_Task)
492 if (taskSortCriteria[0] == CoreAttributesList::TreeMode)
493 subIndent = tci->tli->ca2 == 0 ? 8 : 5;
494 if (resourceSortCriteria[0] == CoreAttributesList::TreeMode)
495 topIndent = (tci->tli->ca2 != 0 ? 0 : 5) * maxDepthResourceList;
496 maxDepth = maxDepthTaskList;
498 else if (tci->tli->ca1->getType() == CA_Resource)
500 if (resourceSortCriteria[0] == CoreAttributesList::TreeMode)
501 subIndent = tci->tli->ca2 == 0 ? 8 : 5;
502 if (taskSortCriteria[0] == CoreAttributesList::TreeMode)
503 topIndent = (tci->tli->ca2 != 0 ? 0 : 5) * maxDepthTaskList;
504 maxDepth = maxDepthResourceList;
507 tci->setRightPadding(2 + topIndent +
508 (maxDepth - 1 - tci->tli->ca1->treeLevel()) *
510 genCell(str, tci, false);
514 HTMLReportElement::genHeadDefault(TableCellInfo* tci)
516 puts(" <td rowspan=\"2\"");
517 if (static_cast<HTMLReport*>(report)->hasStyleSheet())
518 puts(" class=\"tj_header_cell\"");
520 generateTitle(tci, tci->tcf->getTitle());
525 HTMLReportElement::genHeadCurrency(TableCellInfo* tci)
527 puts(" <td rowspan=\"2\"");
528 if (static_cast<HTMLReport*>(report)->hasStyleSheet())
529 puts(" class=\"tj_header_cell\"");
531 generateTitle(tci, tci->tcf->getTitle() +
532 (!report->getProject()->getCurrency().isEmpty() ?
533 QString(" ") + report->getProject()->getCurrency() :
539 HTMLReportElement::genHeadDaily1(TableCellInfo* tci)
541 // Generates the 1st header line for daily calendar views.
542 bool weekStartsMonday = report->getWeekStartsMonday();
543 for (time_t day = midnight(start); day < end;
544 day = sameTimeNextMonth(beginOfMonth(day)))
546 int left = daysLeftInMonth(day);
547 if (left > daysBetween(day, end))
548 left = daysBetween(day, end);
549 s() << " <td colspan=\""
550 << QString().sprintf("%d", left) << "\"";
551 if (static_cast<HTMLReport*>(report)->hasStyleSheet())
552 s() << " class=\"tj_header_cell\"";
554 mt.setMacro(new Macro(KW("day"), "01",
555 defFileName, defFileLine));
556 mt.setMacro(new Macro(KW("month"),
557 QString().sprintf("%02d", monthOfYear(day)),
558 defFileName, defFileLine));
559 mt.setMacro(new Macro(KW("quarter"),
561 ("%02d", quarterOfYear(day)),
562 defFileName, defFileLine));
563 mt.setMacro(new Macro(KW("week"),
565 ("%02d", weekOfYear(day, weekStartsMonday)),
566 defFileName, defFileLine));
567 mt.setMacro(new Macro(KW("year"),
568 QString().sprintf("%04d", year(day)),
569 defFileName, defFileLine));
570 generateTitle(tci, monthAndYear(day));
571 s() << "</td>" << endl;
576 HTMLReportElement::genHeadDaily2(TableCellInfo* tci)
578 // Generates the 2nd header line for daily calendar views.
579 bool weekStartsMonday = report->getWeekStartsMonday();
580 for (time_t day = midnight(start); day < end; day = sameTimeNextDay(day))
582 int dom = dayOfMonth(day);
583 s() << " <td style=\"";
584 QColor bgCol = colors.getColor("header");
586 bgCol = bgCol.dark(130);
587 if (isSameDay(report->getProject()->getNow(), day))
588 bgCol = colors.getColor("today");
589 s() << "background-color:" << bgCol.name() << "; "
590 << "font-size:80%; text-align:center\"";
591 if (static_cast<HTMLReport*>(report)->hasStyleSheet())
592 s() << " class=\"tj_header_cell\"";
594 mt.setMacro(new Macro(KW("day"), QString().sprintf("%02d", dom),
595 defFileName, defFileLine));
596 mt.setMacro(new Macro(KW("month"),
597 QString().sprintf("%02d", monthOfYear(day)),
598 defFileName, defFileLine));
599 mt.setMacro(new Macro(KW("quarter"),
601 ("%02d", quarterOfYear(day)),
602 defFileName, defFileLine));
603 mt.setMacro(new Macro(KW("week"),
605 ("%02d", weekOfYear(day, weekStartsMonday)),
606 defFileName, defFileLine));
607 mt.setMacro(new Macro(KW("year"),
608 QString().sprintf("%04d", year(day)),
609 defFileName, defFileLine));
612 generateSubTitle(tci, QString().sprintf("%d", dom));
613 s() << "</td>" << endl;
618 HTMLReportElement::genHeadWeekly1(TableCellInfo* tci)
620 // Generates the 1st header line for weekly calendar views.
621 bool weekStartsMonday = report->getWeekStartsMonday();
622 for (time_t week = beginOfWeek(start, weekStartsMonday); week < end; )
624 int currMonth = monthOfWeek(week, weekStartsMonday);
626 time_t wi = sameTimeNextWeek(week);
627 for (left = 1 ; wi < end &&
628 monthOfWeek(wi, weekStartsMonday) == currMonth;
629 wi = sameTimeNextWeek(wi))
632 s() << " <td colspan=\""
633 << QString().sprintf("%d", left) << "\"";
634 if (static_cast<HTMLReport*>(report)->hasStyleSheet())
635 s() << " class=\"tj_header_cell\"";
637 mt.setMacro(new Macro(KW("day"), QString().sprintf
638 ("%02d", dayOfMonth(week)),
639 defFileName, defFileLine));
640 mt.setMacro(new Macro(KW("month"),
642 ("%02d", monthOfWeek(week, weekStartsMonday)),
643 defFileName, defFileLine));
644 mt.setMacro(new Macro(KW("quarter"),
646 ("%02d", quarterOfYear(week)),
647 defFileName, defFileLine));
648 mt.setMacro(new Macro(KW("week"),
650 ("%02d", weekOfYear(week, weekStartsMonday)),
651 defFileName, defFileLine));
652 mt.setMacro(new Macro(KW("year"),
654 ("%04d", yearOfWeek(week, weekStartsMonday)),
655 defFileName, defFileLine));
657 QString("%1 %2").arg(shortMonthName(monthOfWeek(week,
660 arg(yearOfWeek(week, weekStartsMonday)));
661 s() << "</td>" << endl;
667 HTMLReportElement::genHeadWeekly2(TableCellInfo* tci)
669 // Generates the 2nd header line for weekly calendar views.
670 bool wsm = report->getWeekStartsMonday();
671 for (time_t week = beginOfWeek(start, wsm); week < end;
672 week = sameTimeNextWeek(week))
674 int woy = weekOfYear(week, wsm);
675 s() << " <td style=\"";
677 if (isSameWeek(report->getProject()->getNow(), week, wsm))
678 bgCol = colors.getColor("today");
680 bgCol = colors.getColor("header");
681 s() << "background-color:" << bgCol.name() << "; "
682 << "font-size:80%; text-align:center\"";
683 if (static_cast<HTMLReport*>(report)->hasStyleSheet())
684 s() << " class=\"tj_header_cell\"";
688 mt.setMacro(new Macro(KW("day"), QString().sprintf
689 ("%02d", dayOfMonth(week)),
690 defFileName, defFileLine));
691 mt.setMacro(new Macro(KW("month"),
692 QString().sprintf("%02d",
693 monthOfWeek(week, wsm)),
694 defFileName, defFileLine));
695 mt.setMacro(new Macro(KW("quarter"),
697 ("%02d", quarterOfYear(week)),
698 defFileName, defFileLine));
699 mt.setMacro(new Macro(KW("week"),
700 QString().sprintf("%02d", woy),
701 defFileName, defFileLine));
702 mt.setMacro(new Macro(KW("year"),
703 QString().sprintf("%04d", yearOfWeek(week, wsm)),
704 defFileName, defFileLine));
705 generateSubTitle(tci, QString().sprintf("%d", woy));
706 s() << "</td>" << endl;
711 HTMLReportElement::genHeadMonthly1(TableCellInfo* tci)
713 // Generates 1st header line of monthly calendar view.
714 for (time_t year = beginOfMonth(start); year < end;
715 year = sameTimeNextYear(beginOfYear(year)))
717 int left = monthLeftInYear(year);
718 if (left > monthsBetween(year, end))
719 left = monthsBetween(year, end);
720 s() << " <td colspan=\""
721 << QString().sprintf("%d", left) << "\"";
722 if (static_cast<HTMLReport*>(report)->hasStyleSheet())
723 s() << " class=\"tj_header_cell\"";
725 mt.setMacro(new Macro(KW("day"), "01",
726 defFileName, defFileLine));
727 mt.setMacro(new Macro(KW("month"), "01",
728 defFileName, defFileLine));
729 mt.setMacro(new Macro(KW("quarter"), "1",
730 defFileName, defFileLine));
731 mt.setMacro(new Macro(KW("week"), "01",
732 defFileName, defFileLine));
733 mt.setMacro(new Macro(KW("year"),
734 QString().sprintf("%04d", ::year(year)),
735 defFileName, defFileLine));
736 generateTitle(tci, QString().sprintf("%d", ::year(year)));
737 s() << "</td>" << endl;
742 HTMLReportElement::genHeadMonthly2(TableCellInfo* tci)
744 // Generates 2nd header line of monthly calendar view.
745 bool weekStartsMonday = report->getWeekStartsMonday();
746 for (time_t month = beginOfMonth(start); month < end;
747 month = sameTimeNextMonth(month))
749 int moy = monthOfYear(month);
750 s() << " <td style=\"";
752 if (isSameMonth(report->getProject()->getNow(), month))
753 bgCol = colors.getColor("today");
755 bgCol = colors.getColor("header");
756 s() << "background-color:" << bgCol.name() << "; "
757 << "font-size:80%; text-align:center\"";
758 if (static_cast<HTMLReport*>(report)->hasStyleSheet())
759 s() << " class=\"tj_header_cell\"";
763 mt.setMacro(new Macro(KW("day"), "01",
764 defFileName, defFileLine));
765 mt.setMacro(new Macro(KW("month"),
766 QString().sprintf("%02d", moy),
767 defFileName, defFileLine));
768 mt.setMacro(new Macro(KW("quarter"),
770 ("%02d", quarterOfYear(month)),
771 defFileName, defFileLine));
772 mt.setMacro(new Macro(KW("week"),
774 ("%02d", weekOfYear(month, weekStartsMonday)),
775 defFileName, defFileLine));
776 mt.setMacro(new Macro(KW("year"),
777 QString().sprintf("%04d", year(month)),
778 defFileName, defFileLine));
779 generateSubTitle(tci, shortMonthName(moy - 1));
780 s() << "</td>" << endl;
785 HTMLReportElement::genHeadQuarterly1(TableCellInfo* tci)
787 // Generates 1st header line of quarterly calendar view.
788 for (time_t year = beginOfQuarter(start); year < end;
789 year = sameTimeNextYear(beginOfYear(year)))
791 int left = quartersLeftInYear(year);
792 if (left > quartersBetween(year, end))
793 left = quartersBetween(year, end);
794 s() << " <td colspan=\""
795 << QString().sprintf("%d", left) << "\"";
796 if (static_cast<HTMLReport*>(report)->hasStyleSheet())
797 s() << " class=\"tj_header_cell\"";
799 mt.setMacro(new Macro(KW("day"), "01",
800 defFileName, defFileLine));
801 mt.setMacro(new Macro(KW("month"), "01",
802 defFileName, defFileLine));
803 mt.setMacro(new Macro(KW("quarter"), "1",
804 defFileName, defFileLine));
805 mt.setMacro(new Macro(KW("week"), "01",
806 defFileName, defFileLine));
807 mt.setMacro(new Macro(KW("year"),
808 QString().sprintf("%04d", ::year(year)),
809 defFileName, defFileLine));
810 generateTitle(tci, QString().sprintf("%d", ::year(year)));
811 s() << "</td>" << endl;
816 HTMLReportElement::genHeadQuarterly2(TableCellInfo* tci)
818 // Generates 2nd header line of quarterly calendar view.
819 static const char* qnames[] =
821 I18N_NOOP("1st Quarter"), I18N_NOOP("2nd Quarter"),
822 I18N_NOOP("3rd Quarter"), I18N_NOOP("4th Quarter")
825 bool weekStartsMonday = report->getWeekStartsMonday();
826 for (time_t quarter = beginOfQuarter(start); quarter < end;
827 quarter = sameTimeNextQuarter(quarter))
829 int qoy = quarterOfYear(quarter);
830 s() << " <td style=\"";
832 if (isSameQuarter(report->getProject()->getNow(), quarter))
833 bgCol = colors.getColor("today");
835 bgCol = colors.getColor("header");
836 s() << "background-color:" << bgCol.name() << "; "
837 << "font-size:80%; text-align:center\"";
838 if (static_cast<HTMLReport*>(report)->hasStyleSheet())
839 s() << " class=\"tj_header_cell\"";
841 mt.setMacro(new Macro(KW("day"), QString().sprintf("%02d",
842 dayOfMonth(quarter)),
843 defFileName, defFileLine));
844 mt.setMacro(new Macro(KW("month"),
845 QString().sprintf("%02d", monthOfYear(quarter)),
846 defFileName, defFileLine));
847 mt.setMacro(new Macro(KW("quarter"),
848 QString().sprintf("%d", qoy),
849 defFileName, defFileLine));
850 mt.setMacro(new Macro(KW("week"),
852 ("%02d", weekOfYear(quarter, weekStartsMonday)),
853 defFileName, defFileLine));
854 mt.setMacro(new Macro(KW("year"),
855 QString().sprintf("%04d", year(quarter)),
856 defFileName, defFileLine));
857 generateSubTitle(tci, i18n(qnames[qoy - 1]));
858 s() << "</td>" << endl;
863 HTMLReportElement::genHeadYear(TableCellInfo* tci)
865 // Generates 1st header line of monthly calendar view.
866 for (time_t year = beginOfYear(start); year < end;
867 year = sameTimeNextYear(year))
869 s() << " <td rowspan=\"2\"";
870 if (static_cast<HTMLReport*>(report)->hasStyleSheet())
871 s() << " class=\"tj_header_cell\"";
873 mt.setMacro(new Macro(KW("day"), QString().sprintf("%02d",
875 defFileName, defFileLine));
876 mt.setMacro(new Macro(KW("month"),
877 QString().sprintf("%02d", monthOfYear(year)),
878 defFileName, defFileLine));
879 mt.setMacro(new Macro(KW("quarter"), "1",
880 defFileName, defFileLine));
881 mt.setMacro(new Macro(KW("week"), "01",
882 defFileName, defFileLine));
883 mt.setMacro(new Macro(KW("year"),
884 QString().sprintf("%04d", ::year(year)),
885 defFileName, defFileLine));
886 generateTitle(tci, QString().sprintf("%d", ::year(year)));
887 s() << "</td>" << endl;
892 HTMLReportElement::genCellEmpty(TableCellInfo* tci)
894 genCell("", tci, true);
898 HTMLReportElement::genCellAccounts(TableCellInfo* tci)
900 genCell(QString().sprintf("%s", tci->tli->task->getAccount() ?
901 tci->tli->task->getAccount()->getId().latin1() :
906 HTMLReportElement::genCellSequenceNo(TableCellInfo* tci)
908 genCell(tci->tli->ca2 == 0 ?
909 QString().sprintf("%d.", tci->tli->ca1->getSequenceNo()) :
910 QString::null, tci, true);
914 HTMLReportElement::genCellNo(TableCellInfo* tci)
916 genCell(tci->tli->ca2 == 0 ? QString().sprintf("%d.", tci->tli->idxNo) :
917 QString::null, tci, true);
921 HTMLReportElement::genCellHierarchNo(TableCellInfo* tci)
923 genCell(tci->tli->ca2 == 0 ?
924 tci->tli->ca1->getHierarchNo() : QString::null, tci, true);
928 HTMLReportElement::genCellIndex(TableCellInfo* tci)
930 genCell(tci->tli->ca2 == 0 ?
931 QString().sprintf("%d.", tci->tli->ca1->getIndex()) :
932 QString::null, tci, true);
936 HTMLReportElement::genCellHierarchIndex(TableCellInfo* tci)
938 genCell(tci->tli->ca2 == 0 ?
939 tci->tli->ca1->getHierarchIndex() : QString::null, tci, true);
943 HTMLReportElement::genCellHierarchLevel(TableCellInfo* tci)
945 genCell(tci->tli->ca2 == 0 ?
946 tci->tli->ca1->getHierarchLevel() : QString::null, tci, true);
950 HTMLReportElement::genCellId(TableCellInfo* tci)
952 genCell(tci->tli->ca1->getId(), tci, true);
956 HTMLReportElement::genCellName(TableCellInfo* tci)
959 int fontSize = tci->tli->ca2 == 0 ? 100 : 90;
960 if ((tci->tli->ca2 && tci->tli->ca2->getType() == CA_Resource &&
961 resourceSortCriteria[0] == CoreAttributesList::TreeMode) ||
962 (tci->tli->ca2 && tci->tli->ca2->getType() == CA_Task &&
963 taskSortCriteria[0] == CoreAttributesList::TreeMode) ||
964 (tci->tli->ca2 && tci->tli->ca2->getType() == CA_Account &&
965 accountSortCriteria[0] == CoreAttributesList::TreeMode))
966 for (const CoreAttributes* cp = tci->tli->ca2 ; cp != 0;
967 cp = cp->getParent())
971 if (tci->tli->specialName.isNull())
974 mt.setMacro(new Macro(KW("taskid"), tci->tli->task->getId(),
975 defFileName, defFileLine));
976 if (tci->tli->resource)
977 mt.setMacro(new Macro(KW("resourceid"), tci->tli->resource->getId(),
978 defFileName, defFileLine));
979 if (tci->tli->account)
980 mt.setMacro(new Macro(KW("accountid"), tci->tli->account->getId(),
981 defFileName, defFileLine));
983 if ((tci->tli->ca1->getType() == CA_Resource &&
984 resourceSortCriteria[0] == CoreAttributesList::TreeMode) ||
985 (tci->tli->ca1->getType() == CA_Task &&
986 taskSortCriteria[0] == CoreAttributesList::TreeMode) ||
987 (tci->tli->ca1->getType() == CA_Account &&
988 accountSortCriteria[0] == CoreAttributesList::TreeMode))
990 lPadding += tci->tli->ca1->treeLevel();
991 tci->setFontFactor(fontSize + 5 * (maxDepthTaskList - 1 -
992 tci->tli->ca1->treeLevel()));
994 tci->setLeftPadding(2 + lPadding * 15);
995 text = tci->tli->ca1->getName();
998 text = tci->tli->specialName;
999 genCell(text, tci, true);
1003 HTMLReportElement::genCellStart(TableCellInfo* tci)
1005 if (!tci->tli->task->isStartOk(tci->tli->sc))
1006 tci->setBgColor(colors.getColor("error"));
1007 genCell(time2user(tci->tli->task->getStart(tci->tli->sc), timeFormat),
1012 HTMLReportElement::genCellEnd(TableCellInfo* tci)
1014 if (!tci->tli->task->isEndOk(tci->tli->sc))
1015 tci->setBgColor(colors.getColor("error"));
1016 genCell(time2user(tci->tli->task->getEnd(tci->tli->sc) + 1, timeFormat),
1020 #define GCMMSE(a, b) \
1022 HTMLReportElement::genCell##a(TableCellInfo* tci) \
1024 genCell(tci->tli->task->get##a(tci->tli->sc) == 0 ? QString() : \
1025 time2user(tci->tli->task->get##a(tci->tli->sc) + b, timeFormat), \
1034 #define GCSEBUFFER(a) \
1036 HTMLReportElement::genCell##a##Buffer(TableCellInfo* tci) \
1038 genCell(QString().sprintf \
1039 ("%3.0f", tci->tli->task->get##a##Buffer(tci->tli->sc)), \
1047 HTMLReportElement::genCellStartBufferEnd(TableCellInfo* tci)
1049 genCell(time2user(tci->tli->task->getStartBufferEnd
1050 (tci->tli->sc), timeFormat), tci, false);
1054 HTMLReportElement::genCellEndBufferStart(TableCellInfo* tci)
1056 genCell(time2user(tci->tli->task->getStartBufferEnd
1057 (tci->tli->sc) + 1, timeFormat), tci, false);
1061 HTMLReportElement::genCellDuration(TableCellInfo* tci)
1063 genCell(scaledDuration(tci->tli->task->getCalcDuration(tci->tli->sc),
1064 tci->tcf->realFormat),
1069 HTMLReportElement::genCellEffort(TableCellInfo* tci)
1072 if (tci->tli->ca1->getType() == CA_Task)
1074 val = tci->tli->task->getLoad(tci->tli->sc, Interval(start, end),
1075 tci->tli->resource);
1077 else if (tci->tli->ca1->getType() == CA_Resource)
1079 val = tci->tli->resource->getEffectiveLoad
1080 (tci->tli->sc, Interval(start, end), AllAccounts, tci->tli->task);
1083 generateRightIndented(tci, scaledLoad(val, tci->tcf->realFormat));
1087 HTMLReportElement::genCellFreeLoad(TableCellInfo* tci)
1090 if (tci->tli->ca1->getType() == CA_Resource)
1092 val = tci->tli->resource->getEffectiveFreeLoad
1093 (tci->tli->sc, Interval(start, end));
1096 generateRightIndented(tci, scaledLoad(val, tci->tcf->realFormat));
1100 HTMLReportElement::genCellUtilization(TableCellInfo* tci)
1103 if (tci->tli->ca1->getType() == CA_Resource)
1105 double load = tci->tli->resource->getEffectiveLoad
1106 (tci->tli->sc, Interval(start, end));
1109 double availableLoad =
1110 tci->tli->resource->getEffectiveFreeLoad
1111 (tci->tli->sc, Interval(start, end));
1113 val = 100.0 / (1.0 + availableLoad / load);
1117 generateRightIndented(tci, QString().sprintf("%.1f%%", val));
1121 HTMLReportElement::genCellCriticalness(TableCellInfo* tci)
1123 generateRightIndented
1124 (tci, scaledLoad(tci->tli->task->getCriticalness(tci->tli->sc),
1125 tci->tcf->realFormat));
1129 HTMLReportElement::genCellPathCriticalness(TableCellInfo* tci)
1131 generateRightIndented
1132 (tci, scaledLoad(tci->tli->task->getPathCriticalness(tci->tli->sc),
1133 tci->tcf->realFormat));
1137 HTMLReportElement::genCellProjectId(TableCellInfo* tci)
1139 genCell(tci->tli->task->getProjectId() + " (" +
1140 report->getProject()->getIdIndex(tci->tli->task->
1141 getProjectId()) + ")", tci,
1146 HTMLReportElement::genCellProjectIDs(TableCellInfo* tci)
1148 genCell(tci->tli->resource->getProjectIDs(tci->tli->sc,
1149 Interval(start, end)), tci, true);
1153 HTMLReportElement::genCellResources(TableCellInfo* tci)
1156 for (ResourceListIterator rli(tci->tli->task->
1157 getBookedResourcesIterator(tci->tli->sc));
1160 if (!text.isEmpty())
1163 text += (*rli)->getName();
1165 genCell(text, tci, false);
1169 HTMLReportElement::genCellResponsible(TableCellInfo* tci)
1171 if (tci->tli->task->getResponsible())
1172 genCell(tci->tli->task->getResponsible()->getName(),
1175 genCell("", tci, true);
1179 HTMLReportElement::genCellText(TableCellInfo* tci)
1181 if (tci->tcf->getId() == "note")
1183 if (tci->tli->task->getNote().isEmpty())
1184 genCell("", tci, true);
1186 genCell(tci->tli->task->getNote(), tci, true);
1190 const TextAttribute* ta = static_cast<const TextAttribute*>
1191 (tci->tli->ca1->getCustomAttribute(tci->tcf->getId()));
1192 if (!ta || ta->getText().isEmpty())
1193 genCell("", tci, true);
1195 genCell(ta->getText(), tci, true);
1199 HTMLReportElement::genCellStatusNote(TableCellInfo* tci)
1201 if (tci->tli->task->getStatusNote(tci->tli->sc).isEmpty())
1202 genCell("", tci, true);
1204 genCell(tci->tli->task->getStatusNote(tci->tli->sc),
1209 HTMLReportElement::genCellCost(TableCellInfo* tci)
1212 if (tci->tli->ca1->getType() == CA_Task)
1214 val = tci->tli->task->getCredits(tci->tli->sc, Interval(start, end),
1215 Cost, tci->tli->resource);
1217 else if (tci->tli->ca1->getType() == CA_Resource)
1219 val = tci->tli->resource->getCredits(tci->tli->sc, Interval(start, end),
1220 Cost, tci->tli->task);
1222 generateRightIndented(tci, tci->tcf->realFormat.format(val, tci));
1226 HTMLReportElement::genCellRevenue(TableCellInfo* tci)
1229 if (tci->tli->ca1->getType() == CA_Task)
1231 val = tci->tli->task->getCredits(tci->tli->sc, Interval(start, end),
1232 Revenue, tci->tli->resource);
1234 else if (tci->tli->ca1->getType() == CA_Resource)
1236 val = tci->tli->resource->getCredits(tci->tli->sc, Interval(start, end),
1237 Revenue, tci->tli->task);
1239 generateRightIndented(tci, tci->tcf->realFormat.format(val, tci));
1243 HTMLReportElement::genCellProfit(TableCellInfo* tci)
1246 if (tci->tli->ca1->getType() == CA_Task)
1248 val = tci->tli->task->getCredits(tci->tli->sc, Interval(start, end),
1249 Revenue, tci->tli->resource) -
1250 tci->tli->task->getCredits(tci->tli->sc, Interval(start, end),
1251 Cost, tci->tli->resource);
1253 else if (tci->tli->ca1->getType() == CA_Resource)
1255 val = tci->tli->resource->getCredits(tci->tli->sc, Interval(start, end),
1256 Revenue, tci->tli->task) -
1257 tci->tli->resource->getCredits(tci->tli->sc, Interval(start, end),
1258 Cost, tci->tli->task);
1260 generateRightIndented(tci, tci->tcf->realFormat.format(val, tci));
1264 HTMLReportElement::genCellPriority(TableCellInfo* tci)
1266 genCell(QString().sprintf("%d", tci->tli->task->getPriority()),
1271 HTMLReportElement::genCellFlags(TableCellInfo* tci)
1273 FlagList allFlags = tci->tli->ca1->getFlagList();
1275 for (QStringList::Iterator it = allFlags.begin();
1276 it != allFlags.end(); ++it)
1278 if (it != allFlags.begin())
1282 genCell(flagStr, tci, true);
1286 HTMLReportElement::genCellCompleted(TableCellInfo* tci)
1288 double calcedCompletionDegree =
1289 tci->tli->task->getCalcedCompletionDegree(tci->tli->sc);
1290 double providedCompletionDegree =
1291 tci->tli->task->getCompletionDegree(tci->tli->sc);
1293 if (calcedCompletionDegree < 0)
1295 if (calcedCompletionDegree == providedCompletionDegree)
1297 genCell(QString(i18n("in progress")), tci, false);
1301 genCell(QString(i18n("%1% (in progress)"))
1302 .arg((int) providedCompletionDegree),
1308 if (calcedCompletionDegree == providedCompletionDegree)
1310 genCell(QString("%1%").arg((int) providedCompletionDegree),
1315 genCell(QString("%1% (%2%)")
1316 .arg((int) providedCompletionDegree)
1317 .arg((int) calcedCompletionDegree),
1324 HTMLReportElement::genCellCompletedEffort(TableCellInfo* tci)
1328 if (!tci->tli->resource && tci->tli->task->isLeaf())
1330 // Task line, no resource.
1331 val = tci->tli->task->getCompletedLoad(tci->tli->sc);
1333 else if (tci->tli->ca2 && tci->tli->ca2->getType() == CA_Resource &&
1334 tci->tli->task && tci->tli->task->isLeaf())
1336 // Task line, nested into a resource
1337 const Project* project = report->getProject();
1338 time_t now = project->getNow();
1339 if (now < project->getStart())
1340 now = project->getStart();
1341 if (now > project->getEnd())
1342 now = project->getEnd();
1343 Interval iv = Interval(project->getStart(), now);
1344 val = tci->tli->task->getLoad(tci->tli->sc, iv, tci->tli->resource);
1348 genCell("", tci, false);
1351 generateRightIndented(tci, scaledLoad(val, tci->tcf->realFormat));
1355 HTMLReportElement::genCellRemainingEffort(TableCellInfo* tci)
1359 if (!tci->tli->resource && tci->tli->task->isLeaf())
1361 // Task line, no resource.
1362 val = tci->tli->task->getRemainingLoad(tci->tli->sc);
1364 else if (tci->tli->ca2 && tci->tli->ca2->getType() == CA_Resource &&
1365 tci->tli->task && tci->tli->task->isLeaf())
1367 // Task line, nested into a resource
1368 const Project* project = report->getProject();
1369 time_t now = project->getNow();
1370 if (now < project->getStart())
1371 now = project->getStart();
1372 if (now > project->getEnd())
1373 now = project->getEnd();
1374 Interval iv = Interval(now, project->getEnd());
1375 val = tci->tli->task->getLoad(tci->tli->sc, iv, tci->tli->resource);
1379 genCell("", tci, false);
1383 generateRightIndented(tci, scaledLoad(val, tci->tcf->realFormat));
1387 HTMLReportElement::genCellStatus(TableCellInfo* tci)
1389 genCell(tci->tli->task->getStatusText(tci->tli->sc), tci, false);
1393 HTMLReportElement::genCellReference(TableCellInfo* tci)
1395 if (tci->tcf->getId() == "reference")
1397 if (tci->tli->task->getReference().isEmpty())
1398 genCell("", tci, true);
1401 QString text ="<a href=\"" + tci->tli->task->getReference() + "\">";
1402 if (tci->tli->task->getReferenceLabel().isEmpty())
1403 text += htmlFilter(tci->tli->task->getReference());
1405 text += htmlFilter(tci->tli->task->getReferenceLabel());
1407 genCell(text, tci, true, false);
1412 const ReferenceAttribute* ra = static_cast<const ReferenceAttribute*>
1413 (tci->tli->ca1->getCustomAttribute(tci->tcf->getId()));
1414 if (!ra || ra->getURL().isEmpty())
1415 genCell("", tci, true);
1418 QString text ="<a href=\"" + ra->getURL() + "\">";
1419 if (ra->getLabel().isEmpty())
1420 text += htmlFilter(ra->getURL());
1422 text += htmlFilter(ra->getLabel());
1424 genCell(text, tci, true, false);
1429 HTMLReportElement::genCellScenario(TableCellInfo* tci)
1431 genCell(report->getProject()->getScenarioName(tci->tli->sc), tci, false);
1434 #define GCDEPFOL(a, b) \
1436 HTMLReportElement::genCell##a(TableCellInfo* tci) \
1439 for (TaskListIterator it(tci->tli->task->get##b##Iterator()); *it != 0; \
1442 if (!text.isEmpty()) \
1444 text += (*it)->getId(); \
1446 genCell(text, tci, true); \
1449 GCDEPFOL(Depends, Previous)
1450 GCDEPFOL(Follows, Followers)
1453 HTMLReportElement::selectTaskBgColor(TableCellInfo* tci, double load,
1454 const Interval& period, bool daily)
1457 if (tci->tli->task->isActive(tci->tli->sc, period) &&
1458 ((tci->tli->resource != 0 && load > 0.0) || tci->tli->resource == 0))
1460 if (tci->tli->task->isCompleted(tci->tli->sc, period.getEnd()))
1462 if (tci->tli->ca2 == 0)
1463 bgCol = colors.getColor("completed");
1465 bgCol = colors.getColor("completed").light(130);
1469 if (tci->tli->ca2 == 0 &&
1470 !tci->tli->task->isBuffer(tci->tli->sc, period))
1472 bgCol = colors.getColor("booked");
1476 bgCol = colors.getColor("booked").light(130);
1480 else if (period.contains(report->getProject()->getNow()))
1482 bgCol = colors.getColor("today");
1484 else if (daily && (isWeekend(period.getStart()) ||
1485 report->getProject()->isVacation(period.getStart())))
1487 bgCol = colors.getColor("vacation");
1494 HTMLReportElement::selectResourceBgColor(TableCellInfo* tci, double load,
1495 const Interval& period, bool)
1498 if ((load > tci->tli->resource->getMinEffort() *
1499 tci->tli->resource->getEfficiency()) ||
1500 (load == 0.0 && tci->tli->resource->isAllocated(tci->tli->sc, period)))
1502 if (tci->tli->ca2 == 0)
1504 bgCol = colors.getColor("booked");
1508 if (tci->tli->task->isCompleted(tci->tli->sc, period.getEnd()))
1509 bgCol = colors.getColor("completed").light(130);
1511 bgCol = colors.getColor("booked").light(130);
1514 else if (period.contains(report->getProject()->getNow()))
1516 bgCol = colors.getColor("today");
1518 else if (tci->tli->resource->getEffectiveLoad
1519 (tci->tli->sc, period) == 0.0 &&
1520 tci->tli->resource->getEffectiveFreeLoad(tci->tli->sc, period) ==
1523 bgCol = colors.getColor("vacation");
1530 HTMLReportElement::genCellTaskFunc(TableCellInfo* tci, bool daily,
1531 time_t (*beginOfT)(time_t),
1532 time_t (*sameTimeNextT)(time_t))
1534 for (time_t t = (*beginOfT)(start); t < end; t = (*sameTimeNextT)(t))
1536 Interval period = Interval(t, sameTimeNextT(t) - 1);
1537 double load = tci->tli->task->getLoad(tci->tli->sc, period,
1538 tci->tli->resource);
1539 QColor bgCol = selectTaskBgColor(tci, load, period, daily);
1542 if (!tci->tli->task->isActive(tci->tli->sc, period))
1544 time_t lastEndT = t;
1545 for (time_t endT = sameTimeNextT(t); endT < end;
1546 endT = sameTimeNextT(endT))
1548 Interval periodProbe = Interval(endT, sameTimeNextT(endT) - 1);
1549 double loadProbe = tci->tli->task->getLoad(tci->tli->sc,
1551 tci->tli->resource);
1552 QColor bgColProbe = selectTaskBgColor(tci, loadProbe,
1553 periodProbe, daily);
1554 if (load != loadProbe || bgCol != bgColProbe)
1561 tci->setColumns(runLength);
1562 tci->setBgColor(bgCol);
1564 reportTaskLoad(load, tci, period);
1569 HTMLReportElement::genCellResourceFunc(TableCellInfo* tci, bool daily,
1570 time_t (*beginOfT)(time_t),
1571 time_t (*sameTimeNextT)(time_t))
1573 for (time_t t = beginOfT(start); t < end; t = sameTimeNextT(t))
1575 Interval period = Interval(t, sameTimeNextT(t) - 1);
1576 double load = tci->tli->resource->getEffectiveLoad
1577 (tci->tli->sc, period, AllAccounts, tci->tli->task);
1578 QColor bgCol = selectResourceBgColor(tci, load, period, daily);
1583 time_t lastEndT = t;
1584 for (time_t endT = sameTimeNextT(t); endT < end;
1585 endT = sameTimeNextT(endT))
1587 Interval periodProbe = Interval(endT, sameTimeNextT(endT) - 1);
1588 double loadProbe = tci->tli->resource->getEffectiveLoad
1589 (tci->tli->sc, periodProbe, AllAccounts, tci->tli->task);
1590 QColor bgColProbe = selectResourceBgColor(tci, loadProbe,
1591 periodProbe, daily);
1593 if (load != loadProbe || bgCol != bgColProbe)
1600 tci->setColumns(runLength);
1601 tci->setBgColor(bgCol);
1603 reportResourceLoad(load, tci, period);
1608 HTMLReportElement::genCellAccountFunc(TableCellInfo* tci,
1609 time_t (*beginOfT)(time_t),
1610 time_t (*sameTimeNextT)(time_t))
1612 tci->tcf->realFormat = currencyFormat;
1613 for (time_t t = beginOfT(start); t < end; t = sameTimeNextT(t))
1615 double volume = tci->tli->account->
1616 getVolume(tci->tli->sc, Interval(t, sameTimeNextT(t) - 1));
1617 if ((accountSortCriteria[0] == CoreAttributesList::TreeMode &&
1618 tci->tli->account->isRoot()) ||
1619 (accountSortCriteria[0] != CoreAttributesList::TreeMode))
1620 tci->tci->addToSum(tci->tli->sc, time2ISO(t), volume);
1621 reportCurrency(volume, tci, t);
1626 HTMLReportElement::genCellDailyTask(TableCellInfo* tci)
1628 genCellTaskFunc(tci, true, midnight, sameTimeNextDay);
1632 HTMLReportElement::genCellDailyResource(TableCellInfo* tci)
1634 genCellResourceFunc(tci, true, midnight, sameTimeNextDay);
1638 HTMLReportElement::genCellDailyAccount(TableCellInfo* tci)
1640 genCellAccountFunc(tci, midnight, sameTimeNextDay);
1644 HTMLReportElement::genCellWeeklyTask(TableCellInfo* tci)
1646 bool weekStartsMonday = report->getWeekStartsMonday();
1647 for (time_t week = beginOfWeek(start, weekStartsMonday); week < end;
1648 week = sameTimeNextWeek(week))
1650 Interval period = Interval(week, sameTimeNextWeek(week) - 1);
1651 double load = tci->tli->task->getLoad(tci->tli->sc, period,
1652 tci->tli->resource);
1653 QColor bgCol = selectTaskBgColor(tci, load, period, false);
1656 if (!tci->tli->task->isActive(tci->tli->sc, period))
1658 time_t lastEndWeek = week;
1659 for (time_t endWeek = sameTimeNextWeek(week); endWeek < end;
1660 endWeek = sameTimeNextWeek(endWeek))
1662 Interval periodProbe = Interval(endWeek)
1663 .firstWeek(weekStartsMonday);
1664 double loadProbe = tci->tli->task->getLoad(tci->tli->sc,
1666 tci->tli->resource);
1667 QColor bgColProbe = selectTaskBgColor(tci, loadProbe,
1668 periodProbe, false);
1669 if (load != loadProbe || bgCol != bgColProbe)
1671 lastEndWeek = endWeek;
1676 tci->setColumns(runLength);
1677 tci->setBgColor(bgCol);
1679 reportTaskLoad(load, tci, period);
1684 HTMLReportElement::genCellWeeklyResource(TableCellInfo* tci)
1686 bool weekStartsMonday = report->getWeekStartsMonday();
1687 for (time_t week = beginOfWeek(start, weekStartsMonday); week < end;
1688 week = sameTimeNextWeek(week))
1690 Interval period = Interval(week, sameTimeNextWeek(week) - 1);
1691 double load = tci->tli->resource->getEffectiveLoad
1692 (tci->tli->sc, period, AllAccounts, tci->tli->task);
1693 QColor bgCol = selectResourceBgColor(tci, load, period, false);
1698 time_t lastEndWeek = week;
1699 for (time_t endWeek = sameTimeNextWeek(week); endWeek < end;
1700 endWeek = sameTimeNextWeek(endWeek))
1702 Interval periodProbe = Interval(endWeek)
1703 .firstWeek(weekStartsMonday);
1704 double loadProbe = tci->tli->resource->getEffectiveLoad
1705 (tci->tli->sc, periodProbe, AllAccounts, tci->tli->task);
1706 QColor bgColProbe = selectResourceBgColor(tci, loadProbe,
1707 periodProbe, false);
1708 if (load != loadProbe || bgCol != bgColProbe)
1710 lastEndWeek = endWeek;
1715 tci->setColumns(runLength);
1716 tci->setBgColor(bgCol);
1718 reportResourceLoad(load, tci, period);
1723 HTMLReportElement::genCellWeeklyAccount(TableCellInfo* tci)
1725 bool weekStartsMonday = report->getWeekStartsMonday();
1726 for (time_t week = beginOfWeek(start, weekStartsMonday); week < end;
1727 week = sameTimeNextWeek(week))
1729 double volume = tci->tli->account->
1730 getVolume(tci->tli->sc, Interval(week, sameTimeNextWeek(week) - 1));
1731 if ((accountSortCriteria[0] == CoreAttributesList::TreeMode &&
1732 tci->tli->account->isRoot()) ||
1733 (accountSortCriteria[0] != CoreAttributesList::TreeMode))
1734 tci->tci->addToSum(tci->tli->sc, time2ISO(week), volume);
1735 reportCurrency(volume, tci, week);
1740 HTMLReportElement::genCellMonthlyTask(TableCellInfo* tci)
1742 genCellTaskFunc(tci, false, beginOfMonth, sameTimeNextMonth);
1746 HTMLReportElement::genCellMonthlyResource(TableCellInfo* tci)
1748 genCellResourceFunc(tci, false, beginOfMonth, sameTimeNextMonth);
1752 HTMLReportElement::genCellMonthlyAccount(TableCellInfo* tci)
1754 genCellAccountFunc(tci, beginOfMonth, sameTimeNextMonth);
1758 HTMLReportElement::genCellQuarterlyTask(TableCellInfo* tci)
1760 genCellTaskFunc(tci, false, beginOfQuarter, sameTimeNextQuarter);
1764 HTMLReportElement::genCellQuarterlyResource(TableCellInfo* tci)
1766 genCellResourceFunc(tci, false, beginOfQuarter, sameTimeNextQuarter);
1770 HTMLReportElement::genCellQuarterlyAccount(TableCellInfo* tci)
1772 genCellAccountFunc(tci, beginOfQuarter, sameTimeNextQuarter);
1776 HTMLReportElement::genCellYearlyTask(TableCellInfo* tci)
1778 genCellTaskFunc(tci, false, beginOfYear, sameTimeNextYear);
1782 HTMLReportElement::genCellYearlyResource(TableCellInfo* tci)
1784 genCellResourceFunc(tci, false, beginOfYear, sameTimeNextYear);
1788 HTMLReportElement::genCellYearlyAccount(TableCellInfo* tci)
1790 genCellAccountFunc(tci, beginOfYear, sameTimeNextYear);
1794 HTMLReportElement::genCellResponsibilities(TableCellInfo* tci)
1797 for (TaskListIterator it(report->getProject()->getTaskListIterator());
1800 if ((*it)->getResponsible() == tci->tli->resource)
1802 if (!text.isEmpty())
1804 text += (*it)->getId();
1807 genCell(text, tci, true);
1811 HTMLReportElement::genCellScheduling(TableCellInfo* tci)
1813 genCell(tci->tli->task->getSchedulingText(), tci, true);
1817 HTMLReportElement::genCellSchedule(TableCellInfo* tci)
1819 s() << " <td>" << endl;
1821 if (tci->tli->resource)
1823 BookingList jobs = tci->tli->resource->getJobs(tci->tli->sc);
1824 jobs.setAutoDelete(true);
1825 time_t prevTime = 0;
1826 Interval reportPeriod(start, end);
1827 s() << " <table style=\"width:150px; font-size:100%; "
1828 << "text-align:left\">" << endl
1830 << " <th style=\"width:35%\"></th>" << endl
1831 << " <th style=\"width:65%\"></th>" << endl
1832 << " </tr>" << endl;
1833 for (BookingList::Iterator bli(jobs); *bli != 0; ++bli)
1835 if ((tci->tli->ca2 == 0 || tci->tli->task == (*bli)->getTask()) &&
1836 reportPeriod.overlaps(Interval((*bli)->getStart(),
1839 /* If the reporting interval is not more than a day, we
1840 * do not print the day since this information is most
1841 * likely given by the context of the report. */
1842 if (!isSameDay(prevTime, (*bli)->getStart()) &&
1843 !isSameDay(start, end - 1))
1845 s() << " <tr>" << endl
1846 << " <td colspan=\"2\" style=\"font-size:120%\">"
1847 << time2weekday((*bli)->getStart()) << ", "
1848 << time2date((*bli)->getStart()) << "</td>" << endl
1852 s() << " <tr>" << endl
1854 Interval workPeriod((*bli)->getStart(), (*bli)->getEnd());
1855 workPeriod.overlap(reportPeriod);
1856 s() << time2user(workPeriod.getStart(), shortTimeFormat)
1858 << time2user(workPeriod.getEnd() + 1, shortTimeFormat);
1859 s() << "</td>" << endl
1861 if (tci->tli->ca2 == 0)
1862 s() << " " << htmlFilter((*bli)->getTask()->getName());
1863 s() << " </td>" << endl;
1864 prevTime = (*bli)->getStart();
1865 s() << " </tr>" << endl;
1868 s() << " </table>" << endl;
1873 s() << " </td>" << endl;
1876 #define GCEFFORT(a) \
1878 HTMLReportElement::genCell##a##Effort(TableCellInfo* tci) \
1880 genCell(tci->tcf->realFormat.format \
1881 (tci->tli->resource->get##a##Effort(), false), \
1888 HTMLReportElement::genCellMaxEffort(TableCellInfo* tci)
1890 genCell(tci->tcf->realFormat.format
1891 (tci->tli->resource->getLimits() ?
1892 tci->tli->resource->getLimits()->getDailyMax() : 0, false),
1897 HTMLReportElement::genCellEfficiency(TableCellInfo* tci)
1899 genCell(tci->tcf->realFormat.format(tci->tli->resource->getEfficiency(),
1904 HTMLReportElement::genCellRate(TableCellInfo* tci)
1906 genCell(tci->tcf->realFormat.format(tci->tli->resource->getRate(), tci),
1911 HTMLReportElement::genCellTotal(TableCellInfo* tci)
1913 double value = tci->tli->account->getVolume(tci->tli->sc,
1914 Interval(start, end));
1915 if (tci->tli->account->isLeaf())
1916 tci->tci->addToSum(tci->tli->sc, "total", value);
1917 genCell(tci->tcf->realFormat.format(value, tci), tci, false);
1921 HTMLReportElement::genCellSummary(TableCellInfo* tci)
1923 QMap<QString, double>::ConstIterator it;
1924 const QMap<QString, double>* sum = tci->tci->getSum();
1927 uint sc = tci->tli->sc;
1929 if (sum[sc].begin() != sum[sc].end())
1931 for (it = sum[sc].begin(); it != sum[sc].end(); ++it)
1937 genCell(tci->tcf->realFormat.format(val, tci), tci, false);
1942 // The column counter is not set in all cases. These are always single
1944 if (tci->tci->getSubColumns() > 0)
1945 for (uint col = 0; col < tci->tci->getSubColumns(); ++col)
1946 genCell(tci->tcf->realFormat.format(0.0, tci), tci, false);
1948 genCell(tci->tcf->realFormat.format(0.0, tci), tci, false);