karm Library API Documentation

timekard.cpp

00001 /* 00002 * This file only: 00003 * Copyright (C) 2003 Mark Bucciarelli <mark@hubcapconsutling.com> 00004 * 00005 * This program is free software; you can redistribute it and/or modify 00006 * it under the terms of the GNU General Public License as published by 00007 * the Free Software Foundation; either version 2 of the License, or 00008 * (at your option) any later version. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License along 00016 * with this program; if not, write to the 00017 * Free Software Foundation, Inc. 00018 * 59 Temple Place - Suite 330 00019 * Boston, MA 02111-1307 USA. 00020 * 00021 */ 00022 00023 // #include <iostream> 00024 00025 #include <qdatetime.h> 00026 #include <qpaintdevicemetrics.h> 00027 #include <qpainter.h> 00028 #include <qmap.h> 00029 00030 #include <kglobal.h> 00031 #include <kdebug.h> 00032 #include <klocale.h> // i18n 00033 #include <event.h> 00034 00035 #include "karmutility.h" // formatTime() 00036 #include "timekard.h" 00037 #include "task.h" 00038 #include "taskview.h" 00039 00040 const int taskWidth = 40; 00041 const int timeWidth = 6; 00042 const int totalTimeWidth = 7; 00043 const int reportWidth = taskWidth + timeWidth; 00044 const int weekReportWidth = taskWidth + (7 * timeWidth) + totalTimeWidth; 00045 00046 const QString cr = QString::fromLatin1("\n"); 00047 00048 QString TimeKard::totalsAsText(TaskView* taskview, bool justThisTask) 00049 { 00050 QString retval; 00051 QString taskhdr, totalhdr; 00052 QString line; 00053 QString buf; 00054 long sum; 00055 00056 line.fill('-', reportWidth); 00057 line += cr; 00058 00059 // header 00060 retval += i18n("Task Totals") + cr; 00061 retval += KGlobal::locale()->formatDateTime(QDateTime::currentDateTime()); 00062 retval += cr + cr; 00063 retval += QString(QString::fromLatin1("%1 %2")) 00064 .arg(i18n("Time"), timeWidth) 00065 .arg(i18n("Task")); 00066 retval += cr; 00067 retval += line; 00068 00069 // tasks 00070 if (taskview->current_item()) 00071 { 00072 if (justThisTask) 00073 { 00074 // a task's total time includes the sum of all subtask times 00075 sum = taskview->current_item()->totalTime(); 00076 printTask(taskview->current_item(), retval, 0); 00077 } 00078 else 00079 { 00080 sum = 0; 00081 for (Task* task= taskview->current_item(); task; 00082 task= task->nextSibling()) 00083 { 00084 sum += task->totalTime(); 00085 printTask(task, retval, 0); 00086 } 00087 } 00088 00089 // total 00090 buf.fill('-', reportWidth); 00091 retval += QString(QString::fromLatin1("%1")).arg(buf, timeWidth) + cr; 00092 retval += QString(QString::fromLatin1("%1 %2")) 00093 .arg(formatTime(sum),timeWidth) 00094 .arg(i18n("Total")); 00095 } 00096 else 00097 retval += i18n("No tasks!"); 00098 00099 return retval; 00100 } 00101 00102 void TimeKard::printTask(Task *task, QString &s, int level) 00103 { 00104 QString buf; 00105 00106 s += buf.fill(' ', level); 00107 s += QString(QString::fromLatin1("%1 %2")) 00108 .arg(formatTime(task->totalTime()), timeWidth) 00109 .arg(task->name()); 00110 s += cr; 00111 00112 for (Task* subTask = task->firstChild(); 00113 subTask; 00114 subTask = subTask->nextSibling()) 00115 { 00116 printTask(subTask, s, level+1); 00117 } 00118 } 00119 00120 void TimeKard::printWeekTask(const Task *task, 00121 const QMap<QString,long>& taskdaytotals, 00122 QMap<QString,long>& daytotals, 00123 const Week& week, const int level, QString& s) 00124 { 00125 QString buf; 00126 QString daytaskkey, daykey; 00127 QDate day; 00128 long weeksum; 00129 00130 day = week.start(); 00131 weeksum = 0; 00132 for (int i = 0; i < 7; i++) 00133 { 00134 daykey = day.toString(QString::fromLatin1("yyyyMMdd")); 00135 daytaskkey = QString::fromLatin1("%1_%2") 00136 .arg(daykey) 00137 .arg(task->uid()); 00138 00139 if (taskdaytotals.contains(daytaskkey)) 00140 { 00141 s += QString::fromLatin1("%1") 00142 .arg(formatTime(taskdaytotals[daytaskkey]/60), timeWidth); 00143 weeksum += taskdaytotals[daytaskkey]; // in seconds 00144 00145 if (daytotals.contains(daykey)) 00146 daytotals.replace(daykey, daytotals[daykey] + taskdaytotals[daytaskkey]); 00147 else 00148 daytotals.insert(daykey, taskdaytotals[daytaskkey]); 00149 } 00150 else 00151 { 00152 buf.fill(' ', timeWidth); 00153 s += buf; 00154 } 00155 00156 day = day.addDays(1); 00157 } 00158 00159 // Total for task this week 00160 s += QString::fromLatin1("%1").arg(formatTime(weeksum/60), totalTimeWidth); 00161 00162 // Task name 00163 s += buf.fill(' ', level + 1); 00164 s += QString::fromLatin1("%1").arg(task->name()); 00165 s += cr; 00166 00167 for (Task* subTask = task->firstChild(); 00168 subTask; 00169 subTask = subTask->nextSibling()) 00170 { 00171 printWeekTask(subTask, taskdaytotals, daytotals, week, level+1, s); 00172 } 00173 } 00174 00175 QString TimeKard::historyAsText(TaskView* taskview, const QDate& from, 00176 const QDate& to, bool justThisTask) 00177 { 00178 QString retval; 00179 QString taskhdr, totalhdr; 00180 QString line, buf; 00181 long sum; 00182 00183 QValueList<Week>::iterator week; 00184 QValueList<HistoryEvent> events; 00185 QValueList<HistoryEvent>::iterator event; 00186 QMap<QString, long> taskdaytotals; 00187 QMap<QString, long> daytotals; 00188 QString daytaskkey, daykey; 00189 QDate day; 00190 00191 line.fill('-', weekReportWidth); 00192 line += cr; 00193 00194 // header 00195 retval += i18n("Task History") + cr; 00196 retval += i18n("From %1 to %2") 00197 .arg(KGlobal::locale()->formatDate(from)) 00198 .arg(KGlobal::locale()->formatDate(to)); 00199 retval += cr; 00200 retval += i18n("Printed on: %1") 00201 .arg(KGlobal::locale()->formatDateTime(QDateTime::currentDateTime())); 00202 00203 // output one time card table for each week in the date range 00204 QValueList<Week> weeks = Week::weeksFromDateRange(from, to); 00205 for (week = weeks.begin(); week != weeks.end(); ++week) 00206 { 00207 if ( (*week).start() < from && (*week).end() > to) 00208 { 00209 events = taskview->getHistory(from, to); 00210 } 00211 else if ( (*week).start() < from ) 00212 { 00213 events = taskview->getHistory(from, (*week).end()); 00214 } 00215 else if ( (*week).end() > to) 00216 { 00217 events = taskview->getHistory((*week).start(), to); 00218 } 00219 else 00220 { 00221 events = taskview->getHistory((*week).start(), (*week).end()); 00222 } 00223 00224 taskdaytotals.clear(); 00225 daytotals.clear(); 00226 00227 // Build lookup dictionary used to output data in table cells. keys are 00228 // in this format: YYYYMMDD_NNNNNN, where Y = year, M = month, d = day and 00229 // NNNNN = the VTODO uid. The value is the total seconds logged against 00230 // that task on that day. Note the UID is the todo id, not the event id, 00231 // so times are accumulated for each task. 00232 for (event = events.begin(); event != events.end(); ++event) 00233 { 00234 daykey = (*event).start().date().toString(QString::fromLatin1("yyyyMMdd")); 00235 daytaskkey = QString(QString::fromLatin1("%1_%2")) 00236 .arg(daykey) 00237 .arg((*event).todoUid()); 00238 00239 if (taskdaytotals.contains(daytaskkey)) 00240 taskdaytotals.replace(daytaskkey, 00241 taskdaytotals[daytaskkey] + (*event).duration()); 00242 else 00243 taskdaytotals.insert(daytaskkey, (*event).duration()); 00244 } 00245 00246 // week name 00247 retval += cr + cr; 00248 buf.fill(' ', int((weekReportWidth - (*week).name().length()) / 2)); 00249 retval += buf + (*week).name() + cr; 00250 00251 // day headings 00252 for (int i = 0; i < 7; i++) 00253 { 00254 retval += QString::fromLatin1("%1") 00255 .arg((*week).start().addDays(i).day(), timeWidth); 00256 } 00257 retval += cr; 00258 retval += line; 00259 00260 // the tasks 00261 if (events.empty()) 00262 { 00263 retval += i18n(" No hours logged."); 00264 } 00265 else 00266 { 00267 sum = 0; 00268 if (justThisTask) 00269 { 00270 printWeekTask(taskview->current_item(), taskdaytotals, daytotals, 00271 (*week), 0, retval); 00272 } 00273 else 00274 { 00275 for (Task* task= taskview->current_item(); task; 00276 task= task->nextSibling()) 00277 { 00278 printWeekTask(task, taskdaytotals, daytotals, (*week), 0, retval); 00279 } 00280 } 00281 retval += line; 00282 00283 // totals 00284 sum = 0; 00285 day = (*week).start(); 00286 for (int i = 0; i < 7; i++) 00287 { 00288 daykey = day.toString(QString::fromLatin1("yyyyMMdd")); 00289 00290 if (daytotals.contains(daykey)) 00291 { 00292 retval += QString::fromLatin1("%1") 00293 .arg(formatTime(daytotals[daykey]/60), timeWidth); 00294 sum += daytotals[daykey]; // in seconds 00295 } 00296 else 00297 { 00298 buf.fill(' ', timeWidth); 00299 retval += buf; 00300 } 00301 00302 day = day.addDays(1); 00303 } 00304 00305 retval += QString::fromLatin1("%1 %2") 00306 .arg(formatTime(sum/60), totalTimeWidth) 00307 .arg(i18n("Total")); 00308 } 00309 } 00310 return retval; 00311 } 00312 00313 Week::Week() {} 00314 00315 Week::Week(QDate from) 00316 { 00317 _start = from; 00318 } 00319 00320 QDate Week::start() const 00321 { 00322 return _start; 00323 } 00324 00325 QDate Week::end() const 00326 { 00327 return _start.addDays(7); 00328 } 00329 00330 QString Week::name() const 00331 { 00332 return QString(i18n("Week of %1")) 00333 .arg(KGlobal::locale()->formatDate(start())); 00334 } 00335 00336 QValueList<Week> Week::weeksFromDateRange(const QDate& from, const QDate& to) 00337 { 00338 QDate start; 00339 QValueList<Week> weeks; 00340 00341 // The QDate weekNumber() method always puts monday as the first day of the 00342 // week. 00343 // 00344 // Not that it matters here, but week 1 always includes the first Thursday 00345 // of the year. For example, January 1, 2000 was a Saturday, so 00346 // QDate(2000,1,1).weekNumber() returns 52. 00347 00348 // Since report always shows a full week, we generate a full week of dates, 00349 // even if from and to are the same date. The week starts on the day 00350 // that is set in the locale settings. 00351 start = from.addDays( 00352 -((7 - KGlobal::locale()->weekStartDay() + from.dayOfWeek()) % 7)); 00353 00354 for (QDate d = start; d <= to; d = d.addDays(7)) 00355 weeks.append(Week(d)); 00356 00357 return weeks; 00358 } 00359
KDE Logo
This file is part of the documentation for karm Library Version 3.2.2.
Documentation copyright © 1996-2004 the KDE developers.
Generated on Wed Jul 28 23:58:06 2004 by doxygen 1.3.7 written by Dimitri van Heesch, © 1997-2003