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