OSDN Git Service

Merge branch 'post-2.4.2'
[tjqt4port/tj2qt4.git] / taskjuggler / ReportElementBase.cpp
1 /*
2  * ReportElementBase.cpp - TaskJuggler
3  *
4  * Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006
5  * by Chris Schlaeger <cs@kde.org>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of version 2 of the GNU General Public License as
9  * published by the Free Software Foundation.
10  *
11  * $Id: ReportElement.h 1335 2006-09-24 13:49:05Z cs $
12  */
13
14 #include "ReportElementBase.h"
15 #include "TableLineInfo.h"
16 #include "tjlib-internal.h"
17 #include "Project.h"
18 #include "Account.h"
19 #include "Task.h"
20 #include "Resource.h"
21 #include "TextAttribute.h"
22 #include "ReferenceAttribute.h"
23
24 ReportElementBase::ReportElementBase(Report* r, const QString& df, int dl) :
25     report(r),
26     loadUnit(shortAuto),
27     numberFormat(),
28     currencyFormat(),
29     mt(),
30     defFileName(df),
31     defFileLine(dl)
32 {
33 }
34
35 bool
36 ReportElementBase::setLoadUnit(const QString& u)
37 {
38     if (u == KW("minutes"))
39         loadUnit = minutes;
40     else if (u == KW("hours"))
41         loadUnit = hours;
42     else if (u == KW("days"))
43         loadUnit = days;
44     else if (u == KW("weeks"))
45         loadUnit = weeks;
46     else if (u == KW("months"))
47         loadUnit = months;
48     else if (u == KW("years"))
49         loadUnit = years;
50     else if (u == KW("shortauto"))
51         loadUnit = shortAuto;
52     else if (u == KW("longauto"))
53         loadUnit = longAuto;
54     else
55         return false;
56
57     return true;
58 }
59
60 QString
61 ReportElementBase::scaledDuration(double t, const RealFormat& realFormat,
62                                   bool showUnit, bool longUnit) const
63 {
64     QValueList<double> factors;
65
66     factors.append(24 * 60);
67     factors.append(24);
68     factors.append(1);
69     factors.append(1.0 / 7);
70     factors.append(1.0 / 30.42);
71     factors.append(1.0 / 365);
72
73     return scaledValue(t, realFormat, showUnit, longUnit, factors);
74 }
75
76 QString
77 ReportElementBase::scaledLoad(double t, const RealFormat& realFormat,
78                               bool showUnit, bool longUnit) const
79 {
80     QValueList<double> factors;
81
82     factors.append(report->getProject()->getDailyWorkingHours() * 60);
83     factors.append(report->getProject()->getDailyWorkingHours());
84     factors.append(1);
85     factors.append(1.0 / report->getProject()->getWeeklyWorkingDays());
86     factors.append(1.0 / report->getProject()->getMonthlyWorkingDays());
87     factors.append(1.0 / report->getProject()->getYearlyWorkingDays());
88
89     return scaledValue(t, realFormat, showUnit, longUnit, factors);
90 }
91
92 QString
93 ReportElementBase::scaledValue(double t, const RealFormat& realFormat,
94                                bool showUnit, bool longUnit,
95                                const QValueList<double>& factors) const
96 {
97     QStringList variations;
98     const char* shortUnit[] = { "min", "h", "d", "w", "m", "y" };
99     const char* unit[] = { "minute", "hour", "day", "week", "month", "year" };
100     const char* units[] = { "minutes", "hours", "days", "weeks", "months",
101         "years"};
102     double max[] = { 60, 48, 0, 8, 24, 0 };
103
104     QString str;
105
106     if (loadUnit == shortAuto || loadUnit == longAuto)
107     {
108         for (QValueList<double>::ConstIterator it = factors.begin();
109              it != factors.end(); ++it)
110         {
111             str = realFormat.format(t * *it, false);
112             int idx = factors.findIndex(*it);
113             if ((*it != 1.0 && str == "0") ||
114                 (max[idx] != 0 && max[idx] < (t * *it)))
115                 variations.append("");
116             else
117                 variations.append(str);
118         }
119
120         uint shortest = 2;      // default to days in case all are the same
121         for (QStringList::Iterator it = variations.begin();
122              it != variations.end();
123              ++it)
124         {
125             if ((*it).length() > 0 &&
126                 (*it).length() < variations[shortest].length())
127             {
128                 shortest = variations.findIndex(*it);
129             }
130         }
131         str = variations[shortest];
132         if (loadUnit == longAuto)
133         {
134             if (variations[shortest] == "1")
135                 str += QString(" ") + unit[shortest];
136             else
137                 str += QString(" ") + units[shortest];
138         }
139         else
140             str += shortUnit[shortest];
141     }
142     else
143     {
144         switch (loadUnit)
145         {
146             case minutes:
147                 str = realFormat.format(t * factors[0], false);
148                 break;
149             case hours:
150                 str = realFormat.format(t * factors[1], false);
151                 break;
152             case days:
153                 str = realFormat.format(t * factors[2], false);
154                 break;
155             case weeks:
156                 str = realFormat.format(t * factors[3], false);
157                 break;
158             case months:
159                 str = realFormat.format(t * factors[4], false);
160                 break;
161             case years:
162                 str = realFormat.format(t * factors[5], false);
163                 break;
164             case shortAuto:
165             case longAuto:
166                 break;  // handled above switch statement already
167         }
168         // Add unit in case it's forced by caller.
169         if (showUnit && loadUnit <= years)
170             str += longUnit ? QString(" ") + units[loadUnit] :
171                 QString(shortUnit[loadUnit]);
172     }
173     return str;
174 }
175
176 void
177 ReportElementBase::setMacros(TableLineInfo* tli)
178 {
179     mt.clear();
180
181     /* In some cases it might be useful to have not only the ID of the current
182      * property but also the assigned property (e. g. in task reports with
183      * resources, we want the task ID while processing the resource line. */
184     if (tli->task)
185     {
186         if (tli->task->getAccount()) mt.addMacro(new Macro(KW("accounts"), tli->task->getAccount()->getName(), defFileName, defFileLine));
187         mt.addMacro(new Macro(KW("completed"), tli->task->getComplete(tli->sc), defFileName, defFileLine));
188         mt.addMacro(new Macro(KW("completedeffort"), tli->task->getCompletedLoad(tli->sc), defFileName, defFileLine));
189         mt.addMacro(new Macro(KW("criticalness"), tli->task->getCriticalness(tli->sc), defFileName, defFileLine));
190         mt.addMacro(new Macro(KW("duration"), tli->task->getDuration(tli->sc), defFileName, defFileLine));
191         mt.addMacro(new Macro(KW("effort"), tli->task->getEffort(tli->sc), defFileName, defFileLine));
192         if (tli->task->getEnd(tli->sc))
193             mt.addMacro(new Macro(KW("end"), time2user(tli->task->getEnd(tli->sc), tli->task->getProject()->getTimeFormat()), defFileName, defFileLine));
194         if (tli->task->getMaxEnd(tli->sc))
195             mt.addMacro(new Macro(KW("maxend"), time2user(tli->task->getMaxEnd(tli->sc), tli->task->getProject()->getTimeFormat()), defFileName, defFileLine));
196         if (tli->task->getMaxStart(tli->sc))
197             mt.addMacro(new Macro(KW("maxstart"), time2user(tli->task->getMaxStart(tli->sc), tli->task->getProject()->getTimeFormat()), defFileName, defFileLine));
198         if (tli->task->getMinEnd(tli->sc))
199             mt.addMacro(new Macro(KW("minend"), time2user(tli->task->getMinEnd(tli->sc), tli->task->getProject()->getTimeFormat()), defFileName, defFileLine));
200         if (tli->task->getMinStart(tli->sc))
201             mt.addMacro(new Macro(KW("minstart"), time2user(tli->task->getMinStart(tli->sc), tli->task->getProject()->getTimeFormat()), defFileName, defFileLine));
202         mt.addMacro(new Macro(KW("note"), tli->task->getNote(), defFileName, defFileLine));
203         mt.addMacro(new Macro(KW("pathcriticalness"), tli->task->getPathCriticalness(tli->sc), defFileName, defFileLine));
204         mt.addMacro(new Macro(KW("priority"), tli->task->getPriority(), defFileName, defFileLine));
205         mt.addMacro(new Macro(KW("reference"), tli->task->getReference(), defFileName, defFileLine));
206         mt.addMacro(new Macro(KW("remainingeffort"), tli->task->getRemainingLoad(tli->sc), defFileName, defFileLine));
207         if (tli->task->getResponsible())
208             mt.addMacro(new Macro(KW("responsible"), tli->task->getResponsible()->getName(), defFileName, defFileLine));
209         if (tli->task->getStart(tli->sc))
210             mt.addMacro(new Macro(KW("start"), time2user(tli->task->getStart(tli->sc), tli->task->getProject()->getTimeFormat()), defFileName, defFileLine));
211         mt.addMacro(new Macro(KW("status"), tli->task->getStatusText(tli->sc), defFileName, defFileLine));
212         mt.addMacro(new Macro(KW("statusnote"), tli->task->getStatusNote(tli->sc), defFileName, defFileLine));
213         mt.addMacro(new Macro(KW("taskid"), tli->task->getId(), defFileName, defFileLine));
214
215         QString label = "";
216         for (ResourceListIterator rli
217                 (tli->task->getBookedResourcesIterator(tli->sc)); *rli != 0; ++rli)
218         {
219             if (!label.isEmpty())
220                 label += ", ";
221
222             label += (*rli)->getName();
223         }
224         mt.addMacro(new Macro(KW("resources"), label, defFileName, defFileLine));
225     }
226     if (tli->resource)
227     {
228         mt.addMacro(new Macro(KW("efficiency"), tli->resource->getEfficiency(), defFileName, defFileLine));
229         mt.addMacro(new Macro(KW("mineffort"), tli->resource->getMinEffort(), defFileName, defFileLine));
230         mt.addMacro(new Macro(KW("rate"), tli->resource->getRate(), defFileName, defFileLine));
231         mt.addMacro(new Macro(KW("resourceid"), tli->resource->getId(), defFileName, defFileLine));
232     }
233
234     if (tli->account)
235     {
236         mt.addMacro(new Macro(KW("accountid"), tli->account->getId(), defFileName, defFileLine));
237     }
238                               
239     // Set macros for built-in attributes.
240     mt.addMacro(new Macro(KW("id"), tli->ca1 ? tli->ca1->getId() :
241                           QString::null,
242                           defFileName, defFileLine));
243     mt.addMacro(new Macro(KW("no"), tli->ca1 ?
244                           QString("%1").arg(tli->ca1->getSequenceNo()) :
245                           QString::null,
246                           defFileName, defFileLine));
247     mt.addMacro(new Macro(KW("index"), tli->ca1 ?
248                           QString("%1").arg(tli->ca1->getIndex()) :
249                           QString::null,
250                           defFileName, defFileLine));
251     mt.addMacro(new Macro(KW("hierarchno"), tli->ca1 ?
252                           tli->ca1->getHierarchNo() : QString::null,
253                           defFileName, defFileLine));
254     mt.addMacro(new Macro(KW("hierarchindex"),
255                           tli->ca1 ? tli->ca1->getHierarchIndex() :
256                           QString::null,
257                           defFileName, defFileLine));
258     mt.addMacro(new Macro(KW("hierarchlevel"),
259                           tli->ca1 ? tli->ca1->getHierarchLevel() :
260                           QString::null,
261                           defFileName, defFileLine));
262     mt.addMacro(new Macro(KW("name"),
263                           tli->ca1 ? tli->ca1->getName() : QString::null,
264                           defFileName, defFileLine));
265
266
267     setPropertyMacros(tli, report->getProject()->getTaskAttributeDict());
268     setPropertyMacros(tli, report->getProject()->getResourceAttributeDict());
269     setPropertyMacros(tli, report->getProject()->getAccountAttributeDict());
270 }
271
272 void
273 ReportElementBase::setPropertyMacros(TableLineInfo* tli,
274    const QDictIterator<CustomAttributeDefinition>& d)
275 {
276     QDictIterator<CustomAttributeDefinition> cadi(d);
277     for ( ; cadi.current(); ++cadi)
278     {
279         const CustomAttribute* custAttr;
280         QString macroName = cadi.currentKey();
281         QString macroValue;
282         if (tli->ca1 &&
283             (custAttr = tli->ca1->getCustomAttribute(macroName)) != 0)
284         {
285             switch (custAttr->getType())
286             {
287                 case CAT_Text:
288                     macroValue = static_cast<const TextAttribute*>(custAttr)->getText();
289                     break;
290                 case CAT_Reference:
291                     macroValue = static_cast<const ReferenceAttribute*>(custAttr)->getURL();
292                     break;
293                 default:
294                     break;
295             }
296         }
297         mt.addMacro(new Macro(macroName, macroValue, defFileName,
298                               defFileLine));
299     }
300 }
301
302 const QString
303 ReportElementBase::expandReportVariable(const QString& t) const
304 {
305 //     printf ("ReportElementBase::expandReportVariable <%s>", t.latin1());
306     QStringList sl("");
307     return mt.expandReportVariable(t, &sl);
308 }
309