00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
#include <qdatetime.h>
00024
#include <qstring.h>
00025
#include <qptrlist.h>
00026
00027
#include <kdebug.h>
00028
00029
#include "vcaldrag.h"
00030
#include "vcalformat.h"
00031
#include "icalformat.h"
00032
#include "exceptions.h"
00033
#include "incidence.h"
00034
#include "journal.h"
00035
#include "filestorage.h"
00036
00037
#include "calendarlocal.h"
00038
00039
using namespace KCal;
00040
00041 CalendarLocal::CalendarLocal()
00042 :
Calendar(), mEvents( 47 )
00043 {
00044 init();
00045 }
00046
00047 CalendarLocal::CalendarLocal(
const QString &timeZoneId)
00048 :
Calendar(timeZoneId), mEvents( 47 )
00049 {
00050 init();
00051 }
00052
00053
void CalendarLocal::init()
00054 {
00055 }
00056
00057
00058 CalendarLocal::~CalendarLocal()
00059 {
00060
close();
00061 }
00062
00063 bool CalendarLocal::load(
const QString &fileName )
00064 {
00065
FileStorage storage(
this, fileName );
00066
return storage.
load();
00067 }
00068
00069 bool CalendarLocal::save(
const QString &fileName,
CalFormat *format )
00070 {
00071
FileStorage storage(
this, fileName, format );
00072
return storage.
save();
00073 }
00074
00075 void CalendarLocal::close()
00076 {
00077
deleteAllEvents();
00078
deleteAllTodos();
00079
deleteAllJournals();
00080
00081 setModified(
false );
00082 }
00083
00084
00085 bool CalendarLocal::addEvent(
Event *event )
00086 {
00087
insertEvent( event );
00088
00089 event->
registerObserver(
this );
00090
00091 setModified(
true );
00092
00093
return true;
00094 }
00095
00096 void CalendarLocal::deleteEvent(
Event *event )
00097 {
00098 kdDebug(5800) <<
"CalendarLocal::deleteEvent" << endl;
00099
00100
if ( mEvents.remove( event->
uid() ) ) {
00101 setModified(
true );
00102 }
else {
00103 kdWarning() <<
"CalendarLocal::deleteEvent(): Event not found." << endl;
00104 }
00105 }
00106
00107 void CalendarLocal::deleteAllEvents()
00108 {
00109
00110 mEvents.setAutoDelete(
true );
00111 mEvents.clear();
00112 mEvents.setAutoDelete(
false );
00113 }
00114
00115 Event *CalendarLocal::event(
const QString &uid )
00116 {
00117
00118
return mEvents[ uid ];
00119 }
00120
00121 bool CalendarLocal::addTodo(
Todo *todo )
00122 {
00123 mTodoList.append( todo );
00124
00125 todo->
registerObserver(
this );
00126
00127
00128 setupRelations( todo );
00129
00130 setModified(
true );
00131
00132
return true;
00133 }
00134
00135 void CalendarLocal::deleteTodo(
Todo *todo )
00136 {
00137
00138 removeRelations( todo );
00139
00140
if ( mTodoList.
removeRef( todo ) ) {
00141 setModified(
true );
00142 }
00143 }
00144
00145 void CalendarLocal::deleteAllTodos()
00146 {
00147
00148 mTodoList.
setAutoDelete(
true );
00149 mTodoList.clear();
00150 mTodoList.
setAutoDelete(
false );
00151 }
00152
00153 Todo::List CalendarLocal::rawTodos()
00154 {
00155
return mTodoList;
00156 }
00157
00158 Todo *CalendarLocal::todo(
const QString &uid )
00159 {
00160 Todo::List::ConstIterator it;
00161
for ( it = mTodoList.begin(); it != mTodoList.end(); ++it ) {
00162
if ( (*it)->uid() == uid )
return *it;
00163 }
00164
00165
return 0;
00166 }
00167
00168 Todo::List CalendarLocal::todos(
const QDate &date )
00169 {
00170
Todo::List todos;
00171
00172 Todo::List::ConstIterator it;
00173
for ( it = mTodoList.begin(); it != mTodoList.end(); ++it ) {
00174
Todo *
todo = *it;
00175
if ( todo->
hasDueDate() && todo->
dtDue().date() == date ) {
00176 todos.append( todo );
00177 }
00178 }
00179
00180
return todos;
00181 }
00182
00183 Alarm::List CalendarLocal::alarmsTo(
const QDateTime &to )
00184 {
00185
return alarms( QDateTime( QDate( 1900, 1, 1 ) ), to );
00186 }
00187
00188 Alarm::List CalendarLocal::alarms(
const QDateTime &from,
const QDateTime &to )
00189 {
00190
00191
00192
00193
Alarm::List alarms;
00194
00195 EventDictIterator it( mEvents );
00196
for( ; it.current(); ++it ) {
00197
Event *e = *it;
00198
if ( e->
doesRecur() )
appendRecurringAlarms( alarms, e, from, to );
00199
else appendAlarms( alarms, e, from, to );
00200 }
00201
00202 Todo::List::ConstIterator it2;
00203
for( it2 = mTodoList.begin(); it2 != mTodoList.end(); ++it2 ) {
00204
if (! (*it2)->isCompleted() )
appendAlarms( alarms, *it2, from, to );
00205 }
00206
00207
return alarms;
00208 }
00209
00210 void CalendarLocal::appendAlarms(
Alarm::List &alarms,
Incidence *incidence,
00211
const QDateTime &from,
const QDateTime &to )
00212 {
00213 Alarm::List::ConstIterator it;
00214
for( it = incidence->
alarms().begin(); it != incidence->
alarms().end();
00215 ++it ) {
00216
00217
00218
if ( (*it)->enabled() ) {
00219
if ( (*it)->time() >= from && (*it)->time() <= to ) {
00220 kdDebug(5800) <<
"CalendarLocal::appendAlarms() '"
00221 << incidence->
summary() <<
"': "
00222 << (*it)->time().toString() << endl;
00223 alarms.append( *it );
00224 }
00225 }
00226 }
00227 }
00228
00229 void CalendarLocal::appendRecurringAlarms(
Alarm::List &alarms,
00230
Incidence *incidence,
00231
const QDateTime &from,
00232
const QDateTime &to )
00233 {
00234 Alarm::List::ConstIterator it;
00235 QDateTime qdt;
00236
int endOffset = 0;
00237
bool endOffsetValid =
false;
00238
for( it = incidence->
alarms().begin(); it != incidence->
alarms().end();
00239 ++it ) {
00240
Alarm *alarm = *it;
00241
if ( alarm->
hasTime() ) {
00242
00243 qdt = alarm->
time();
00244 }
else {
00245
00246
00247
00248
int offset = 0;
00249
if ( alarm->
hasStartOffset() ) {
00250 offset = alarm->
startOffset().
asSeconds();
00251 }
else if ( alarm->
hasEndOffset() ) {
00252
if ( !endOffsetValid ) {
00253 endOffset = incidence->
dtStart().secsTo( incidence->
dtEnd() );
00254 endOffsetValid =
true;
00255 }
00256 offset = alarm->
endOffset().
asSeconds() + endOffset;
00257 }
00258
00259 qdt = incidence->
recurrence()->
getNextDateTime( from.addSecs(-offset - 1) );
00260
if (!qdt.isValid() || incidence->
isException(qdt.date()) )
00261
continue;
00262
00263 qdt = qdt.addSecs( offset );
00264 }
00265 kdDebug(5800) <<
"CalendarLocal::appendAlarms() '" << incidence->
summary()
00266 <<
"': " << qdt.toString() <<
" - " << (*it)->enabled()
00267 << endl;
00268
if ( (*it)->enabled() ) {
00269
00270
00271
if ( qdt >= from && qdt <= to ) {
00272 alarms.append( *it );
00273 }
00274 }
00275 }
00276 }
00277
00278
00279
00280 void CalendarLocal::update(
IncidenceBase *incidence )
00281 {
00282 incidence->
setSyncStatus( Event::SYNCMOD );
00283 incidence->
setLastModified( QDateTime::currentDateTime() );
00284
00285
00286
00287
00288 setModified(
true );
00289 }
00290
00291 void CalendarLocal::insertEvent(
Event *event )
00292 {
00293 QString uid = event->
uid();
00294
if ( mEvents[ uid ] == 0 ) {
00295 mEvents.insert( uid, event );
00296 }
00297
#ifndef NDEBUG
00298
else
00299
00300 Q_ASSERT( mEvents[uid] == event );
00301
#endif
00302
}
00303
00304
00305 Event::List CalendarLocal::rawEventsForDate(
const QDate &qd,
bool sorted )
00306 {
00307
Event::List eventList;
00308
00309 EventDictIterator it( mEvents );
00310
for( ; it.current(); ++it ) {
00311
Event *
event = *it;
00312
00313
if ( event->
doesRecur() ) {
00314
if ( event->
isMultiDay() ) {
00315
int extraDays = event->
dtStart().date().daysTo( event->
dtEnd().date() );
00316
int i;
00317
for ( i = 0; i <= extraDays; i++ ) {
00318
if ( event->
recursOn( qd.addDays( -i ) ) ) {
00319 eventList.append( event );
00320
break;
00321 }
00322 }
00323 }
else {
00324
if ( event->
recursOn( qd ) )
00325 eventList.append( event );
00326 }
00327 }
else {
00328
if ( event->
dtStart().date() <= qd && event->
dtEnd().date() >= qd ) {
00329 eventList.append( event );
00330 }
00331 }
00332 }
00333
00334
if ( !sorted ) {
00335
return eventList;
00336 }
00337
00338
00339
00340
Event::List eventListSorted;
00341 Event::List::Iterator sortIt;
00342 Event::List::Iterator eit;
00343
for ( eit = eventList.begin(); eit != eventList.end(); ++eit ) {
00344 sortIt = eventListSorted.begin();
00345
while ( sortIt != eventListSorted.end() &&
00346 (*eit)->dtStart().time() >= (*sortIt)->dtStart().time() ) {
00347 ++sortIt;
00348 }
00349 eventListSorted.insert( sortIt, *eit );
00350 }
00351
return eventListSorted;
00352 }
00353
00354
00355 Event::List CalendarLocal::rawEvents(
const QDate &start,
const QDate &end,
00356
bool inclusive )
00357 {
00358
Event::List eventList;
00359
00360
00361 EventDictIterator it( mEvents );
00362
for( ; it.current(); ++it ) {
00363
Event *
event = *it;
00364
if ( event->
doesRecur() ) {
00365 QDate rStart = event->
dtStart().date();
00366
bool found =
false;
00367
if ( inclusive ) {
00368
if ( rStart >= start && rStart <= end ) {
00369
00370
00371
if ( event->
recurrence()->
duration() == 0 ) {
00372 QDate rEnd = event->
recurrence()->
endDate();
00373
if ( rEnd >= start && rEnd <= end ) {
00374 found =
true;
00375 }
00376 }
else if ( event->
recurrence()->
duration() > 0 ) {
00377
00378
00379 }
00380 }
00381 }
else {
00382
if ( rStart <= end ) {
00383
if ( rStart >= start ) {
00384 found =
true;
00385 }
else if ( event->
recurrence()->
duration() == -1 ) {
00386 found =
true;
00387 }
else if ( event->
recurrence()->
duration() == 0 ) {
00388 QDate rEnd = event->
recurrence()->
endDate();
00389
if ( rEnd >= start && rEnd <= end ) {
00390 found =
true;
00391 }
00392 }
else {
00393
00394
00395 found =
true;
00396 }
00397 }
00398 }
00399
00400
if ( found ) eventList.append( event );
00401 }
else {
00402 QDate s = event->
dtStart().date();
00403 QDate e = event->
dtEnd().date();
00404
00405
if ( inclusive ) {
00406
if ( s >= start && e <= end ) {
00407 eventList.append( event );
00408 }
00409 }
else {
00410
if ( ( s >= start && s <= end ) || ( e >= start && e <= end ) ) {
00411 eventList.append( event );
00412 }
00413 }
00414 }
00415 }
00416
00417
return eventList;
00418 }
00419
00420 Event::List CalendarLocal::rawEventsForDate(
const QDateTime &qdt )
00421 {
00422
return rawEventsForDate( qdt.date() );
00423 }
00424
00425 Event::List CalendarLocal::rawEvents()
00426 {
00427
Event::List eventList;
00428 EventDictIterator it( mEvents );
00429
for( ; it.current(); ++it )
00430 eventList.append( *it );
00431
return eventList;
00432 }
00433
00434 bool CalendarLocal::addJournal(
Journal *journal)
00435 {
00436
if (journal->
dtStart().isValid())
00437 kdDebug(5800) <<
"Adding Journal on " << journal->
dtStart().toString() << endl;
00438
else
00439 kdDebug(5800) <<
"Adding Journal without a DTSTART" << endl;
00440
00441 mJournalList.append(journal);
00442
00443 journal->
registerObserver(
this );
00444
00445 setModified(
true );
00446
00447
return true;
00448 }
00449
00450 void CalendarLocal::deleteJournal(
Journal *journal )
00451 {
00452
if ( mJournalList.
removeRef(journal) ) {
00453 setModified(
true );
00454 }
00455 }
00456
00457 void CalendarLocal::deleteAllJournals()
00458 {
00459 mJournalList.
setAutoDelete(
true );
00460 mJournalList.clear();
00461 mJournalList.
setAutoDelete(
false );
00462 }
00463
00464 Journal *CalendarLocal::journal(
const QDate &date )
00465 {
00466
00467
00468 Journal::List::ConstIterator it;
00469
for ( it = mJournalList.begin(); it != mJournalList.end(); ++it )
00470
if ( (*it)->dtStart().date() == date )
00471
return *it;
00472
00473
return 0;
00474 }
00475
00476 Journal *CalendarLocal::journal(
const QString &uid )
00477 {
00478 Journal::List::ConstIterator it;
00479
for ( it = mJournalList.begin(); it != mJournalList.end(); ++it )
00480
if ( (*it)->uid() == uid )
00481
return *it;
00482
00483
return 0;
00484 }
00485
00486 Journal::List CalendarLocal::journals()
00487 {
00488
return mJournalList;
00489 }
00490