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