00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
#include <sys/types.h>
00024
#include <sys/stat.h>
00025
#include <fcntl.h>
00026
#include <unistd.h>
00027
00028
#include <cassert>
00029
00030
#include <qfile.h>
00031
#include <qsize.h>
00032
#include <qdict.h>
00033
#include <qdatetime.h>
00034
#include <qstringlist.h>
00035
00036
#include "incidence.h"
00037
#include "kapplication.h"
00038
#include <kdebug.h>
00039
#include <kemailsettings.h>
00040
#include <klocale.h>
00041
#include <kmessagebox.h>
00042
#include <kprogress.h>
00043
#include <resourcecalendar.h>
00044
#include <resourcelocal.h>
00045
#include <kpimprefs.h>
00046
#include <taskview.h>
00047
#include <timekard.h>
00048
#include <karmutility.h>
00049
00050
00051
00052
00053
00054
00055
#include "karmstorage.h"
00056
#include "preferences.h"
00057
#include "task.h"
00058
#include "reportcriteria.h"
00059
00060
00061
KarmStorage *KarmStorage::_instance = 0;
00062
00063
KarmStorage *KarmStorage::instance()
00064 {
00065
if (_instance == 0) _instance =
new KarmStorage();
00066
return _instance;
00067 }
00068
00069 KarmStorage::KarmStorage()
00070 {
00071 _calendar = 0;
00072 _lock = 0;
00073 }
00074
00075
QString KarmStorage::load (
TaskView* view,
const Preferences* preferences)
00076 {
00077
00078
00079
00080
00081
00082
00083
00084
00085
QString err;
00086 KEMailSettings settings;
00087
00088
00089
if ( preferences->
iCalFile() == _icalfile )
return err;
00090
00091
00092
00093
00094
00095
int handle;
00096 handle = open (
00097 QFile::encodeName( preferences->
iCalFile() ),
00098 O_CREAT|O_EXCL|O_WRONLY,
00099 S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH
00100 );
00101
if (handle != -1) close(handle);
00102
00103
if ( _calendar) closeStorage(view);
00104
else _calendar =
new KCal::CalendarResources();
00105
00106
00107 _icalfile = preferences->
iCalFile();
00108 KCal::ResourceCalendar *l =
new KCal::ResourceLocal( _icalfile );
00109 l->setTimeZoneId( KPimPrefs::timezone() );
00110 l->setResourceName( QString::fromLatin1(
"KArm") );
00111 l->open();
00112 l->load();
00113
00114 KCal::CalendarResourceManager *m = _calendar->resourceManager();
00115 m->add(l);
00116 m->setStandardResource(l);
00117
00118
00119
QString email = _calendar->getEmail();
00120
QString owner = _calendar->getOwner();
00121
if ( email.isEmpty() && owner.isEmpty() )
00122 {
00123 _calendar->setEmail( settings.getSetting( KEMailSettings::EmailAddress ) );
00124 _calendar->setOwner( settings.getSetting( KEMailSettings::RealName ) );
00125 }
00126
00127
00128
00129
00130
00131 _lock = _calendar->requestSaveTicket(m->standardResource());
00132
if ( !_lock )
00133 {
00134 KMessageBox::information(0,
00135 i18n(
"Another program is currently using this file. "
00136
"Access will be read-only."));
00137 }
00138
00139
00140
if (!err)
00141 {
00142 KCal::Todo::List todoList;
00143 KCal::Todo::List::ConstIterator todo;
00144
QDict< Task > map;
00145
00146
00147
00148 todoList = _calendar->rawTodos();
00149 kdDebug(5970) <<
"KarmStorage::load "
00150 <<
"rawTodo count (includes completed todos) ="
00151 << todoList.count() << endl;
00152
for( todo = todoList.begin(); todo != todoList.end(); ++todo )
00153 {
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
Task* task =
new Task(*todo, view);
00172 map.insert( (*todo)->uid(), task );
00173 view->setRootIsDecorated(
true);
00174
if ((*todo)->isCompleted())
00175 {
00176 task->setEnabled(
false);
00177 task->setOpen(
false);
00178 }
00179
else
00180 task->setOpen(
true);
00181 }
00182
00183
00184
for( todo = todoList.begin(); todo != todoList.end(); ++todo )
00185 {
00186
Task* task = map.find( (*todo)->uid() );
00187
00188
00189
if ( (*todo)->relatedTo() )
00190 {
00191
Task* newParent = map.find( (*todo)->relatedToUid() );
00192
00193
00194
if ( !newParent )
00195 err = i18n(
"Error loading \"%1\": could not find parent (uid=%2)")
00196 .arg(task->
name())
00197 .arg((*todo)->relatedToUid());
00198
00199
if (!err) task->
move( newParent);
00200 }
00201 }
00202
00203 kdDebug(5970) <<
"KarmStorage::load - loaded " << view->
count()
00204 <<
" tasks from " << _icalfile << endl;
00205 }
00206
00207
return err;
00208 }
00209
00210
void KarmStorage::closeStorage(
TaskView* view)
00211 {
00212
if ( _calendar )
00213 {
00214
if ( _lock ) _calendar->releaseSaveTicket( _lock );
00215
00216 _calendar->close();
00217
00218 KCal::CalendarResourceManager *m = _calendar->resourceManager();
00219 m->remove( m->standardResource() );
00220
00221 view->clear();
00222 }
00223 }
00224
00225
void KarmStorage::save(
TaskView* taskview)
00226 {
00227
if ( !_lock )
return;
00228
00229
QPtrStack< KCal::Todo > parents;
00230
00231
for (
Task* task=taskview->
first_child(); task; task = task->
nextSibling())
00232 {
00233 writeTaskAsTodo(task, 1, parents );
00234 }
00235
00236 _calendar->save(_lock);
00237 _lock = _calendar->requestSaveTicket
00238 ( _calendar->resourceManager()->standardResource() );
00239
00240 kdDebug(5970)
00241 <<
"KarmStorage::save : wrote "
00242 << taskview->
count() <<
" tasks to " << _icalfile << endl;
00243 }
00244
00245
void KarmStorage::writeTaskAsTodo(
Task* task,
const int level,
00246
QPtrStack< KCal::Todo >& parents )
00247 {
00248 KCal::Todo* todo;
00249
00250 todo = _calendar->todo(task->
uid());
00251 task->
asTodo(todo);
00252
if ( !parents.isEmpty() ) todo->setRelatedTo( parents.top() );
00253 parents.push( todo );
00254
00255
for (
Task* nextTask = task->
firstChild(); nextTask;
00256 nextTask = nextTask->
nextSibling() )
00257 {
00258 writeTaskAsTodo(nextTask, level+1, parents );
00259 }
00260
00261 parents.pop();
00262 }
00263
00264 bool KarmStorage::isEmpty()
00265 {
00266 KCal::Todo::List todoList;
00267
00268 todoList = _calendar->rawTodos();
00269
return todoList.empty();
00270 }
00271
00272 bool KarmStorage::isNewStorage(
const Preferences* preferences)
const
00273
{
00274
if ( !_icalfile.isNull() )
return preferences->
iCalFile() != _icalfile;
00275
else return false;
00276 }
00277
00278
00279
00280
00281
00282
00283 QString KarmStorage::loadFromFlatFile(
TaskView* taskview,
00284
const QString& filename)
00285 {
00286
QString err;
00287
00288 kdDebug(5970)
00289 <<
"KarmStorage::loadFromFlatFile: " << filename << endl;
00290
00291
QFile f(filename);
00292
if( !f.exists() )
00293 err = i18n(
"File \"%1\" not found.").arg(filename);
00294
00295
if (!err)
00296 {
00297
if( !f.open( IO_ReadOnly ) )
00298 err = i18n(
"Could not open \"%1\".").arg(filename);
00299 }
00300
00301
if (!err)
00302 {
00303
00304
QString line;
00305
00306
QPtrStack<Task> stack;
00307
Task *task;
00308
00309
QTextStream stream(&f);
00310
00311
while( !stream.atEnd() ) {
00312
00313
00314
00315
00316 line = stream.readLine();
00317 kdDebug(5970) <<
"DEBUG: line: " << line <<
"\n";
00318
00319
if (line.isNull())
00320
break;
00321
00322
long minutes;
00323
int level;
00324
QString name;
00325
DesktopList desktopList;
00326
if (!parseLine(line, &minutes, &name, &level, &desktopList))
00327
continue;
00328
00329
unsigned int stackLevel = stack.count();
00330
for (
unsigned int i = level; i<=stackLevel ; i++) {
00331 stack.pop();
00332 }
00333
00334
if (level == 1) {
00335 kdDebug(5970) <<
"KarmStorage::loadFromFlatFile - toplevel task: "
00336 << name <<
" min: " << minutes <<
"\n";
00337 task =
new Task(name, minutes, 0, desktopList, taskview);
00338 task->
setUid(
addTask(task, 0));
00339 }
00340
else {
00341
Task *parent = stack.top();
00342 kdDebug(5970) <<
"KarmStorage::loadFromFlatFile - task: " << name
00343 <<
" min: " << minutes <<
" parent" << parent->
name() <<
"\n";
00344 task =
new Task(name, minutes, 0, desktopList, parent);
00345
00346 task->
setUid(
addTask(task, parent));
00347
00348
00349 parent->
changeTimes(0, -minutes);
00350 taskview->setRootIsDecorated(
true);
00351 parent->setOpen(
true);
00352 }
00353
if (!task->
uid().isNull())
00354 stack.push(task);
00355
else
00356
delete task;
00357 }
00358
00359 f.close();
00360
00361 }
00362
00363
return err;
00364 }
00365
00366 QString KarmStorage::loadFromFlatFileCumulative(
TaskView* taskview,
00367
const QString& filename)
00368 {
00369
QString err =
loadFromFlatFile(taskview, filename);
00370
if (!err)
00371 {
00372
for (
Task* task = taskview->
first_child(); task;
00373 task = task->
nextSibling())
00374 {
00375 adjustFromLegacyFileFormat(task);
00376 }
00377 }
00378
return err;
00379 }
00380
00381
bool KarmStorage::parseLine(
QString line,
long *time,
QString *name,
00382
int *level,
DesktopList* desktopList)
00383 {
00384
if (line.find(
'#') == 0) {
00385
00386
return false;
00387 }
00388
00389
int index = line.find(
'\t');
00390
if (index == -1) {
00391
00392
return false;
00393 }
00394
00395
QString levelStr = line.left(index);
00396
QString rest = line.remove(0,index+1);
00397
00398 index = rest.find(
'\t');
00399
if (index == -1) {
00400
00401
return false;
00402 }
00403
00404
QString timeStr = rest.left(index);
00405 rest = rest.remove(0,index+1);
00406
00407
bool ok;
00408
00409 index = rest.find(
'\t');
00410
if (index >= 0) {
00411 *name = rest.left(index);
00412
QString deskLine = rest.remove(0,index+1);
00413
00414
00415
00416
QString ds;
00417
int d;
00418
int commaIdx = deskLine.find(
',');
00419
while (commaIdx >= 0) {
00420 ds = deskLine.left(commaIdx);
00421 d = ds.toInt(&ok);
00422
if (!ok)
00423
return false;
00424
00425 desktopList->push_back(d);
00426 deskLine.remove(0,commaIdx+1);
00427 commaIdx = deskLine.find(
',');
00428 }
00429
00430 d = deskLine.toInt(&ok);
00431
00432
if (!ok)
00433
return false;
00434
00435 desktopList->push_back(d);
00436 }
00437
else {
00438 *name = rest.remove(0,index+1);
00439 }
00440
00441 *time = timeStr.toLong(&ok);
00442
00443
if (!ok) {
00444
00445
return false;
00446 }
00447 *level = levelStr.toInt(&ok);
00448
if (!ok) {
00449
00450
return false;
00451 }
00452
00453
return true;
00454 }
00455
00456
void KarmStorage::adjustFromLegacyFileFormat(
Task* task)
00457 {
00458
00459
if ( task->
parent() )
00460 task->
parent()->
changeTimes(-task->
sessionTime(), -task->
time());
00461
00462
00463
00464
00465
00466
for (
Task* subtask = task->
firstChild(); subtask;
00467 subtask = subtask->
nextSibling() )
00468 adjustFromLegacyFileFormat(subtask);
00469 }
00470
00471
00472
00473
00474
QString KarmStorage::exportcsvFile(
TaskView *taskview,
00475
const ReportCriteria &rc )
00476 {
00477
QString delim = rc.
delimiter;
00478
QString dquote = rc.
quote;
00479
QString double_dquote = dquote + dquote;
00480
bool to_quote =
true;
00481
00482
QString err;
00483
Task* task;
00484
int maxdepth=0;
00485
00486 kdDebug(5970)
00487 <<
"KarmStorage::exportcsvFile: " << rc.
url << endl;
00488
00489
QFile f( rc.
url );
00490
if( !f.open( IO_WriteOnly ) ) {
00491 err = i18n(
"Could not open \"%1\".").arg( rc.
url );
00492 }
00493
00494
if (!err)
00495 {
00496
QString title = i18n(
"Export Progress");
00497 KProgressDialog dialog( taskview, 0, title );
00498 dialog.setAutoClose(
true );
00499 dialog.setAllowCancel(
true );
00500 dialog.progressBar()->setTotalSteps( 2 * taskview->
count() );
00501
00502
00503
int width = taskview->fontMetrics().width(title) * 3;
00504
QSize dialogsize;
00505 dialogsize.setWidth(width);
00506 dialog.setInitialSize( dialogsize,
true );
00507
00508
if ( taskview->
count() > 1 ) dialog.show();
00509
00510
QTextStream stream(&f);
00511
00512
00513
int tasknr = 0;
00514
while ( tasknr < taskview->
count() && !dialog.wasCancelled() )
00515 {
00516 dialog.progressBar()->advance( 1 );
00517
if ( tasknr % 15 == 0 ) kapp->processEvents();
00518
if ( taskview->
item_at_index(tasknr)->depth() > maxdepth )
00519 maxdepth = taskview->
item_at_index(tasknr)->depth();
00520 tasknr++;
00521 }
00522
00523
00524 tasknr = 0;
00525
while ( tasknr < taskview->
count() && !dialog.wasCancelled() )
00526 {
00527 task = taskview->
item_at_index( tasknr );
00528
00529 dialog.progressBar()->advance( 1 );
00530
if ( tasknr % 15 == 0 ) kapp->processEvents();
00531
00532
00533
for (
int i=0; i < task->depth(); ++i ) stream << delim;
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544 to_quote =
true;
00545
00546
if (to_quote)
00547 stream << dquote;
00548
00549
00550 stream << task->
name().replace( dquote, double_dquote );
00551
00552
if (to_quote)
00553 stream << dquote;
00554
00555
00556
for (
int i = 0; i < maxdepth - task->depth(); ++i ) stream << delim;
00557
00558 stream << delim << formatTime( task->
sessionTime(),
00559 rc.
decimalMinutes )
00560 << delim << formatTime( task->
time(),
00561 rc.
decimalMinutes )
00562 << delim << formatTime( task->
totalSessionTime(),
00563 rc.
decimalMinutes )
00564 << delim << formatTime( task->
totalTime(),
00565 rc.
decimalMinutes )
00566 << endl;
00567 tasknr++;
00568 }
00569 f.close();
00570
00571 }
00572
return err;
00573 }
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583 QString KarmStorage::addTask(
const Task* task,
const Task* parent)
00584 {
00585 KCal::Todo* todo;
00586
QString uid;
00587
00588 todo =
new KCal::Todo();
00589
if (_calendar->addTodo(todo))
00590 {
00591 task->
asTodo(todo);
00592
if (parent)
00593 todo->setRelatedTo(_calendar->todo(parent->
uid()));
00594 uid = todo->uid();
00595 }
00596
00597
return uid;
00598 }
00599
00600 bool KarmStorage::removeTask(
Task* task)
00601 {
00602
if ( !_lock )
return false;
00603
00604
00605 KCal::Event::List eventList = _calendar->rawEvents();
00606
for(KCal::Event::List::iterator i = eventList.begin();
00607 i != eventList.end();
00608 ++i)
00609 {
00610
00611
00612
00613
00614
if ( (*i)->relatedToUid() == task->
uid()
00615 || ( (*i)->relatedTo()
00616 && (*i)->relatedTo()->uid() == task->
uid()))
00617 {
00618 _calendar->deleteEvent(*i);
00619 }
00620 }
00621
00622
00623 KCal::Todo *todo = _calendar->todo(task->
uid());
00624 _calendar->deleteTodo(todo);
00625
00626
00627 _calendar->save(_lock);
00628 _lock = _calendar->requestSaveTicket
00629 (_calendar->resourceManager()->standardResource());
00630
00631
return true;
00632 }
00633
00634 void KarmStorage::addComment(
const Task* task,
const QString& comment)
00635 {
00636
if ( !_lock)
return;
00637
00638 KCal::Todo* todo;
00639
00640 todo = _calendar->todo(task->
uid());
00641
00642
00643
00644
QString s = comment;
00645
00646
00647
00648
00649 todo->setDescription(task->
comment());
00650
00651 _calendar->save(_lock);
00652 _lock = _calendar->requestSaveTicket
00653 ( _calendar->resourceManager()->standardResource() );
00654 }
00655
00656
void KarmStorage::printTaskHistory (
00657
const Task *task,
00658
const QMap<QString,long> &taskdaytotals,
00659
QMap<QString,long> &daytotals,
00660
const QDate &from,
00661
const QDate &to,
00662
const int level,
00663
QString &s,
00664
const ReportCriteria &rc)
00665
00666 {
00667
QString delim = rc.
delimiter;
00668
QString dquote = rc.
quote;
00669
QString double_dquote = dquote + dquote;
00670
bool to_quote =
true;
00671
00672
const QString cr = QString::fromLatin1(
"\n");
00673
QString buf;
00674
QString daytaskkey, daykey;
00675
QDate day;
00676
long sum;
00677
00678
if ( !task )
return;
00679
00680 day = from;
00681 sum = 0;
00682
while (day <= to)
00683 {
00684
00685 daykey = day.toString(QString::fromLatin1(
"yyyyMMdd"));
00686 daytaskkey = QString::fromLatin1(
"%1_%2")
00687 .arg(daykey)
00688 .arg(task->
uid());
00689
00690
if (taskdaytotals.contains(daytaskkey))
00691 {
00692 s += QString::fromLatin1(
"%1")
00693 .arg(formatTime(taskdaytotals[daytaskkey]/60, rc.
decimalMinutes));
00694 sum += taskdaytotals[daytaskkey];
00695
00696
if (daytotals.contains(daykey))
00697 daytotals.replace(daykey, daytotals[daykey]+taskdaytotals[daytaskkey]);
00698
else
00699 daytotals.insert(daykey, taskdaytotals[daytaskkey]);
00700 }
00701 s += delim;
00702
00703 day = day.addDays(1);
00704 }
00705
00706
00707 s += QString::fromLatin1(
"%1").arg(formatTime(sum/60, rc.
decimalMinutes));
00708
00709
00710
for (
int i = level + 1; i > 0; i-- ) s += delim;
00711
00712
00713
00714
00715
00716
00717
00718 to_quote =
true;
00719
if ( to_quote) s += dquote;
00720
00721
00722
00723 s += task->
name().replace( dquote, double_dquote );
00724
00725
if ( to_quote) s += dquote;
00726
00727 s += cr;
00728
00729
for (
Task* subTask = task->
firstChild();
00730 subTask;
00731 subTask = subTask->
nextSibling())
00732 {
00733 printTaskHistory( subTask, taskdaytotals, daytotals, from, to , level+1, s,
00734 rc );
00735 }
00736 }
00737
00738 QString KarmStorage::report(
TaskView *taskview,
const ReportCriteria &rc )
00739 {
00740
QString err;
00741
if ( rc.
reportType == ReportCriteria::CSVHistoryExport )
00742 err = exportActivityReport( taskview, rc.
from, rc.
to, rc );
00743
else if ( rc.
reportType == ReportCriteria::CSVTotalsExport )
00744 err = exportcsvFile( taskview, rc );
00745
else
00746
00747 ;
00748
return err;
00749 };
00750
00751
00752
QString KarmStorage::exportActivityReport (
TaskView *taskview,
00753
const QDate &from,
00754
const QDate &to,
00755
const ReportCriteria &rc)
00756 {
00757
QString delim = rc.
delimiter;
00758
const QString cr = QString::fromLatin1(
"\n");
00759
QString err;
00760
00761
00762
QString retval;
00763
QString taskhdr, totalhdr;
00764
QString line, buf;
00765
long sum;
00766
00767
QValueList<Week>::iterator week;
00768
QValueList<HistoryEvent> events;
00769
QValueList<HistoryEvent>::iterator event;
00770
QMap<QString, long> taskdaytotals;
00771
QMap<QString, long> daytotals;
00772
QString daytaskkey, daykey;
00773
QDate day;
00774
QDate dayheading;
00775
00776
00777
if ( from > to )
00778 {
00779 err = QString::fromLatin1 (
00780
"'to' has to be a date later than or equal to 'from'.");
00781 }
00782
00783
00784 retval += i18n(
"Task History\n");
00785 retval += i18n(
"From %1 to %2")
00786 .arg(KGlobal::locale()->formatDate(from))
00787 .arg(KGlobal::locale()->formatDate(to));
00788 retval += cr;
00789 retval += i18n(
"Printed on: %1")
00790 .arg(KGlobal::locale()->formatDateTime(QDateTime::currentDateTime()));
00791 retval += cr;
00792
00793
00794
QValueList<Week> weeks =
Week::weeksFromDateRange(from, to);
00795 day=from;
00796
00797 events = taskview->
getHistory(from, to);
00798 taskdaytotals.clear();
00799 daytotals.clear();
00800
00801
00802
00803
00804
00805
00806
for (event = events.begin(); event != events.end(); ++event)
00807 {
00808 daykey = (*event).start().date().toString(QString::fromLatin1(
"yyyyMMdd"));
00809 daytaskkey =
QString(QString::fromLatin1(
"%1_%2"))
00810 .arg(daykey)
00811 .arg((*event).todoUid());
00812
00813
if (taskdaytotals.contains(daytaskkey))
00814 taskdaytotals.replace(daytaskkey,
00815 taskdaytotals[daytaskkey] + (*event).duration());
00816
else
00817 taskdaytotals.insert(daytaskkey, (*event).duration());
00818 }
00819
00820
00821 dayheading = from;
00822
while ( dayheading <= to )
00823 {
00824
00825 retval += dayheading.toString(QString::fromLatin1(
"yyyy-MM-dd"));
00826 retval += delim;
00827 dayheading=dayheading.addDays(1);
00828 }
00829 retval += cr;
00830 retval += line;
00831
00832
00833
if (events.empty())
00834 {
00835 retval += i18n(
" No hours logged.");
00836 }
00837
else
00838 {
00839
if ( rc.
allTasks )
00840 {
00841
for (
Task* task= taskview->
item_at_index(0);
00842 task; task= task->
nextSibling() )
00843 {
00844 printTaskHistory( task, taskdaytotals, daytotals, from, to, 0,
00845 retval, rc );
00846 }
00847 }
00848
else
00849 {
00850 printTaskHistory( taskview->
current_item(), taskdaytotals, daytotals,
00851 from, to, 0, retval, rc );
00852 }
00853 retval += line;
00854
00855
00856 sum = 0;
00857 day = from;
00858
while (day<=to)
00859 {
00860 daykey = day.toString(QString::fromLatin1(
"yyyyMMdd"));
00861
00862
if (daytotals.contains(daykey))
00863 {
00864 retval += QString::fromLatin1(
"%1")
00865 .arg(formatTime(daytotals[daykey]/60, rc.
decimalMinutes));
00866 sum += daytotals[daykey];
00867 }
00868 retval += delim;
00869 day = day.addDays(1);
00870 }
00871
00872 retval += QString::fromLatin1(
"%1%2%3")
00873 .arg( formatTime( sum/60, rc.
decimalMinutes ) )
00874 .arg( delim )
00875 .arg( i18n(
"Total" ) );
00876 }
00877
00878
00879
00880
QFile f( rc.
url );
00881
if( !f.open( IO_WriteOnly ) ) {
00882 err = i18n(
"Could not open \"%1\"." ).arg( rc.
url );
00883 }
00884
00885
if (!err)
00886 {
00887
00888
QTextStream stream(&f);
00889
00890 stream << retval;
00891 f.close();
00892
00893 }
00894
return err;
00895 }
00896
00897 void KarmStorage::stopTimer(
const Task* task)
00898 {
00899
long delta = task->
startTime().secsTo(QDateTime::currentDateTime());
00900 changeTime(task, delta);
00901 }
00902
00903
void KarmStorage::changeTime(
const Task* task,
const long deltaSeconds)
00904 {
00905 KCal::Event* e;
00906
QDateTime end;
00907
00908
00909
00910
if ( ! task->
taskView()->
preferences()->
logging() )
return;
00911
00912 e = baseEvent(task);
00913
00914
00915
00916 end = task->
startTime();
00917
if ( deltaSeconds > 0 ) end = task->
startTime().addSecs(deltaSeconds);
00918 e->setDtEnd(end);
00919
00920
00921 e->setCustomProperty( kapp->instanceName(),
00922
QCString(
"duration"),
00923 QString::number(deltaSeconds));
00924
00925 _calendar->addEvent(e);
00926
00927
00928
00929
00930
00931
00932
00933
00934
00935 task->
taskView()->
scheduleSave();
00936 }
00937
00938
00939 KCal::Event* KarmStorage::baseEvent(
const Task * task)
00940 {
00941 KCal::Event* e;
00942
QStringList categories;
00943
00944 e =
new KCal::Event;
00945 e->setSummary(task->
name());
00946
00947
00948 e->setRelatedTo(_calendar->todo(task->
uid()));
00949
00950
00951 assert(e->relatedTo()->uid() == task->
uid());
00952
00953
00954 e->setFloats(
false);
00955 e->setDtStart(task->
startTime());
00956
00957
00958 categories.append(i18n(
"KArm"));
00959 e->setCategories(categories);
00960
00961
return e;
00962 }
00963
00964
HistoryEvent::HistoryEvent(
QString uid,
QString name,
long duration,
00965
QDateTime start,
QDateTime stop,
QString todoUid)
00966 {
00967 _uid = uid;
00968 _name = name;
00969 _duration = duration;
00970 _start = start;
00971 _stop = stop;
00972 _todoUid = todoUid;
00973 }
00974
00975
00976 QValueList<HistoryEvent> KarmStorage::getHistory(
const QDate& from,
00977
const QDate& to)
00978 {
00979
QValueList<HistoryEvent> retval;
00980
QStringList processed;
00981 KCal::Event::List events;
00982 KCal::Event::List::iterator event;
00983
QString duration;
00984
00985
for(
QDate d = from; d <= to; d = d.addDays(1))
00986 {
00987 events = _calendar->events(d);
00988
for (event = events.begin(); event != events.end(); ++event)
00989 {
00990
00991
00992
if (! processed.contains( (*event)->uid()))
00993 {
00994
00995
00996
00997
00998
00999 processed.append( (*event)->uid());
01000
01001 duration = (*event)->customProperty(kapp->instanceName(),
01002
QCString(
"duration"));
01003
if ( ! duration.isNull() )
01004 {
01005
if ( (*event)->relatedTo()
01006 && ! (*event)->relatedTo()->uid().isEmpty() )
01007 {
01008 retval.append(
HistoryEvent(
01009 (*event)->uid(),
01010 (*event)->summary(),
01011 duration.toLong(),
01012 (*event)->dtStart(),
01013 (*event)->dtEnd(),
01014 (*event)->relatedTo()->uid()
01015 ));
01016 }
01017
else
01018
01019
01020
01021 kdDebug(5970) <<
"KarmStorage::getHistory(): "
01022 <<
"The event " << (*event)->uid()
01023 <<
" is not related to a todo. Dropped." << endl;
01024 }
01025 }
01026 }
01027 }
01028
01029
return retval;
01030 }
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087